Обновление до версии 2.9.0
201 files added
197 files modified
| | |
| | |
|
| | | # Organize usings
|
| | | dotnet_separate_import_directive_groups = false
|
| | | dotnet_sort_system_directives_first = false
|
| | | dotnet_sort_system_directives_first = true
|
| | | file_header_template = unset
|
| | |
|
| | | # this. and Me. preferences
|
New file |
| | |
| | | ---
|
| | | name: Bug report
|
| | | about: Create a report to help us improve
|
| | | title: ''
|
| | | labels: ''
|
| | | assignees: ''
|
| | |
|
| | | ---
|
| | |
|
| | | **Describe the bug**
|
| | | A clear and concise description of what the bug is.
|
| | |
|
| | | **To Reproduce**
|
| | | Steps to reproduce the behavior:
|
| | | 1. Go to '...'
|
| | | 2. Click on '....'
|
| | | 3. Scroll down to '....'
|
| | | 4. See error
|
| | |
|
| | | **Expected behavior**
|
| | | A clear and concise description of what you expected to happen.
|
| | |
|
| | | **Screenshots**
|
| | | If applicable, add screenshots to help explain your problem.
|
| | |
|
| | | **Desktop (please complete the following information):**
|
| | | - Qt VS Tool Version [e.g. 2.7.1, 2.8.1, 2.8.1 (Rev.06)]
|
| | | - Visual Studio version [e.g. VS2017, VS2019, VS2022]
|
| | |
|
| | | **Additional context**
|
| | | Add any other context about the problem here.
|
New file |
| | |
| | | ---
|
| | | name: Feature request
|
| | | about: Suggest an idea for this project
|
| | | title: ''
|
| | | labels: ''
|
| | | assignees: ''
|
| | |
|
| | | ---
|
| | |
|
| | | **Is your feature request related to a problem? Please describe.**
|
| | | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
| | |
|
| | | **Describe the solution you'd like**
|
| | | A clear and concise description of what you want to happen.
|
| | |
|
| | | **Describe alternatives you've considered**
|
| | | A clear and concise description of any alternative solutions or features you've considered.
|
| | |
|
| | | **Additional context**
|
| | | Add any other context or screenshots about the feature request here.
|
| | |
| | | QtNatvisPoC/*.txt |
| | | Tests/BigSolution/generated/ |
| | | vstools.pri |
| | | templates/widgetsclass/Properties/AssemblyInfo.tt.cs |
| | | templates/widgetsclass/widgetsclass.vstemplate |
| | | templates/qtclass/Properties/AssemblyInfo.tt.cs |
| | | templates/qtclass/qtclass.vstemplate |
| | | templates/translation/Properties/AssemblyInfo.tt.cs |
| | | templates/translation/translation.vstemplate |
| | |
| | | Qt Visual Studio Tools version 2.9.0:
|
| | |
|
| | | Changes
|
| | | -------
|
| | | - Added QStringRef and QStringView debug visualizers
|
| | | - Check if Qt translation tools are available
|
| | | - New widget class wizards accessible from "Add New Item"
|
| | | - New Qt class wizards accessible from "Add New Item"
|
| | | - InfoBar notification of missing Qt installation
|
| | | - InfoBar notification of recently installed new Qt VS Tools version
|
| | | - Additional compiler options from Qt included in the build
|
| | | - Enabled reporting issues and feature requests via GitHub
|
| | | - Debug visualizer for Qt types added to PDB
|
| | | - Improved intellisense performance for Qt projects
|
| | | - Fixed QTVSADDINBUG-626: Qt VS Tools does not generate the same code as Qt Creator
|
| | | - Fixed QTVSADDINBUG-707: Integrating the main window widget into the Qt Gui application wizard.
|
| | | - Fixed QTVSADDINBUG-884: QStringRef and QStringView have no natvis definitions
|
| | | - Fixed QTVSADDINBUG-925: Can't add an "add-on" module to project using GUI
|
| | | - Fixed QTVSADDINBUG-937: OpenGL Widgets module missing
|
| | | - Fixed QTVSADDINBUG-951: Can't build QT6 WebEngine example
|
| | | - Fixed QTVSADDINBUG-965: Pragma warning not working with "external header warning level" option
|
| | | - Fixed QTVSADDINBUG-966: Debug version of Qt Dlls are linked even if we asked for release mode
|
| | | - Fixed QTVSADDINBUG-970: Qt6 in Visual Studio plugin doesn't load qmake projects
|
| | | - Fixed QTVSADDINBUG-972: VS Plugin is ignoring module core5compat when loading project with QT6
|
| | | - Fixed QTVSADDINBUG-973: unable to add a new qt version with visual studio 2022
|
| | | - Fixed QTVSADDINBUG-979: Project Properties are overwritten by Qt Vs Tools
|
| | | - Fixed QTVSADDINBUG-980: The "Release Notes" link does not work
|
| | | - Fixed QTVSADDINBUG-982: Can't add new Qt Version
|
| | |
|
| | |
|
| | |
|
| | | Qt Visual Studio Tools version 2.8.1:
|
| | |
|
| | | Changes
|
New file |
| | |
| | | # Coding guidelines -- `using` directives
|
| | |
|
| | | Three kinds of `using` directives are available:
|
| | | * **Reference**: `using <namespace>` -- _namespace_ can be omitted when referencing types.
|
| | | * **Alias**: `using <alias> = <namespace|type>` -- _alias_ can be used in place of _namespace_
|
| | | or _type_.
|
| | | * **Static**: `using static <type>` -- all static members of _type_ are accessible without
|
| | | having to specify the type name.
|
| | |
|
| | | The following conventions apply to `using` directives in the Qt VS Tools code:
|
| | | * `using` directives are grouped by root namespace, and ordered alphabetically within each group.
|
| | | * Directives that reference external namespaces are located at the start of the source file,
|
| | | before the local namespace declaration.
|
| | | * The order of external namespace groups is as follows:
|
| | | 1. `System*` namespaces.
|
| | | 2. `Microsoft*` namespaces.
|
| | | 3. `EnvDTE*` namespaces.
|
| | | 4. All other external namespaces.
|
| | | * Directives referencing in-solution namespaces (i.e. `QtVsTools*` or `QtVsTest*` namespaces) are
|
| | | nested within the local namespace block.
|
| | | * In-solution reference directives will use an abbreviated form of the namespace, whenever
|
| | | possible.
|
| | | * Alias and static directives can be specified either at top-level or nested in the local
|
| | | namespace.
|
| | | * Alias directives are specified after all reference directives.
|
| | | * Static directives are specified after all reference directives and all alias directives.
|
| | | * Optionally, directives of different kinds can be separated with an empty line.
|
| | |
|
| | | ## Example
|
| | | ```csharp
|
| | | using System;
|
| | | using System.IO;
|
| | | using System.Linq;
|
| | | using System.Runtime.InteropServices;
|
| | | using System.Text.RegularExpressions;
|
| | | using Microsoft.VisualStudio;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using EnvDTE;
|
| | | using EnvDTE80;
|
| | |
|
| | | using Task = System.Threading.Tasks.Task;
|
| | |
|
| | | namespace QtVsTools
|
| | | {
|
| | | using Core;
|
| | | using QtMsBuild;
|
| | |
|
| | | using RegExprParser = SyntaxAnalysis.RegExpr.Parser;
|
| | |
|
| | | using static SyntaxAnalysis.RegExpr;
|
| | |
|
| | | class ...
|
| | | ```
|
| | |
| | | totalLength += this_.at(i).size();
|
| | |
|
| | | if (sz)
|
| | | totalLength += sepSize * (sz - 1);
|
| | | totalLength += int(sepSize) * (sz - 1);
|
| | |
|
| | | QString res(totalLength, Qt::Uninitialized);
|
| | | QChar *ptr = (QChar *)res.constData();
|
| | |
| | | <ItemGroup>
|
| | | <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
|
| | | <Reference Include="System" />
|
| | | <Reference Include="System.Xml.Linq" />
|
| | | <Reference Include="System.Runtime" />
|
| | | <Reference Include="$(VCTargetsPath)\Application Type\Linux\1.0\Microsoft.Build.Linux.Tasks.dll" />
|
| | | <Reference Include="$(VCTargetsPath)\Application Type\Linux\1.0\liblinux.dll" />
|
| | | </ItemGroup>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Version specific references
|
| | | // General package references
|
| | | // -->
|
| | | <Import Project="$(SolutionDir)\references.props" />
|
| | | <ItemGroup>
|
| | | <PackageReference Include="Microsoft.Build"
|
| | | Version="$(Version_Microsoft_Build)" />
|
| | | <PackageReference Include="Microsoft.Build.Framework"
|
| | | Version="$(Version_Microsoft_Build_Framework)" />
|
| | | <PackageReference Include="Microsoft.Build.Tasks.Core"
|
| | | Version="$(Version_Microsoft_Build_Tasks_Core)" />
|
| | | <PackageReference Include="Microsoft.Bcl.AsyncInterfaces"
|
| | | Version="$(Version_Microsoft_Bcl_AsyncInterfaces)" />
|
| | | <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
|
| | | <PackageReference Include="$(Name_Microsoft_Build)" Version="$(Version_Microsoft_Build)" />
|
| | | <PackageReference Include="$(Name_Microsoft_Build_Tasks_Core)" Version="$(Version_Microsoft_Build_Tasks_Core)" />
|
| | | </ItemGroup>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Version specific package references
|
| | | // -->
|
| | | <Choose>
|
| | | <When Condition="'$(VisualStudioVersion)'=='17.0'">
|
| | | <ItemGroup>
|
| | | </ItemGroup>
|
| | | </When>
|
| | | <When Condition="'$(VisualStudioVersion)'=='16.0'">
|
| | | <ItemGroup>
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_RpcContracts)" Version="$(Version_Microsoft_VisualStudio_RpcContracts)" />
|
| | | </ItemGroup>
|
| | | </When>
|
| | | <When Condition="'$(VisualStudioVersion)'=='15.0'">
|
| | | <ItemGroup>
|
| | | </ItemGroup>
|
| | | </When>
|
| | | </Choose>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Solution project references
|
| | |
| | | <DesignTime>True</DesignTime>
|
| | | <DependentUpon>AssemblyInfo.cs</DependentUpon>
|
| | | </Compile>
|
| | | <Content Include="QtMSBuild\qt5.natvis.xml">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\qt6.natvis.xml">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Qt/MSBuild common property pages and targets
|
| | |
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\qt_vars.targets">
|
| | | <SubType>Designer</SubType>
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | | <Content Include="QtMSBuild\qt_inner.targets">
|
| | | <SubType>Designer</SubType>
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | </Content>
|
| | |
| | | // Inline tasks
|
| | | // -->
|
| | | <Compile Include="Tasks\CriticalSection.cs" />
|
| | | <Compile Include="Tasks\QtRunTask.cs" />
|
| | | <Compile Include="Tasks\GetVarsFromMSBuild.cs" />
|
| | | <Compile Include="Tasks\HostExec_LinuxWSL_Error.cs" />
|
| | | <Compile Include="Tasks\HostTranslatePaths_LinuxWSL_Error.cs" />
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | ****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************
|
| | | -->
|
| | |
|
| | | <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
| | |
|
| | | <Type Name="##NAMESPACE##::QPoint">
|
| | | <AlternativeType Name="##NAMESPACE##::QPointF"/>
|
| | | <DisplayString>{{ x = {xp}, y = {yp} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[x]">xp</Item>
|
| | | <Item Name="[y]">yp</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QRect">
|
| | | <DisplayString>{{ x = {x1}, y = {y1}, width = {x2 - x1 + 1}, height = {y2 - y1 + 1} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[x]">x1</Item>
|
| | | <Item Name="[y]">y1</Item>
|
| | | <Item Name="[width]">x2 - x1 + 1</Item>
|
| | | <Item Name="[height]">y2 - y1 + 1</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QRectF">
|
| | | <DisplayString>{{ x = {xp}, y = {yp}, width = {w}, height = {h} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[x]">xp</Item>
|
| | | <Item Name="[y]">yp</Item>
|
| | | <Item Name="[width]">w</Item>
|
| | | <Item Name="[height]">h</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QSize">
|
| | | <AlternativeType Name="##NAMESPACE##::QSizeF"/>
|
| | | <DisplayString>{{ width = {wd}, height = {ht} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[width]">wd</Item>
|
| | | <Item Name="[height]">ht</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QLine">
|
| | | <AlternativeType Name="##NAMESPACE##::QLineF"/>
|
| | | <DisplayString>{{ start point = {pt1}, end point = {pt2} }}</DisplayString>
|
| | | <Expand>
|
| | | <Synthetic Name="[start point]">
|
| | | <DisplayString>{pt1}</DisplayString>
|
| | | <Expand>
|
| | | <ExpandedItem>pt1</ExpandedItem>
|
| | | </Expand>
|
| | | </Synthetic>
|
| | | <Synthetic Name="[end point]">
|
| | | <DisplayString>{pt2}</DisplayString>
|
| | | <Expand>
|
| | | <ExpandedItem>pt2</ExpandedItem>
|
| | | </Expand>
|
| | | </Synthetic>
|
| | |
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QPolygon">
|
| | | <DisplayString>{{ size = {d->size} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[referenced]">d->ref.atomic._q_value</Item>
|
| | | <ArrayItems>
|
| | | <Size>d->size</Size>
|
| | | <ValuePointer>(##NAMESPACE##::QPoint*)((reinterpret_cast<char*>(d)) + d->offset)</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QPolygonF">
|
| | | <DisplayString>{{ size = {d->size} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[closed]">
|
| | | d->size > 0
|
| | | && ((((##NAMESPACE##::QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[0]).xp
|
| | | == (((##NAMESPACE##::QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[d->size - 1]).xp)
|
| | | && ((((##NAMESPACE##::QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[0]).yp
|
| | | == (((##NAMESPACE##::QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[d->size - 1]).yp)
|
| | | </Item>
|
| | | <Item Name="[referenced]">d->ref.atomic._q_value</Item>
|
| | | <ArrayItems>
|
| | | <Size>d->size</Size>
|
| | | <ValuePointer>(##NAMESPACE##::QPointF*)((reinterpret_cast<char*>(d)) + d->offset)</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name ="##NAMESPACE##::QVector2D">
|
| | | <DisplayString>{{ x = {xp}, y = {yp} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[x]">xp</Item>
|
| | | <Item Name="[y]">yp</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name ="##NAMESPACE##::QVector3D">
|
| | | <DisplayString>{{ x = {xp}, y = {yp}, z = {zp} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[x]">xp</Item>
|
| | | <Item Name="[y]">yp</Item>
|
| | | <Item Name="[z]">zp</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name ="##NAMESPACE##::QVector4D">
|
| | | <DisplayString>{{ x = {xp}, y = {yp}, z = {zp}, w = {wp} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[x]">xp</Item>
|
| | | <Item Name="[y]">yp</Item>
|
| | | <Item Name="[z]">zp</Item>
|
| | | <Item Name="[w]">wp</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name ="##NAMESPACE##::QMatrix">
|
| | | <DisplayString>
|
| | | {{ m11 = {_m11}, m12 = {_m12}, m21 = {_m21}, m22 = {_m22}, ... }}
|
| | | </DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[m11]">_m11</Item>
|
| | | <Item Name="[m12]">_m12</Item>
|
| | | <Item Name="[m21]">_m21</Item>
|
| | | <Item Name="[m22]">_m22</Item>
|
| | | <Item Name="[dx]">_dx</Item>
|
| | | <Item Name="[dy]">_dy</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name ="##NAMESPACE##::QMatrix4x4">
|
| | | <DisplayString>
|
| | | {{ m11 = {m[0][0]}, m12 = {m[1][0]}, m13 = {m[2][0]}, m14 = {m[3][0]}, ... }}
|
| | | </DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[m11]">m[0][0]</Item>
|
| | | <Item Name="[m12]">m[1][0]</Item>
|
| | | <Item Name="[m13]">m[2][0]</Item>
|
| | | <Item Name="[m14]">m[3][0]</Item>
|
| | | <Item Name="[m21]">m[0][1]</Item>
|
| | | <Item Name="[m22]">m[1][1]</Item>
|
| | | <Item Name="[m23]">m[2][1]</Item>
|
| | | <Item Name="[m24]">m[3][1]</Item>
|
| | | <Item Name="[m31]">m[0][2]</Item>
|
| | | <Item Name="[m32]">m[1][2]</Item>
|
| | | <Item Name="[m33]">m[2][2]</Item>
|
| | | <Item Name="[m34]">m[3][2]</Item>
|
| | | <Item Name="[m41]">m[0][3]</Item>
|
| | | <Item Name="[m42]">m[1][3]</Item>
|
| | | <Item Name="[m43]">m[2][3]</Item>
|
| | | <Item Name="[m44]">m[3][3]</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QSizePolicy">
|
| | | <DisplayString>
|
| | | {{ horizontal = {static_cast<Policy>(bits.horPolicy)}, vertical = {static_cast<Policy>(bits.verPolicy)}, type = {ControlType(1 << bits.ctype)} }}
|
| | | </DisplayString>
|
| | | <Expand>
|
| | | <Synthetic Name="[vertical policy]">
|
| | | <DisplayString>##NAMESPACE##::QSizePolicy::Policy::{static_cast<Policy>(bits.verPolicy)}</DisplayString>
|
| | | </Synthetic>
|
| | | <Synthetic Name="[horizontal policy]">
|
| | | <DisplayString>##NAMESPACE##::QSizePolicy::Policy::{static_cast<Policy>(bits.horPolicy)}</DisplayString>
|
| | | </Synthetic>
|
| | | <Synthetic Name="[control type]">
|
| | | <DisplayString>##NAMESPACE##::QSizePolicy::ControlType::{ControlType(1 << bits.ctype)}</DisplayString>
|
| | | </Synthetic>
|
| | | <Synthetic Name="[expanding directions]">
|
| | | <DisplayString
|
| | | Condition="(static_cast<Policy>(bits.verPolicy) & ExpandFlag)">
|
| | | ##NAMESPACE##::Qt::Vertical (2)
|
| | | </DisplayString>
|
| | | <DisplayString
|
| | | Condition="(static_cast<Policy>(bits.horPolicy) & ExpandFlag)">
|
| | | ##NAMESPACE##::Qt::Horizontal (1)
|
| | | </DisplayString>
|
| | | </Synthetic>
|
| | | <Item Name="[vertical stretch]">static_cast<int>(bits.verStretch)</Item>
|
| | | <Item Name="[horizontal stretch]">static_cast<int>(bits.horStretch)</Item>
|
| | | <Item Name="[has height for width]">bits.hfw == 1</Item>
|
| | | <Item Name="[has width for height]">bits.wfh == 1</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QChar">
|
| | | <DisplayString>{ucs,c}</DisplayString>
|
| | | <StringView>ucs,c</StringView>
|
| | | <Expand>
|
| | | <Item Name="[latin 1]">ucs > 0xff ? '\0' : char(ucs),c</Item>
|
| | | <Item Name="[unicode]">ucs,c</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QString">
|
| | | <DisplayString>{((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),sub}</DisplayString>
|
| | | <StringView>((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),sub</StringView>
|
| | | <Expand>
|
| | | <Item Name="[size]">d->size</Item>
|
| | | <Item Name="[referenced]">d->ref.atomic._q_value</Item>
|
| | | <ArrayItems>
|
| | | <Size>d->size</Size>
|
| | | <ValuePointer>((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),c</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QStringRef">
|
| | | <Intrinsic Name="offset" Expression="(reinterpret_cast<char16_t*>(m_string->d))
|
| | | + m_string->d->offset / 2" />
|
| | | <DisplayString Condition="m_string == nullptr">{m_string,[m_size]} u""</DisplayString>
|
| | | <DisplayString Condition="m_string != nullptr">{offset() + m_position,[m_size]}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[position]" ExcludeView="simple">m_position</Item>
|
| | | <Item Name="[size]" ExcludeView="simple">m_size</Item>
|
| | | <ArrayItems Condition="m_string != nullptr">
|
| | | <Size>m_size</Size>
|
| | | <ValuePointer>offset()+m_position</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QStringView">
|
| | | <DisplayString>{m_data,[m_size]}</DisplayString>
|
| | | <StringView>m_data,[m_size]</StringView>
|
| | | <Expand>
|
| | | <Item Name="[size]" ExcludeView="simple">m_size</Item>
|
| | | <ArrayItems>
|
| | | <Size>m_size</Size>
|
| | | <ValuePointer>m_data</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QByteArray">
|
| | | <DisplayString>{((reinterpret_cast<char*>(d)) + d->offset),sb}</DisplayString>
|
| | | <StringView>((reinterpret_cast<char*>(d)) + d->offset),sb</StringView>
|
| | | <Expand>
|
| | | <Item Name="[size]">d->size</Item>
|
| | | <Item Name="[referenced]">d->ref.atomic._q_value</Item>
|
| | | <ArrayItems>
|
| | | <Size>d->size</Size>
|
| | | <ValuePointer>((reinterpret_cast<char*>(d)) + d->offset),c</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QUrl">
|
| | | <Intrinsic Name="isEmpty" Expression="size==0">
|
| | | <Parameter Name="size" Type="int"/>
|
| | | </Intrinsic>
|
| | | <Intrinsic Name="memberOffset" Expression="sizeof(QAtomicInt) + sizeof(int) + (sizeof(QString) * count)">
|
| | | <Parameter Name="count" Type="int"/>
|
| | | </Intrinsic>
|
| | | <Intrinsic Name="scheme" Expression="*((QString*)(((char*)(d) + memberOffset(0))))" />
|
| | | <Intrinsic Name="username" Expression="*((QString*)(((char*)(d) + memberOffset(1))))" />
|
| | | <Intrinsic Name="password" Expression="*((QString*)(((char*)(d) + memberOffset(2))))" />
|
| | | <Intrinsic Name="host" Expression="*((QString*)(((char*)(d) + memberOffset(3))))" />
|
| | | <Intrinsic Name="path" Expression="*((QString*)(((char*)(d) + memberOffset(4))))" />
|
| | | <Intrinsic Name="query" Expression="*((QString*)(((char*)(d) + memberOffset(5))))" />
|
| | | <Intrinsic Name="fragment" Expression="*((QString*)(((char*)(d) + memberOffset(6))))" />
|
| | |
|
| | | <DisplayString Condition="!isEmpty(scheme().d->size)">{scheme()}://{host()}{path()}</DisplayString>
|
| | | <DisplayString Condition="isEmpty(scheme().d->size)">{path()}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[scheme]">scheme()</Item>
|
| | | <Item Name="[username]">username()</Item>
|
| | | <Item Name="[password]">password()</Item>
|
| | | <Item Name="[host]">host()</Item>
|
| | | <Item Name="[path]">path()</Item>
|
| | | <Item Name="[query]">query()</Item>
|
| | | <Item Name="[fragment]">fragment()</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QBitArray">
|
| | | <DisplayString>{{ size = {(d.d->size << 3) - *((reinterpret_cast<char*>(d.d)) + d.d->offset)} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[referenced]">d.d->ref.atomic._q_value</Item>
|
| | | <IndexListItems>
|
| | | <Size>(d.d->size << 3) - *((reinterpret_cast<char*>(d.d)) + d.d->offset)</Size>
|
| | | <ValueNode>
|
| | | (*(reinterpret_cast<const unsigned char*>((reinterpret_cast<char*>(d.d)) + d.d->offset) + 1
|
| | | + ($i >> 3)) & (1 << ($i & 7))) != 0
|
| | | </ValueNode>
|
| | | </IndexListItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QVarLengthArray<*>">
|
| | | <AlternativeType Name="##NAMESPACE##::QVarLengthArray<*, int>"/>
|
| | | <DisplayString>{{ size = {s} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[capacity]">a</Item>
|
| | | <ArrayItems>
|
| | | <Size>s</Size>
|
| | | <ValuePointer>ptr</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QDate">
|
| | | <DisplayString>{{ julian day = {jd} }}</DisplayString>
|
| | | <Expand></Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QTime">
|
| | | <DisplayString
|
| | | Condition="mds == 1">{{ millisecond = {mds} }}</DisplayString>
|
| | | <DisplayString
|
| | | Condition="mds != 1">{{ milliseconds = {mds} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[hour]"
|
| | | Condition="(mds / 3600000) == 1">mds / 3600000, d</Item>
|
| | | <Item Name="[hours]"
|
| | | Condition="(mds / 3600000) != 1">mds / 3600000, d</Item>
|
| | | <Item Name="[minute]"
|
| | | Condition="((mds % 3600000) / 60000) == 1">(mds % 3600000) / 60000, d</Item>
|
| | | <Item Name="[minutes]"
|
| | | Condition="((mds % 3600000) / 60000) != 1">(mds % 3600000) / 60000, d</Item>
|
| | | <Item Name="[second]"
|
| | | Condition="((mds / 1000) % 60) == 1">(mds / 1000) % 60, d</Item>
|
| | | <Item Name="[seconds]"
|
| | | Condition="((mds / 1000) % 60) != 1">(mds / 1000) % 60, d</Item>
|
| | | <Item Name="[millisecond]"
|
| | | Condition="(mds % 1000) == 1">mds % 1000, d</Item>
|
| | | <Item Name="[milliseconds]"
|
| | | Condition="(mds % 1000) != 1">mds % 1000, d</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QRegularExpression">
|
| | | <DisplayString>{d.pattern}</DisplayString>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QSharedData">
|
| | | <Expand>
|
| | | <Item Name="[referenced]">ref._q_value</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QSharedPointer<*>">
|
| | | <DisplayString>strong reference to shared pointer of type {"$T1"}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[is null]">value == 0</Item>
|
| | | <Item Name="[weak referenced]">d->weakref._q_value</Item>
|
| | | <Item Name="[strong referenced]">d->strongref._q_value</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QSharedDataPointer<*>">
|
| | | <DisplayString>pointer to implicit shared object of type {"$T1"}</DisplayString>
|
| | | <Expand>
|
| | | <ExpandedItem>d</ExpandedItem>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QExplicitlySharedDataPointer<*>">
|
| | | <DisplayString>pointer to explicit shared object of type {"$T1"}</DisplayString>
|
| | | <Expand>
|
| | | <ExpandedItem>d</ExpandedItem>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QPointer<*>">
|
| | | <DisplayString>guarded pointer to subclass of QObject of type {"$T1"}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[is null]">wp.d == 0 || wp.d->strongref._q_value == 0 || wp.value == 0</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QWeakPointer<*>">
|
| | | <DisplayString>weak reference to shared pointer of type {"$T1"}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[is null]">d == 0 || d->strongref._q_value == 0 || value == 0</Item>
|
| | | <Item Name="[weak referenced]">d->weakref._q_value</Item>
|
| | | <Item Name="[strong referenced]">d->strongref._q_value</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QScopedPointer<*>">
|
| | | <DisplayString>scoped pointer to a dynamically allocated object of type {"$T1"}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[is null]">!d</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QScopedArrayPointer<*>">
|
| | | <DisplayString>scoped pointer to dynamically allocated array of objects of type {"$T1"}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[is null]">!d</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QPair<*,*>">
|
| | | <DisplayString>({first}, {second})</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[first]">first</Item>
|
| | | <Item Name="[second]">second</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QVector<*>">
|
| | | <AlternativeType Name="##NAMESPACE##::QStack<*>"></AlternativeType>
|
| | | <DisplayString>{{ size = {d->size} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[referenced]">d->ref.atomic._q_value</Item>
|
| | | <ArrayItems>
|
| | | <Size>d->size</Size>
|
| | | <ValuePointer>($T1*)((reinterpret_cast<char*>(d)) + d->offset)</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QList<*>">
|
| | | <AlternativeType Name="##NAMESPACE##::QQueue<*>"></AlternativeType>
|
| | | <DisplayString>{{ size = {d->end - d->begin} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[referenced]">d->ref.atomic._q_value</Item>
|
| | | <IndexListItems>
|
| | | <Size>d->end - d->begin</Size>
|
| | | <ValueNode>*reinterpret_cast<$T1*>((sizeof($T1) > sizeof(void*))
|
| | | ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
|
| | | : reinterpret_cast<$T1*>(d->array + d->begin + $i))
|
| | | </ValueNode>
|
| | | </IndexListItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QStringList">
|
| | | <DisplayString>{{ size = {d->end - d->begin} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[referenced]">d->ref.atomic._q_value</Item>
|
| | | <IndexListItems>
|
| | | <Size>d->end - d->begin</Size>
|
| | | <ValueNode>
|
| | | *reinterpret_cast<QString*>((sizeof(QString) > sizeof(void*))
|
| | | ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
|
| | | : reinterpret_cast<QString*>(d->array + d->begin + $i))
|
| | | </ValueNode>
|
| | | </IndexListItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QList<QVariant>">
|
| | | <DisplayString>{{ size = {d->end - d->begin} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[referenced]">d->ref.atomic._q_value</Item>
|
| | | <IndexListItems>
|
| | | <Size>d->end - d->begin</Size>
|
| | | <ValueNode>
|
| | | *reinterpret_cast<QVariant*>((sizeof(QVariant) > sizeof(void*))
|
| | | ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
|
| | | : reinterpret_cast<QVariant*>(d->array + d->begin + $i))
|
| | | </ValueNode>
|
| | | </IndexListItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QLinkedList<*>">
|
| | | <DisplayString>{{ size = {d->size} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[referenced]">d->ref.atomic._q_value</Item>
|
| | | <LinkedListItems>
|
| | | <Size>d->size</Size>
|
| | | <HeadPointer>d->n</HeadPointer>
|
| | | <NextPointer>n</NextPointer>
|
| | | <ValueNode>(*(##NAMESPACE##::QLinkedListNode<$T1>*)this).t</ValueNode>
|
| | | </LinkedListItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QMapNode<*,*>">
|
| | | <DisplayString>({key}, {value})</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[key]">key</Item>
|
| | | <Item Name="[value]">value</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QMap<*,*>">
|
| | | <AlternativeType Name="##NAMESPACE##::QMultiMap<*,*>"/>
|
| | | <DisplayString>{{ size = {d->size} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[referenced]">d->ref.atomic._q_value</Item>
|
| | | <TreeItems>
|
| | | <Size>d->size</Size>
|
| | | <HeadPointer>d->header.left</HeadPointer>
|
| | | <LeftPointer>left</LeftPointer>
|
| | | <RightPointer>right</RightPointer>
|
| | | <ValueNode>*((##NAMESPACE##::QMapNode<$T1,$T2>*)this)</ValueNode>
|
| | | </TreeItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QHashNode<*,*>">
|
| | | <DisplayString Condition="next == 0">(empty)</DisplayString>
|
| | | <DisplayString Condition="next != 0">({key}, {value})</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[key]" Condition="next != 0">key</Item>
|
| | | <Item Name="[value]" Condition="next != 0">value</Item>
|
| | | <Item Name="[next]" Condition="next != 0">next</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QHash<*,*>">
|
| | | <AlternativeType Name="##NAMESPACE##::QMultiHash<*,*>"/>
|
| | | <DisplayString>{{ size = {d->size} }}</DisplayString>
|
| | | <Expand>
|
| | | <ArrayItems IncludeView="buckets">
|
| | | <Size>d->numBuckets</Size>
|
| | | <ValuePointer>reinterpret_cast<Node **>(d->buckets)</ValuePointer>
|
| | | </ArrayItems>
|
| | | <CustomListItems ExcludeView="buckets">
|
| | | <Variable Name="n" InitialValue="d->numBuckets"/>
|
| | | <Variable Name="bucket" InitialValue="d->buckets"/>
|
| | | <Variable Name="node" InitialValue="d->buckets[0]"/>
|
| | | <Variable Name="keyValuePair" InitialValue="reinterpret_cast<Node *>(0)"/>
|
| | | <Size>d->size</Size>
|
| | | <Loop>
|
| | | <Break Condition="n == 0"/>
|
| | | <Exec>node = *(bucket++)</Exec>
|
| | | <Exec>--n</Exec>
|
| | | <Loop>
|
| | | <Break Condition="!node || !node->next"/>
|
| | | <Exec>keyValuePair = reinterpret_cast<Node *>(node)</Exec>
|
| | | <Item Name="[{keyValuePair->key}]">keyValuePair->value</Item>
|
| | | <Exec>node = node->next</Exec>
|
| | | </Loop>
|
| | | </Loop>
|
| | | </CustomListItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QHashNode<*,##NAMESPACE##::QHashDummyValue>">
|
| | | <DisplayString Condition="next == 0">(empty)</DisplayString>
|
| | | <DisplayString Condition="next != 0">({key})</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[key]" Condition="next != 0">key</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QSet<*>">
|
| | | <DisplayString>{{ size = {q_hash.d->size} }}</DisplayString>
|
| | | <Expand>
|
| | | <ExpandedItem>q_hash</ExpandedItem>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QCache<*,*>::Node">
|
| | | <DisplayString>({*keyPtr}, {*t})</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[key]">*keyPtr</Item>
|
| | | <Item Name="[value]">*t</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QCache<*,*>">
|
| | | <DisplayString>{{ size = {hash.d->size} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[max coast]">mx</Item>
|
| | | <Item Name="[total coast]">total</Item>
|
| | | <Item Name="[referenced]">hash.d->ref.atomic._q_value</Item>
|
| | | <LinkedListItems>
|
| | | <Size>hash.d->size</Size>
|
| | | <HeadPointer>f</HeadPointer>
|
| | | <NextPointer>n</NextPointer>
|
| | | <ValueNode>*((Node*)this)</ValueNode>
|
| | | </LinkedListItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QStandardItemPrivate">
|
| | | <Intrinsic Name="memberOffset" Expression="sizeof(QStandardItemModel *)
|
| | | + sizeof(QStandardItem *)
|
| | | + sizeof(int *)
|
| | | + sizeof(int *)
|
| | | + (sizeof(int) * count)">
|
| | | <Parameter Name="count" Type="int"/>
|
| | | </Intrinsic>
|
| | | <Intrinsic Name="rows" Expression="*((int*)(((char*)(this)) + memberOffset(0)))" />
|
| | | <Intrinsic Name="columns" Expression="*((int*)(((char*)(this)) + memberOffset(1)))" />
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QStandardItem">
|
| | | <DisplayString>{{ row count = {(*d_ptr.d).rows()}, column count = {(*d_ptr.d).columns()} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[d]">d_ptr.d,!</Item>
|
| | | <Item Name="[row count]">(*d_ptr.d).rows()</Item>
|
| | | <Item Name="[column count]">(*d_ptr.d).columns()</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QVariant">
|
| | | <!--Region DisplayString QVariant-->
|
| | |
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::UnknownType">Invalid</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::Bool">{d.data.b}</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::Int">{d.data.i}</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::UInt">{d.data.u}</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::LongLong">{d.data.ll}</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::ULongLong">{d.data.ull}</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::Double">{d.data.d}</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QChar">{d.data.c}</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVariantMap">
|
| | | {*((##NAMESPACE##::QMap<##NAMESPACE##::QString,##NAMESPACE##::QVariant>*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVariantList">
|
| | | {*((##NAMESPACE##::QList<##NAMESPACE##::QVariant>*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QString">
|
| | | {*((##NAMESPACE##::QString*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QStringList">
|
| | | {*((##NAMESPACE##::QStringList*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QByteArray">
|
| | | {*((##NAMESPACE##::QByteArray*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QBitArray">
|
| | | {*((##NAMESPACE##::QBitArray*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QDate">
|
| | | {*((##NAMESPACE##::QDate*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QTime">
|
| | | {*((##NAMESPACE##::QTime*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QDateTime">DateTime</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QUrl">Url</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QLocale">Locale</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QRect">
|
| | | {*((##NAMESPACE##::QRect*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QRectF">
|
| | | {*((##NAMESPACE##::QRectF*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QSize">
|
| | | {*((##NAMESPACE##::QSize*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QSizeF">
|
| | | {*((##NAMESPACE##::QSizeF*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QLine">
|
| | | {*((##NAMESPACE##::QLine*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QLineF">
|
| | | {*((##NAMESPACE##::QLineF*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPoint">
|
| | | {*((##NAMESPACE##::QPoint*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPointF">
|
| | | {*((##NAMESPACE##::QPointF*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QRegExp">RegExp</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QRegularExpression">RegularExpression</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVariantHash">
|
| | | {*((##NAMESPACE##::QHash<##NAMESPACE##::QString,##NAMESPACE##::QVariant>*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))}
|
| | | </DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QEasingCurve">EasingCurve</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QUuid">Uuid</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QModelIndex">ModelIndex</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::LastCoreType">LastCoreType</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QFont">Font</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPixmap">Pixmap</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QBrush">Brush</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QColor">Color</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPalette">Palette</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QImage">Image</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPolygon">Polygon</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QRegion">Region</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QBitmap">Bitmap</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QCursor">Cursor</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QKeySequence">KeySequence</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPen">Pen</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QTextLength">TextLength</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QTextFormat">TextFormat</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QMatrix">Matrix</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QTransform">Transform</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QMatrix4x4">Matrix4x4</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVector2D">Vector2D</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVector3D">Vector3D</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVector4D">Vector4D</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QQuaternion">Quaternion</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPolygonF">PolygonF</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QIcon">Icon</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::LastGuiType">LastGuiType</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QSizePolicy">SizePolicy</DisplayString>
|
| | | <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::User">UserType</DisplayString>
|
| | | <DisplayString Condition="d.type == 0xffffffff">LastType</DisplayString>
|
| | |
|
| | | <!--End region DisplayString QVariant-->
|
| | |
|
| | | <!--Region DisplayView QVariant-->
|
| | |
|
| | | <StringView Condition="d.type == ##NAMESPACE##::QMetaType::QChar">d.data.c</StringView>
|
| | |
|
| | | <StringView Condition="d.type == ##NAMESPACE##::QMetaType::QString">
|
| | | *((##NAMESPACE##::QString*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </StringView>
|
| | |
|
| | | <StringView Condition="d.type == ##NAMESPACE##::QMetaType::QByteArray">
|
| | | *((##NAMESPACE##::QByteArray*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </StringView>
|
| | |
|
| | | <!--End region DisplayView QVariant-->
|
| | |
|
| | | <!--Region Expand QVariant-->
|
| | |
|
| | | <Expand>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QVariantMap">
|
| | | *((##NAMESPACE##::QMap<##NAMESPACE##::QString,##NAMESPACE##::QVariant>*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QVariantList">
|
| | | *((##NAMESPACE##::QList<##NAMESPACE##::QVariant>*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QString">
|
| | | *((##NAMESPACE##::QString*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QStringList">
|
| | | *((##NAMESPACE##::QStringList*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QByteArray">
|
| | | *((##NAMESPACE##::QByteArray*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QBitArray">
|
| | | *((##NAMESPACE##::QBitArray*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QDate">
|
| | | *((##NAMESPACE##::QDate*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QTime">
|
| | | *((##NAMESPACE##::QTime*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QRect">
|
| | | *((##NAMESPACE##::QRect*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QRectF">
|
| | | *((##NAMESPACE##::QRectF*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QSize">
|
| | | *((##NAMESPACE##::QSize*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QSizeF">
|
| | | *((##NAMESPACE##::QSizeF*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QLine">
|
| | | *((##NAMESPACE##::QLine*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QLineF">
|
| | | *((##NAMESPACE##::QLineF*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QPoint">
|
| | | *((##NAMESPACE##::QPoint*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QPointF">
|
| | | *((##NAMESPACE##::QPointF*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QVariantHash">
|
| | | *((##NAMESPACE##::QHash<##NAMESPACE##::QString,##NAMESPACE##::QVariant>*)(d.is_shared ? d.data.shared->ptr
|
| | | : reinterpret_cast<const void *>(&d.data.ptr)))
|
| | | </ExpandedItem>
|
| | | </Expand>
|
| | |
|
| | | <!--End region Expand QVariant-->
|
| | | </Type>
|
| | |
|
| | | </AutoVisualizer>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | ****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************
|
| | | -->
|
| | |
|
| | | <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
| | |
|
| | | <Type Name="##NAMESPACE##::QSpecialInteger<*>">
|
| | | <DisplayString>{val}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[value]">val</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QBasicAtomicInteger<*>">
|
| | | <DisplayString>{_q_value}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[value]">_q_value</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QBasicAtomicPointer<*>">
|
| | | <Intrinsic Name="isNull" Expression="value()==0" />
|
| | | <Intrinsic Name="value" Expression="_q_value.value()" />
|
| | | <DisplayString Condition="isNull()">empty</DisplayString>
|
| | | <DisplayString Condition="!isNull()">{_q_value}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name=" " Condition="!isNull()">*value()</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QPoint">
|
| | | <AlternativeType Name="##NAMESPACE##::QPointF"/>
|
| | | <DisplayString>{{ x = {xp}, y = {yp} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[x]">xp</Item>
|
| | | <Item Name="[y]">yp</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QRect">
|
| | | <DisplayString>{{ x = {x1}, y = {y1}, width = {x2 - x1 + 1}, height = {y2 - y1 + 1} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[x]">x1</Item>
|
| | | <Item Name="[y]">y1</Item>
|
| | | <Item Name="[width]">x2 - x1 + 1</Item>
|
| | | <Item Name="[height]">y2 - y1 + 1</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QRectF">
|
| | | <DisplayString>{{ x = {xp}, y = {yp}, width = {w}, height = {h} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[x]">xp</Item>
|
| | | <Item Name="[y]">yp</Item>
|
| | | <Item Name="[width]">w</Item>
|
| | | <Item Name="[height]">h</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QSize">
|
| | | <AlternativeType Name="##NAMESPACE##::QSizeF"/>
|
| | | <DisplayString>{{ width = {wd}, height = {ht} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[width]">wd</Item>
|
| | | <Item Name="[height]">ht</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QLine">
|
| | | <AlternativeType Name="##NAMESPACE##::QLineF"/>
|
| | | <DisplayString>{{ start point = {pt1}, end point = {pt2} }}</DisplayString>
|
| | | <Expand>
|
| | | <Synthetic Name="[start point]">
|
| | | <DisplayString>{pt1}</DisplayString>
|
| | | <Expand>
|
| | | <ExpandedItem>pt1</ExpandedItem>
|
| | | </Expand>
|
| | | </Synthetic>
|
| | | <Synthetic Name="[end point]">
|
| | | <DisplayString>{pt2}</DisplayString>
|
| | | <Expand>
|
| | | <ExpandedItem>pt2</ExpandedItem>
|
| | | </Expand>
|
| | | </Synthetic>
|
| | |
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QPolygon">
|
| | | <DisplayString>{{ size={d->size} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[referenced]">d->ref.atomic._q_value</Item>
|
| | | <ArrayItems>
|
| | | <Size>d->size</Size>
|
| | | <ValuePointer>(QPoint*)((reinterpret_cast<char*>(d)) + d->offset)</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QPolygonF">
|
| | | <DisplayString>{{ size={d->size} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[closed]">
|
| | | d->size > 0
|
| | | && ((((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[0]).xp
|
| | | == (((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[d->size - 1]).xp)
|
| | | && ((((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[0]).yp
|
| | | == (((QPointF*)((reinterpret_cast<char*>(d)) + d->offset)[d->size - 1]).yp)
|
| | | </Item>
|
| | | <Item Name="[referenced]">d->ref.atomic._q_value</Item>
|
| | | <ArrayItems>
|
| | | <Size>d->size</Size>
|
| | | <ValuePointer>(QPointF*)((reinterpret_cast<char*>(d)) + d->offset)</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QVector2D">
|
| | | <DisplayString>{{ x = {xp}, y = {yp} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[x]">xp</Item>
|
| | | <Item Name="[y]">yp</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QVector3D">
|
| | | <DisplayString>{{ x = {xp}, y = {yp}, z = {zp} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[x]">xp</Item>
|
| | | <Item Name="[y]">yp</Item>
|
| | | <Item Name="[z]">zp</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QVector4D">
|
| | | <DisplayString>{{ x = {xp}, y = {yp}, z = {zp}, w = {wp} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[x]">xp</Item>
|
| | | <Item Name="[y]">yp</Item>
|
| | | <Item Name="[z]">zp</Item>
|
| | | <Item Name="[w]">wp</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QMatrix">
|
| | | <DisplayString>
|
| | | {{ m11 = {_m11}, m12 = {_m12}, m21 = {_m21}, m22 = {_m22}, ... }}
|
| | | </DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[m11]">_m11</Item>
|
| | | <Item Name="[m12]">_m12</Item>
|
| | | <Item Name="[m21]">_m21</Item>
|
| | | <Item Name="[m22]">_m22</Item>
|
| | | <Item Name="[dx]">_dx</Item>
|
| | | <Item Name="[dy]">_dy</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QMatrix4x4">
|
| | | <DisplayString>
|
| | | {{ m11 = {m[0][0]}, m12 = {m[1][0]}, m13 = {m[2][0]}, m14 = {m[3][0]}, ... }}
|
| | | </DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[m11]">m[0][0]</Item>
|
| | | <Item Name="[m12]">m[1][0]</Item>
|
| | | <Item Name="[m13]">m[2][0]</Item>
|
| | | <Item Name="[m14]">m[3][0]</Item>
|
| | | <Item Name="[m21]">m[0][1]</Item>
|
| | | <Item Name="[m22]">m[1][1]</Item>
|
| | | <Item Name="[m23]">m[2][1]</Item>
|
| | | <Item Name="[m24]">m[3][1]</Item>
|
| | | <Item Name="[m31]">m[0][2]</Item>
|
| | | <Item Name="[m32]">m[1][2]</Item>
|
| | | <Item Name="[m33]">m[2][2]</Item>
|
| | | <Item Name="[m34]">m[3][2]</Item>
|
| | | <Item Name="[m41]">m[0][3]</Item>
|
| | | <Item Name="[m42]">m[1][3]</Item>
|
| | | <Item Name="[m43]">m[2][3]</Item>
|
| | | <Item Name="[m44]">m[3][3]</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QSizePolicy">
|
| | | <DisplayString>
|
| | | {{ horizontal = {static_cast<Policy>(bits.horPolicy)}, vertical = {static_cast<Policy>(bits.verPolicy)}, type = {ControlType(1 << bits.ctype)} }}
|
| | | </DisplayString>
|
| | | <Expand>
|
| | | <Synthetic Name="[vertical policy]">
|
| | | <DisplayString>QSizePolicy::Policy::{static_cast<Policy>(bits.verPolicy)}</DisplayString>
|
| | | </Synthetic>
|
| | | <Synthetic Name="[horizontal policy]">
|
| | | <DisplayString>QSizePolicy::Policy::{static_cast<Policy>(bits.horPolicy)}</DisplayString>
|
| | | </Synthetic>
|
| | | <Synthetic Name="[control type]">
|
| | | <DisplayString>QSizePolicy::ControlType::{ControlType(1 << bits.ctype)}</DisplayString>
|
| | | </Synthetic>
|
| | | <Synthetic Name="[expanding directions]">
|
| | | <DisplayString
|
| | | Condition="(static_cast<Policy>(bits.verPolicy) & ExpandFlag)">
|
| | | Qt::Vertical (2)
|
| | | </DisplayString>
|
| | | <DisplayString
|
| | | Condition="(static_cast<Policy>(bits.horPolicy) & ExpandFlag)">
|
| | | Qt::Horizontal (1)
|
| | | </DisplayString>
|
| | | </Synthetic>
|
| | | <Item Name="[vertical stretch]">static_cast<int>(bits.verStretch)</Item>
|
| | | <Item Name="[horizontal stretch]">static_cast<int>(bits.horStretch)</Item>
|
| | | <Item Name="[has height for width]">bits.hfw == 1</Item>
|
| | | <Item Name="[has width for height]">bits.wfh == 1</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QChar">
|
| | | <DisplayString>{ucs,c}</DisplayString>
|
| | | <StringView>ucs,c</StringView>
|
| | | <Expand>
|
| | | <Item Name="[latin 1]">ucs > 0xff ? '\0' : char(ucs),c</Item>
|
| | | <Item Name="[unicode]">ucs,c</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QString">
|
| | | <DisplayString>"{(reinterpret_cast<unsigned short*>(d.ptr)),sub}"</DisplayString>
|
| | | <StringView>(reinterpret_cast<unsigned short*>(d.ptr)),sub</StringView>
|
| | | <Expand>
|
| | | <Item Name="[size]">d.size</Item>
|
| | | <ArrayItems>
|
| | | <Size>d.size</Size>
|
| | | <ValuePointer>d.ptr</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QStringRef">
|
| | | <DisplayString Condition="m_string == nullptr">{m_string,[m_size]} u""</DisplayString>
|
| | | <DisplayString Condition="m_string != nullptr">{m_string->d.ptr+m_position,[m_size]}</DisplayString>
|
| | | <StringView Condition="m_string == nullptr">""</StringView>
|
| | | <StringView Condition="m_string != nullptr">m_string,[m_position+m_size]</StringView>
|
| | | <Expand>
|
| | | <Item Name="[position]" ExcludeView="simple">m_position</Item>
|
| | | <Item Name="[size]" ExcludeView="simple">m_size</Item>
|
| | | <ArrayItems Condition="m_string != nullptr">
|
| | | <Size>m_size</Size>
|
| | | <ValuePointer>m_string->d.ptr+m_position</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QStringView">
|
| | | <DisplayString>{m_data,[m_size]}</DisplayString>
|
| | | <StringView>m_data,[m_size]</StringView>
|
| | | <Expand>
|
| | | <Item Name="[size]" ExcludeView="simple">m_size</Item>
|
| | | <ArrayItems>
|
| | | <Size>m_size</Size>
|
| | | <ValuePointer>m_data</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QByteArray">
|
| | | <DisplayString>"{((reinterpret_cast<char*>(d.ptr))),sb}"</DisplayString>
|
| | | <StringView>((reinterpret_cast<char*>(d.ptr))),sb</StringView>
|
| | | <Expand>
|
| | | <Item Name="[size]">d.size</Item>
|
| | | <ArrayItems>
|
| | | <Size>d.size</Size>
|
| | | <ValuePointer>d.ptr</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QUrl">
|
| | | <Intrinsic Name="isEmpty" Expression="size==0">
|
| | | <Parameter Name="size" Type="int"/>
|
| | | </Intrinsic>
|
| | | <Intrinsic Name="memberOffset" Expression="sizeof(QAtomicInt) + sizeof(int) + (sizeof(QString) * count)">
|
| | | <Parameter Name="count" Type="int"/>
|
| | | </Intrinsic>
|
| | | <Intrinsic Name="scheme" Expression="*((QString*)(((char*)(d) + memberOffset(0))))" />
|
| | | <Intrinsic Name="username" Expression="*((QString*)(((char*)(d) + memberOffset(1))))" />
|
| | | <Intrinsic Name="password" Expression="*((QString*)(((char*)(d) + memberOffset(2))))" />
|
| | | <Intrinsic Name="host" Expression="*((QString*)(((char*)(d) + memberOffset(3))))" />
|
| | | <Intrinsic Name="path" Expression="*((QString*)(((char*)(d) + memberOffset(4))))" />
|
| | | <Intrinsic Name="query" Expression="*((QString*)(((char*)(d) + memberOffset(5))))" />
|
| | | <Intrinsic Name="fragment" Expression="*((QString*)(((char*)(d) + memberOffset(6))))" />
|
| | |
|
| | | <DisplayString Condition="!isEmpty(scheme().d->size)">{scheme()}://{host()}{path()}</DisplayString>
|
| | | <DisplayString Condition="isEmpty(scheme().d->size)">{path()}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[scheme]">scheme()</Item>
|
| | | <Item Name="[username]">username()</Item>
|
| | | <Item Name="[password]">password()</Item>
|
| | | <Item Name="[host]">host()</Item>
|
| | | <Item Name="[path]">path()</Item>
|
| | | <Item Name="[query]">query()</Item>
|
| | | <Item Name="[fragment]">fragment()</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QDate">
|
| | | <DisplayString>{{ julian day = {jd} }}</DisplayString>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QTime">
|
| | | <Intrinsic Name="hour" Expression="mds / 3600000" />
|
| | | <Intrinsic Name="minute" Expression="(mds % 3600000) / 60000" />
|
| | | <Intrinsic Name="second" Expression="(mds / 1000) % 60" />
|
| | | <Intrinsic Name="millisecond" Expression="mds % 1000" />
|
| | | <DisplayString Condition="mds == 1">{{ millisecond = {mds} }}</DisplayString>
|
| | | <DisplayString Condition="mds != 1">{{ milliseconds = {mds} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[hour]"
|
| | | Condition="(mds / 3600000) == 1">hour(), d</Item>
|
| | | <Item Name="[hours]"
|
| | | Condition="(mds / 3600000) != 1">hour(), d</Item>
|
| | | <Item Name="[minute]"
|
| | | Condition="((mds % 3600000) / 60000) == 1">minute(), d</Item>
|
| | | <Item Name="[minutes]"
|
| | | Condition="((mds % 3600000) / 60000) != 1">minute(), d</Item>
|
| | | <Item Name="[second]"
|
| | | Condition="((mds / 1000) % 60) == 1">second(), d</Item>
|
| | | <Item Name="[seconds]"
|
| | | Condition="((mds / 1000) % 60) != 1">second(), d</Item>
|
| | | <Item Name="[millisecond]"
|
| | | Condition="(mds % 1000) == 1">millisecond(), d</Item>
|
| | | <Item Name="[milliseconds]"
|
| | | Condition="(mds % 1000) != 1">millisecond(), d</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QPair<*,*>">
|
| | | <DisplayString>({first}, {second})</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[first]">first</Item>
|
| | | <Item Name="[second]">second</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QList<*>">
|
| | | <AlternativeType Name="##NAMESPACE##::QVector<*>"/>
|
| | | <DisplayString>{{ size={d.size} }}</DisplayString>
|
| | | <Expand>
|
| | | <ArrayItems>
|
| | | <Size>d.size</Size>
|
| | | <ValuePointer>reinterpret_cast<$T1*>(d.ptr)</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QVarLengthArray<*>">
|
| | | <DisplayString>{{ size={s} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[capacity]">a</Item>
|
| | | <ArrayItems>
|
| | | <Size>s</Size>
|
| | | <ValuePointer>ptr</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QMap<*,*>">
|
| | | <AlternativeType Name="##NAMESPACE##::QMultiMap<*,*>"/>
|
| | | <DisplayString>{{ size={d.d->m._Mypair._Myval2._Myval2._Mysize} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[std::map]">d.d->m</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QHash<*,*>">
|
| | | <AlternativeType Name="##NAMESPACE##::QMultiHash<*,*>"/>
|
| | | <DisplayString>{{ size = {d->size} }}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[referenced]">d->ref.atomic._q_value</Item>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | </AutoVisualizer>
|
| | |
| | | <QtPathBinaries>bin</QtPathBinaries>
|
| | | <QtPathLibraryExecutables>bin</QtPathLibraryExecutables>
|
| | |
|
| | | <!--// Run Qt tools during design-time build -->
|
| | | <QtToolsDesignTime>true</QtToolsDesignTime>
|
| | |
|
| | | <!--// qmake template -->
|
| | | <QtQMakeTemplate>vcapp</QtQMakeTemplate>
|
| | |
|
| | |
| | | DEFINES=/Project/ItemDefinitionGroup/ClCompile/PreprocessorDefinitions;
|
| | | INCLUDEPATH=/Project/ItemDefinitionGroup/ClCompile/AdditionalIncludeDirectories;
|
| | | STDCPP=/Project/ItemDefinitionGroup/ClCompile/LanguageStandard;
|
| | | RUNTIME=/Project/ItemDefinitionGroup/ClCompile/RuntimeLibrary;
|
| | | CL_OPTIONS=/Project/ItemDefinitionGroup/ClCompile/AdditionalOptions;
|
| | | LIBS=/Project/ItemDefinitionGroup/Link/AdditionalDependencies;
|
| | | LINK_OPTIONS=/Project/ItemDefinitionGroup/Link/AdditionalOptions;
|
| | |
| | | <!--// Qt build config -->
|
| | | <QtBuildConfig Condition="'$(Configuration)' == 'Debug'">debug</QtBuildConfig>
|
| | | <QtBuildConfig Condition="'$(Configuration)' != 'Debug'">release</QtBuildConfig>
|
| | |
|
| | | <!--// Qt Plugin default-->
|
| | | <QtPlugin>false</QtPlugin>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | |
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Set up inner build if Qt vars property file is outdated
|
| | | // -->
|
| | | <PropertyGroup Condition="'$(QtInnerBuild)' == ''">
|
| | | <QtVarsOutdated>false</QtVarsOutdated>
|
| | | <QtVarsOutdated
|
| | | Condition="!Exists('$(QtVarsFilePath)')
|
| | | OR '$(QtBkup_QtInstall)' != '$(QtInstall)'
|
| | | OR '$(QtBkup_QtModules)' != '$(QtModules)'
|
| | | OR '$(QtBkup_QtPathBinaries)' != '$(QtPathBinaries)'
|
| | | OR '$(QtBkup_QtPathLibraryExecutables)' != '$(QtPathLibraryExecutables)'
|
| | | OR '$(QtBkup_QtHeaderSearchPath)' != '$(QtHeaderSearchPath)'
|
| | | OR '$(QtBkup_QtLibrarySearchPath)' != '$(QtLibrarySearchPath)'
|
| | | OR '$(QtBkup_QtVars)' != '$(QtVars)'
|
| | | OR '$(QtBkup_QMakeCodeLines)' != '$(QMakeCodeLines)'
|
| | | OR '$(QtBkup_QtBuildConfig)' != '$(QtBuildConfig)'"
|
| | | >true</QtVarsOutdated>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!-- // Enable inner build targets -->
|
| | | <Import Condition="'$(QtVarsOutdated)' == 'true'" Project="qt_inner.targets"/>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtGetDefaultClCompile
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Get default C++ properties
|
| | |
| | | OR ('$(project_changed)' == 'true' AND '$(log_hash)' != '$(work_hash)')"
|
| | | >true</do_work>
|
| | | <skip_work
|
| | | Condition="'$(do_work)' != 'true' OR '$(DesignTimeBuild)' == 'true'"
|
| | | Condition="'$(do_work)' != 'true'
|
| | | OR ('$(QtDesignTimeBuild)' == 'true' AND '$(QtToolsDesignTime)' != 'true')"
|
| | | >true</skip_work>
|
| | | </PropertyGroup>
|
| | |
|
| | |
| | | // -->
|
| | | <QtRunWork
|
| | | Condition="'$(ApplicationType)' != 'Linux' AND '@(QtWork)' != ''
|
| | | AND '%(QtWork.ParallelBuild)' == 'true'
|
| | | AND '$(DesignTimeBuild)' != 'true'"
|
| | | AND '%(QtWork.ParallelBuild)' == 'true'"
|
| | | QtWork="@(QtWork)" QtMaxProcs="$(QtMaxProcs)" QtDebug="$(QtDebug)">
|
| | | <Output TaskParameter="Result" ItemName="QtWorkResult" />
|
| | | </QtRunWork>
|
| | |
| | | // -->
|
| | | <QtRunWork
|
| | | Condition="'$(ApplicationType)' != 'Linux' AND '@(QtWork)' != ''
|
| | | AND '%(QtWork.ParallelBuild)' != 'true'
|
| | | AND '$(DesignTimeBuild)' != 'true'"
|
| | | AND '%(QtWork.ParallelBuild)' != 'true'"
|
| | | QtWork="@(QtWork)" QtMaxProcs="1" QtDebug="$(QtDebug)">
|
| | | <Output TaskParameter="Result" ItemName="QtWorkResult" />
|
| | | </QtRunWork>
|
| | |
| | | <!-- // Translate local paths to host paths -->
|
| | | <Flatten
|
| | | Condition="'$(ApplicationType)' == 'Linux'
|
| | | AND '@(QtWork)' != '' AND '$(DesignTimeBuild)' != 'true'"
|
| | | AND '@(QtWork)' != '' AND '$(QtDesignTimeBuild)' != 'true'"
|
| | | Items="@(QtWork)" Metadata="ResourceFiles">
|
| | | <Output TaskParameter="Result" ItemName="ResourceFiles"/>
|
| | | </Flatten>
|
| | | <ItemGroup
|
| | | Condition="'$(ApplicationType)' == 'Linux'
|
| | | AND '@(QtWork)' != '' AND '$(DesignTimeBuild)' != 'true'">
|
| | | AND '@(QtWork)' != '' AND '$(QtDesignTimeBuild)' != 'true'">
|
| | | <LocalPath Include="%(QtWork.Identity)">
|
| | | <Name>InputPath</Name>
|
| | | <Item>%(QtWork.Identity)</Item>
|
| | |
| | | </ItemGroup>
|
| | | <HostTranslatePaths
|
| | | Condition="'$(ApplicationType)' == 'Linux'
|
| | | AND '@(QtWork)' != '' AND '$(DesignTimeBuild)' != 'true'"
|
| | | AND '@(QtWork)' != '' AND '$(QtDesignTimeBuild)' != 'true'"
|
| | | Items="@(LocalPath)" Names="InputPath;OutputPath">
|
| | | <Output TaskParameter="Result" ItemName="HostPath"/>
|
| | | </HostTranslatePaths>
|
| | |
| | | <!-- // Run command -->
|
| | | <HostExec
|
| | | Condition="'$(ApplicationType)' == 'Linux'
|
| | | AND '%(Identity)' != '' AND '$(DesignTimeBuild)' != 'true'"
|
| | | AND '%(Identity)' != '' AND '$(QtDesignTimeBuild)' != 'true'"
|
| | | Message="@(QtWork->'%(WorkType) %(Identity)')"
|
| | | Command="@(QtWork->'%(ToolPath) %(Options)')"
|
| | | Inputs="@(InputPath)"
|
| | |
| | | <!-- // Generate result item -->
|
| | | <ItemGroup
|
| | | Condition="'$(ApplicationType)' == 'Linux'
|
| | | AND '@(QtWork)' != '' AND '$(DesignTimeBuild)' != 'true'">
|
| | | AND '@(QtWork)' != '' AND '$(QtDesignTimeBuild)' != 'true'">
|
| | | <QtWorkResult Include="@(QtWork)">
|
| | | <ExitCode>0</ExitCode>
|
| | | </QtWorkResult>
|
| | |
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Save tracking log of files read during build; used by VS to check the up-to-date status
|
| | | // -->
|
| | | <ItemGroup Condition="'$(DesignTimeBuild)' != 'true' AND '$(QtVSToolsBuild)' != 'true'">
|
| | | <ItemGroup>
|
| | | <read_log Include="^%(QtWorkResult.FullPath);%(QtWorkResult.AdditionalDependencies)"
|
| | | Condition="'%(QtWorkResult.ExitCode)' == '0' AND '%(QtWorkResult.DisableLog)' != 'true'">
|
| | | Condition="'%(QtWorkResult.ExitCode)' == '0'
|
| | | AND '%(QtWorkResult.DisableLog)' != 'true'
|
| | | AND '%(QtWorkResult.Skipped)' != 'true'">
|
| | | <WorkType>%(QtWorkResult.WorkType)</WorkType>
|
| | | </read_log>
|
| | | <read_log>
|
| | |
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Save tracking log of files written during build; used by VS to check the up-to-date status
|
| | | // -->
|
| | | <ItemGroup Condition="'$(DesignTimeBuild)' != 'true' AND '$(QtVSToolsBuild)' != 'true'">
|
| | | <ItemGroup>
|
| | | <write_log Include="^%(QtWorkResult.FullPath);%(QtWorkResult.OutputFile)"
|
| | | Condition="'%(QtWorkResult.ExitCode)' == '0' AND '%(QtWorkResult.DisableLog)' != 'true'">
|
| | | Condition="'%(QtWorkResult.ExitCode)' == '0'
|
| | | AND '%(QtWorkResult.DisableLog)' != 'true'
|
| | | AND '%(QtWorkResult.Skipped)' != 'true'">
|
| | | <WorkType>%(QtWorkResult.WorkType)</WorkType>
|
| | | </write_log>
|
| | | <write_log>
|
| | |
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Log output files; this is used by VS to determine what files to delete on "Clean"
|
| | | // -->
|
| | | <ItemGroup Condition="'$(DesignTimeBuild)' != 'true' AND '$(QtVSToolsBuild)' != 'true'">
|
| | | <ItemGroup>
|
| | | <clean_log Include="%(QtWorkResult.OutputFile)"
|
| | | Condition="'%(QtWorkResult.ExitCode)' == '0'">
|
| | | <Source>@(QtWorkResult, '|')</Source>
|
| | |
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Log calls to Qt tools; used in QtWorkPrepare to detect changes to the options of Qt tools
|
| | | // -->
|
| | | <WriteLinesToFile Condition="'@(QtWorkLog)' != '' AND '$(DesignTimeBuild)' != 'true'"
|
| | | <WriteLinesToFile Condition="'@(QtWorkLog)' != ''"
|
| | | File="$(QtLogFilePath)"
|
| | | Lines="@(QtWorkLog->'%(Identity)|%(Hash)')"
|
| | | Overwrite="true" Encoding="Unicode"/>
|
| | |
| | | // -->
|
| | | <Error
|
| | | Condition="'%(QtWorkResult.ExitCode)' != ''
|
| | | AND '%(QtWorkResult.ExitCode)' != '0'
|
| | | AND '$(DesignTimeBuild)' != 'true'"
|
| | | AND '%(QtWorkResult.ExitCode)' != '0'"
|
| | | File="%(QtWorkResult.Identity)" Code="%(QtWorkResult.ExitCode)"
|
| | | Text="%(QtWorkResult.WorkType) (%(QtWorkResult.ToolPath))"/>
|
| | |
|
| | |
| | | // Clean-up
|
| | | // -->
|
| | | <ItemGroup>
|
| | | <ClCompile Remove="DefaultClCompile" />
|
| | | <QtWork Remove="@(QtWork)"/>
|
| | | <QtWorkResult Remove="@(QtWorkResult)"/>
|
| | | <QtWorkLog Remove="@(QtWorkLog)"/>
|
| | |
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET Qt
|
| | | /// TARGET QtSetAdditionalOptions
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Root Qt target
|
| | | // Adds additional compiler options flowing from Qt.
|
| | | // Skips options that are already specified in the user project.
|
| | | // -->
|
| | | <Target Name="Qt" DependsOnTargets="QtPrepare;QtWork" BeforeTargets="FixupCLCompileOptions">
|
| | | <Target Name="QtSetAdditionalOptions" Condition="'@(ClCompile)' != ''">
|
| | |
|
| | | <!-- Command line parser regex -->
|
| | | <PropertyGroup>
|
| | | <CmdLineParser>"[^"]*"|[^\s]+</CmdLineParser>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!-- Parse compiler options from Qt -->
|
| | | <PropertyGroup>
|
| | | <QtCmdLine
|
| | | >$([System.Text.RegularExpressions.Regex]::Matches(
|
| | | '$(Qt_CL_OPTIONS_)', '$(CmdLineParser)'))</QtCmdLine>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!-- Calculate command line for each source file in the project -->
|
| | | <QtRunTask
|
| | | Items="@(ClCompile)"
|
| | | AssemblyPath="$(VCTargetsPath)\Microsoft.Build.CPPTasks.Common.dll"
|
| | | TaskName="Microsoft.Build.CPPTasks.CLCommandLine"
|
| | | TaskInput="Sources"
|
| | | TaskOutput="CommandLines"
|
| | | NewMetadata="ProjectOptions">
|
| | | <Output TaskParameter="Result" ItemName="ClCompile_CmdLine" />
|
| | | </QtRunTask>
|
| | |
|
| | | <!-- Append excluded Qt options to calculated command line -->
|
| | | <ItemGroup>
|
| | | <ClCompile Remove="DefaultClCompile" />
|
| | | <ClCompile_CmdLine Condition="'$(QtExcludedOptions)' != ''">
|
| | | <ProjectOptions>%(ProjectOptions) $(QtExcludedOptions)</ProjectOptions>
|
| | | </ClCompile_CmdLine>
|
| | | </ItemGroup>
|
| | | <CriticalSection Lock="false" Name="$(ProjectGuid)" />
|
| | | <OnError ExecuteTargets="QtLeaveCriticalSection_OnError"/>
|
| | |
|
| | | <!-- Parse compiler command line of each source file -->
|
| | | <ItemGroup>
|
| | | <ClCompile_CmdLine>
|
| | | <ProjectOptions
|
| | | >$([System.Text.RegularExpressions.Regex]::Matches(
|
| | | '%(ProjectOptions)', '$(CmdLineParser)'))</ProjectOptions>
|
| | | </ClCompile_CmdLine>
|
| | | </ItemGroup>
|
| | |
|
| | | <!-- Add (previously parsed) Qt options to each source file -->
|
| | | <ItemGroup>
|
| | | <ClCompile_CmdLine>
|
| | | <QtOptions>$(QtCmdLine)</QtOptions>
|
| | | </ClCompile_CmdLine>
|
| | | </ItemGroup>
|
| | |
|
| | | <!-- Result of parsing command lines, per source file:
|
| | | * ClCompile_CmdLine ::= (Item x ProjectOptions x QtOptions), where:
|
| | | * Item ::= source file
|
| | | * ProjectOptions ::= list of tokens from the compiler command line for Item
|
| | | * QtOptions ::= list of tokens from the Qt additional options -->
|
| | |
|
| | | <!-- Flatten results into a list of tokens per source file:
|
| | | * ClOptions ::= (Item x Name x Value), where:
|
| | | * Item ::= source file
|
| | | * Name ::= token origin: from compiler command line or from Qt
|
| | | * Value ::= token value -->
|
| | | <Flatten Items="@(ClCompile_CmdLine)" Metadata="ProjectOptions;QtOptions">
|
| | | <Output TaskParameter="Result" ItemName="ClOptions" />
|
| | | </Flatten>
|
| | |
|
| | | <!-- Remove non-switch tokens, i.e. tokens that do not start with '/' or '-' -->
|
| | | <ItemGroup>
|
| | | <ClOptions
|
| | | Remove="@(ClOptions)"
|
| | | Condition="!$([System.String]::Copy('%(Value)').StartsWith('-'))
|
| | | AND !$([System.String]::Copy('%(Value)').StartsWith('/'))"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <!-- Calculate option id: token without leading '/' or '-', and without trailing '-' -->
|
| | | <ItemGroup>
|
| | | <ClOptions>
|
| | | <OptionId>$([System.String]::Copy('%(Value)').Substring(1).TrimEnd('-'))</OptionId>
|
| | | </ClOptions>
|
| | | </ItemGroup>
|
| | |
|
| | | <!-- Split into list of Qt options and list of project options -->
|
| | | <ItemGroup>
|
| | | <QtOptions
|
| | | Include="@(ClOptions->'%(Item)')"
|
| | | Condition="'%(ClOptions.Name)' == 'QtOptions'"/>
|
| | | <ProjectOptions
|
| | | Include="@(ClOptions->'%(Item)')"
|
| | | Condition="'%(ClOptions.Name)' == 'ProjectOptions'"/>
|
| | | </ItemGroup>
|
| | |
|
| | | <!-- Find conflicting options, i.e. defined both in Qt options and project options -->
|
| | | <ItemGroup>
|
| | | <QtOptions
|
| | | Condition="'@(QtOptions)' != ''
|
| | | AND '@(ProjectOptions)' != ''
|
| | | AND '%(Item)' != ''
|
| | | AND '%(OptionId)' != ''">
|
| | | <Conflict>true</Conflict>
|
| | | </QtOptions>
|
| | | </ItemGroup>
|
| | |
|
| | | <!-- Set additional compiler options for all source files -->
|
| | | <ItemGroup>
|
| | | <ClCompile Condition="'%(Identity)' != '' AND '%(QtOptions.Conflict)' != 'true'">
|
| | | <AdditionalOptions
|
| | | >@(QtOptions->'%(Value)', ' ') @(ClCompile->'%(AdditionalOptions)')</AdditionalOptions>
|
| | | </ClCompile>
|
| | | <ClCompile Condition="'%(AdditionalOptions)' != ''">
|
| | | <AdditionalOptions
|
| | | >$([System.String]::Copy('%(AdditionalOptions)').Trim())</AdditionalOptions>
|
| | | </ClCompile>
|
| | | </ItemGroup>
|
| | |
|
| | | <!-- Print result to build log, if requested -->
|
| | | <Message
|
| | | Condition="'$(QtOptionsBuildLog)' == 'true'"
|
| | | Importance="High"
|
| | | Text=" Qt - Additional Compiler Options"/>
|
| | | <Message
|
| | | Condition="'$(QtOptionsBuildLog)' == 'true'
|
| | | AND '%(Identity)' != '' AND '%(QtOptions.Conflict)' != 'true'"
|
| | | Importance="High"
|
| | | Text=" [%(Identity)]: @(QtOptions->'%(Value)', ' ')"/>
|
| | |
|
| | | <!-- Clean-up -->
|
| | | <PropertyGroup>
|
| | | <CmdLineParser/>
|
| | | <QtCmdLine/>
|
| | | </PropertyGroup>
|
| | | <ItemGroup>
|
| | | <ClCompile_CmdLine Remove="@(ClCompile_CmdLine)"/>
|
| | | <ClOptions Remove="@(ClOptions)"/>
|
| | | <ProjectOptions Remove="@(ProjectOptions)"/>
|
| | | <QtOptions Remove="@(QtOptions)"/>
|
| | | </ItemGroup>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtOuterBuild
|
| | | /// TARGET Qt
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Run targets in $(QtOuterBuildDependsOn) and then recursively invoke build
|
| | | // Root Qt target
|
| | | // -->
|
| | | <Target Name="QtOuterBuild" DependsOnTargets="$(QtOuterBuildDependsOn)">
|
| | | <!--// Invoke inner build: recursive build in second MSBuild instance -->
|
| | | <MSBuild
|
| | | Projects="$(MSBuildProjectFullPath)"
|
| | | Targets="Build"
|
| | | Properties="QtInnerBuild=$(MSBuildProjectFullPath);RandomFileName=$(RandomFileName);BuildProjectReferences=false">
|
| | | </MSBuild>
|
| | | <Target
|
| | | Name="Qt"
|
| | | DependsOnTargets="QtPrepare;QtWork;QtSetAdditionalOptions">
|
| | | <CriticalSection Lock="false" Name="$(ProjectGuid)" />
|
| | | <OnError ExecuteTargets="QtLeaveCriticalSection_OnError"/>
|
| | | </Target>
|
| | |
|
| | | <PropertyGroup
|
| | | Condition="'$(QtInnerBuild)' == '' AND '$(DesignTimeBuild)' != 'true'">
|
| | | <!--// Outer build: invoke inner build -->
|
| | | <BuildDependsOn>
|
| | | $(QtOuterBuildPrepare);
|
| | | QtOuterBuild;
|
| | | $(QtOuterBuildFinalize)
|
| | | </BuildDependsOn>
|
| | | <QtInnerBuild>$(MSBuildProjectFullPath)</QtInnerBuild>
|
| | | <RandomFileName>$([System.IO.Path]::GetRandomFileName())</RandomFileName>
|
| | | </PropertyGroup>
|
| | |
|
| | | <PropertyGroup
|
| | | Condition="'$(QtInnerBuild)' != '$(MSBuildProjectFullPath)' AND '$(DesignTimeBuild)' != 'true'">
|
| | | <!--// Dependent project inner build: skip build -->
|
| | | <BuildDependsOn>$(QtOuterBuildPrepare);$(QtOuterBuildFinalize)</BuildDependsOn>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | |
| | | <Target Name="QtLeaveCriticalSection_OnError">
|
| | | <CriticalSection Lock="false" Name="$(ProjectGuid)" />
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtNatvis
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Copies the .natvis file matching the Qt version and replaces the namespace placeholder
|
| | | // -->
|
| | | <Target Name="QtNatvis" BeforeTargets="Link"
|
| | | Condition="'$(Configuration)' == 'Debug' AND '$(LinkNatvisFile)' == 'true'"
|
| | | Inputs="$(MSBuildProjectFile);$(QtMsBuild)\qt$(QtVersionMajor).natvis.xml"
|
| | | Outputs="$(IntDir)\qt.natvis">
|
| | | <PropertyGroup>
|
| | | <InputFile>$(QtMsBuild)\qt$(QtVersionMajor).natvis.xml</InputFile>
|
| | | </PropertyGroup>
|
| | | <WriteLinesToFile Condition="'$(QtNamespace)' == ''"
|
| | | Overwrite="true"
|
| | | File="$(IntDir)\qt.natvis"
|
| | | Lines="$([System.IO.File]::ReadAllText($(InputFile)).Replace('##NAMESPACE##::',''))" />
|
| | | <WriteLinesToFile Condition="'$(QtNamespace)' != ''"
|
| | | Overwrite="true"
|
| | | File="$(IntDir)\qt.natvis"
|
| | | Lines="$([System.IO.File]::ReadAllText($(InputFile)).Replace('##NAMESPACE##','$(QtNamespace)'))" />
|
| | | </Target>
|
| | |
|
| | | </Project>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | | -->
|
| | | <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
| | |
|
| | | <PropertyGroup
|
| | | Condition="'$(QtInnerBuild)' == ''">
|
| | | <!--// Outer build: invoke inner build -->
|
| | | <BuildDependsOn>
|
| | | $(QtOuterBuildPrepare);
|
| | | QtOuterBuild;
|
| | | $(QtOuterBuildFinalize)
|
| | | </BuildDependsOn>
|
| | | <QtInnerBuild>$(MSBuildProjectFullPath)</QtInnerBuild>
|
| | | <RandomFileName>$([System.IO.Path]::GetRandomFileName())</RandomFileName>
|
| | | </PropertyGroup>
|
| | |
|
| | | <PropertyGroup
|
| | | Condition="'$(QtInnerBuild)' != '$(MSBuildProjectFullPath)'">
|
| | | <!--// Dependent project inner build: skip build -->
|
| | | <BuildDependsOn>$(QtOuterBuildPrepare);$(QtOuterBuildFinalize)</BuildDependsOn>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET QtOuterBuild
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Run targets in $(QtOuterBuildDependsOn) and then recursively invoke build
|
| | | // -->
|
| | | <Target Name="QtOuterBuild" DependsOnTargets="$(QtOuterBuildDependsOn)">
|
| | | <!--// Invoke inner build: recursive build in second MSBuild instance -->
|
| | | <MSBuild
|
| | | Projects="$(MSBuildProjectFullPath)"
|
| | | Targets="Build"
|
| | | Properties="QtInnerBuild=$(MSBuildProjectFullPath);RandomFileName=$(RandomFileName);BuildProjectReferences=false">
|
| | | </MSBuild>
|
| | | <OnError ExecuteTargets="QtLeaveCriticalSection_OnError"/>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET GetClCommandLineForReference
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | //
|
| | | // -->
|
| | | <Target
|
| | | Name="GetClCommandLineForReference"
|
| | | DependsOnTargets="$(QtOuterBuildDependsOn)"
|
| | | Returns="@(ClCommandLineForReference)">
|
| | | <MSBuild
|
| | | Projects="$(MSBuildProjectFullPath)"
|
| | | Targets="GetClCommandLineForReference"
|
| | | Properties="QtInnerBuild=$(MSBuildProjectFullPath);RandomFileName=$(RandomFileName);BuildProjectReferences=false">
|
| | | <Output TaskParameter="TargetOutputs" ItemName="ClCommandLineForReference"/>
|
| | | </MSBuild>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET GetGeneratedFiles
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | //
|
| | | // -->
|
| | | <Target
|
| | | Name="GetGeneratedFiles"
|
| | | DependsOnTargets="$(QtOuterBuildDependsOn)"
|
| | | Returns="@(_GeneratedFiles)">
|
| | | <MSBuild
|
| | | Projects="$(MSBuildProjectFullPath)"
|
| | | Targets="GetGeneratedFiles"
|
| | | Properties="QtInnerBuild=$(MSBuildProjectFullPath);RandomFileName=$(RandomFileName);BuildProjectReferences=false">
|
| | | <Output TaskParameter="TargetOutputs" ItemName="_GeneratedFiles"/>
|
| | | </MSBuild>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET GetProjectReferencesInfo
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | //
|
| | | // -->
|
| | | <Target
|
| | | Name="GetProjectReferencesInfo"
|
| | | DependsOnTargets="$(QtOuterBuildDependsOn)"
|
| | | Returns="@(_ProjectReferencesInfo)">
|
| | | <MSBuild
|
| | | Projects="$(MSBuildProjectFullPath)"
|
| | | Targets="GetProjectReferencesInfo"
|
| | | Properties="QtInnerBuild=$(MSBuildProjectFullPath);RandomFileName=$(RandomFileName);BuildProjectReferences=false">
|
| | | <Output TaskParameter="TargetOutputs" ItemName="_ProjectReferencesInfo"/>
|
| | | </MSBuild>
|
| | | </Target>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TARGET GetClCommandLines
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | //
|
| | | // -->
|
| | | <Target
|
| | | Name="GetClCommandLines"
|
| | | DependsOnTargets="$(QtOuterBuildDependsOn)"
|
| | | Returns="@(ClCommandLines)">
|
| | | <MSBuild
|
| | | Projects="$(MSBuildProjectFullPath)"
|
| | | Targets="GetClCommandLines"
|
| | | Properties="QtInnerBuild=$(MSBuildProjectFullPath);RandomFileName=$(RandomFileName);BuildProjectReferences=false">
|
| | | <Output TaskParameter="TargetOutputs" ItemName="ClCommandLines"/>
|
| | | </MSBuild>
|
| | | </Target>
|
| | | </Project>
|
| | |
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Check if design-time build
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <QtDesignTimeBuild>false</QtDesignTimeBuild>
|
| | | <QtDesignTimeBuild
|
| | | Condition="'$(DesignTimeBuild)' == 'true'
|
| | | OR '$(QtVSToolsBuild)' == 'true'"
|
| | | >true</QtDesignTimeBuild>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Setup Qt installation path
|
| | | // -->
|
| | | <PropertyGroup Condition="'$(QtVsProjectSettings)' == 'true'">
|
| | |
| | | >$([System.String]::Copy($([System.IO.File]::ReadAllText('$(QtVarsIndexPathDesignTime)'))).Replace('
',''))</QtVarsDesignTime>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--// Import Qt variables (full build) -->
|
| | | <Import
|
| | | Condition="'$(DesignTimeBuild)' != 'true' AND Exists('$(QtVarsFilePath)')"
|
| | | Project="$(QtVarsFilePath)"/>
|
| | | <PropertyGroup>
|
| | | <!--// Path to Qt variables .props: full build -->
|
| | | <QtVarsImportPath
|
| | | Condition="'$(QtDesignTimeBuild)' != 'true'
|
| | | AND Exists('$(QtVarsFilePath)')"
|
| | | >$(QtVarsFilePath)</QtVarsImportPath>
|
| | |
|
| | | <!--// Import Qt variables (design-time build) -->
|
| | | <Import
|
| | | Condition="'$(DesignTimeBuild)' == 'true' AND Exists('$(QtVarsDesignTime)')"
|
| | | Project="$(QtVarsDesignTime)"/>
|
| | | <!--// Path to Qt variables .props: design-time build -->
|
| | | <QtVarsImportPath
|
| | | Condition="'$(QtDesignTimeBuild)' == 'true'
|
| | | AND Exists('$(QtVarsDesignTime)')"
|
| | | >$(QtVarsDesignTime)</QtVarsImportPath>
|
| | |
|
| | | <!--// Import Qt variables (fall-back) -->
|
| | | <Import
|
| | | Condition=
|
| | | "'$(DesignTimeBuild)' == 'true' AND !Exists('$(QtVarsDesignTime)') AND Exists('$(QtVarsFilePath)')"
|
| | | Project="$(QtVarsFilePath)"/>
|
| | | <!--// Path to Qt variables .props: fall-back -->
|
| | | <QtVarsImportPath
|
| | | Condition="'$(QtDesignTimeBuild)' == 'true'
|
| | | AND !Exists('$(QtVarsDesignTime)')
|
| | | AND Exists('$(QtVarsFilePath)')"
|
| | | >$(QtVarsFilePath)</QtVarsImportPath>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--// Import Qt vars property file -->
|
| | | <Import Condition="Exists('$(QtVarsImportPath)')" Project="$(QtVarsImportPath)"/>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | |
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Normalize QtVars (incl. backup)
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <QtVars
|
| | | Condition="'$(QtVars)' !=''"
|
| | | >$(QtVars
|
| | | .Replace(' ', '')
|
| | | .Replace('%0a', '')
|
| | | .Replace('%0d', '')
|
| | | .Trim(';'))</QtVars>
|
| | | <QtBkup_QtVars
|
| | | Condition="'$(QtBkup_QtVars)' !=''"
|
| | | >$(QtBkup_QtVars
|
| | | .Replace(' ', '')
|
| | | .Replace('%0a', '')
|
| | | .Replace('%0d', '')
|
| | | .Trim(';'))</QtBkup_QtVars>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Figure out depending on the user settings if we need to link the .natvis file into the PDB
|
| | | // file. Reads the content of qconfig.pri to find Qt's namespace if set. Predefines the path to
|
| | | // the .natvis file used during link which corresponds to the final output generated by the
|
| | | // QtNatvis target.
|
| | | // Evaluation order: first look at the project settings, if empty take from the global settings.
|
| | | // -->
|
| | | <PropertyGroup>
|
| | | <LinkNatvisFile>$(QtLinkNatvisFile)</LinkNatvisFile>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(QtLinkNatvisFile)' == ''">
|
| | | <LinkNatvisRegValue>$([MSBuild]::GetRegistryValue(
|
| | | 'HKEY_CURRENT_USER\SOFTWARE\Digia\Qt5VS2017','LinkNatvis'
|
| | | ))</LinkNatvisRegValue>
|
| | | <LinkNatvisFile>true</LinkNatvisFile>
|
| | | <LinkNatvisFile Condition="'$(LinkNatvisRegValue)' == '0'">false</LinkNatvisFile>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition="'$(Configuration)' == 'Debug'
|
| | | AND '$(LinkNatvisFile)' == 'true' AND '$(QtInstallDir)' != ''">
|
| | | <QConfigPriPath>$([System.IO.Path]::Combine('$(QtInstallDir)',
|
| | | 'mkspecs', 'qconfig.pri'
|
| | | ))</QConfigPriPath>
|
| | | <QConfigPriContent>$([MSBuild]::Unescape(
|
| | | $([System.IO.File]::ReadAllText('$(QConfigPriPath)')
|
| | | .Replace('
', ';')
|
| | | .Replace(' =', '=')
|
| | | .Replace('= ', '='))
|
| | | ))</QConfigPriContent>
|
| | | <QtNamespace>$([System.Text.RegularExpressions.Regex]::Match($(QConfigPriContent),
|
| | | 'QT_NAMESPACE=([a-zA-Z0-9]+)').get_Groups().get_Item(1)
|
| | | )</QtNamespace>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Default item metadata
|
| | | // -->
|
| | | <ItemDefinitionGroup>
|
| | |
| | | <PreprocessorDefinitions Condition="'$(QtQMLDebugEnable)' == 'true'"
|
| | | >QT_QML_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
| | | <AdditionalIncludeDirectories Condition="'$(Qt_INCLUDEPATH_)' != ''"
|
| | | >$(Qt_INCLUDEPATH_);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
| | | >%(AdditionalIncludeDirectories);$(Qt_INCLUDEPATH_)</AdditionalIncludeDirectories>
|
| | | <LanguageStandard Condition="'$(Qt_STDCPP_)' != ''"
|
| | | >$(Qt_STDCPP_)</LanguageStandard>
|
| | | <AdditionalOptions Condition="'$(Qt_CL_OPTIONS_)' != ''"
|
| | | >$(Qt_CL_OPTIONS_) %(AdditionalOptions)</AdditionalOptions>
|
| | | <RuntimeLibrary Condition="'$(Qt_RUNTIME_)' != ''"
|
| | | >$(Qt_RUNTIME_)</RuntimeLibrary>
|
| | | </ClCompile>
|
| | |
|
| | | <!--// Linker (.obj files) -->
|
| | | <Link>
|
| | | <AdditionalDependencies Condition="'$(Qt_LIBS_)' != ''"
|
| | | >$(Qt_LIBS_);%(AdditionalDependencies)</AdditionalDependencies>
|
| | | >%(AdditionalDependencies);$(Qt_LIBS_)</AdditionalDependencies>
|
| | | <AdditionalLibraryDirectories Condition="'$(Qt_LIBPATH_)' != ''"
|
| | | >$(Qt_LIBPATH_);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
| | | >%(AdditionalLibraryDirectories);$(Qt_LIBPATH_)</AdditionalLibraryDirectories>
|
| | | <SharedLibrarySearchPath Condition="'$(Qt_LIBPATH_)' != ''"
|
| | | >$(Qt_LIBPATH_);%(SharedLibrarySearchPath)</SharedLibrarySearchPath>
|
| | | >%(SharedLibrarySearchPath);$(Qt_LIBPATH_)</SharedLibrarySearchPath>
|
| | | <AdditionalOptions Condition="'$(Qt_LINK_OPTIONS_)' != ''"
|
| | | >$(Qt_LINK_OPTIONS_) %(AdditionalOptions)</AdditionalOptions>
|
| | | <AdditionalOptions Condition="'$(Configuration)' == 'Debug' AND '$(LinkNatvisFile)' == 'true'"
|
| | | >/NATVIS:"$(IntDir)\qt.natvis" %(AdditionalOptions)</AdditionalOptions>
|
| | | </Link>
|
| | |
|
| | | </ItemDefinitionGroup>
|
| | |
|
| | | <!--
|
| | |
| | | <Category Name="QtSettings_02_Paths" DisplayName="Paths"/>
|
| | | <Category Name="QtSettings_03_QMake" DisplayName="qmake"/>
|
| | | <Category Name="QtSettings_04_QML" DisplayName="QML"/>
|
| | | <Category Name="QtSettings_05_AdditionalOptions" DisplayName="Qt Additional Compiler Options"/>
|
| | | <Category Name="QtSettings_06_AdditionalLinkOptions" DisplayName="Qt Additional Linker Options"/>
|
| | | </Rule.Categories>
|
| | | <EnumProperty
|
| | | Name="Keyword"
|
| | |
| | | <ValueEditor EditorType="QtModulesEditor" DisplayName="<Select Modules...>" />
|
| | | </StringListProperty.ValueEditors>
|
| | | </StringListProperty>
|
| | | <BoolProperty
|
| | | Name="QtPlugin"
|
| | | Category="QtSettings_01_General"
|
| | | DisplayName="Qt Plugin"
|
| | | Description="Select whether this project is used to generate a Qt plugin.">
|
| | | </BoolProperty>
|
| | | <EnumProperty
|
| | | Name="QtBuildConfig"
|
| | | Category="QtSettings_01_General"
|
| | |
| | | Category="QtSettings_01_General"
|
| | | DisplayName="Run Deployment Tool"
|
| | | Description="Select whether Qt for Windows Deployment Tool (windeployqt) should be called after build."/>
|
| | | <EnumProperty
|
| | | Name="QtToolsDesignTime"
|
| | | Category="QtSettings_01_General"
|
| | | DisplayName="Design Time Build"
|
| | | Description="Run Qt tools during IntelliSense builds.">
|
| | | <EnumValue Name="true" DisplayName="Run Qt Tools"/>
|
| | | <EnumValue Name="false" DisplayName="Skip Qt Tools"/>
|
| | | </EnumProperty>
|
| | | <StringProperty
|
| | | Name="QtPathBinaries"
|
| | | Category="QtSettings_02_Paths"
|
| | |
| | | DisplayName="Enable QML Debugging"
|
| | | Description="Select whether to launch a QML session when debugging.">
|
| | | </BoolProperty>
|
| | | </Rule>
|
| | | <StringProperty
|
| | | Name="Qt_CL_OPTIONS_"
|
| | | ReadOnly="true"
|
| | | Category="QtSettings_05_AdditionalOptions"
|
| | | DisplayName="Additional Options"
|
| | | Description="
|
| | | Additional compiler options required by Qt. These options will be passed
|
| | | to the compiler, unless specifically excluded in the next field." />
|
| | | <StringProperty
|
| | | Name="QtExcludedOptions"
|
| | | Category="QtSettings_05_AdditionalOptions"
|
| | | DisplayName="Excluded Options"
|
| | | Description="
|
| | | Options to exclude from the above compiler options required by Qt.
|
| | | These options will NOT be passed to the compiler. Prefix options
|
| | | with '/' or '-', and separate them with spaces." />
|
| | | <BoolProperty
|
| | | Name="QtOptionsBuildLog"
|
| | | Category="QtSettings_05_AdditionalOptions"
|
| | | DisplayName="Show in Build Log"
|
| | | Description="
|
| | | Print to the build log the list of additional options passed to the compiler." />
|
| | | <EnumProperty
|
| | | Name="QtLinkNatvisFile"
|
| | | Category="QtSettings_06_AdditionalLinkOptions"
|
| | | DisplayName="Embed .natvis file into PDB"
|
| | | Description=
|
| | | "Embeds the debugger visualizations (.natvis file) into the PDB file
|
| | | generated by LINK. While setting this option, the embedded Natvis file
|
| | | will take precedence over user-specific Natvis files (for example the
|
| | | files located in %USERPROFILE%\\Documents\\Visual Studio 2022\\Visualizers).">
|
| | | <EnumValue Name="false" DisplayName="No" />
|
| | | <EnumValue Name="true" DisplayName="Yes" />
|
| | | </EnumProperty>
|
| | | </Rule>
|
| | |
| | | <ItemGroup>
|
| | | <QMakeArgsList Condition="'$(QMakeOptionEarly)' == 'true'" Include="-early"/>
|
| | | <QMakeArgsList Include="CONFIG -= debug release debug_and_release"/>
|
| | | <QMakeArgsList Include="CONFIG += $(QtBuildConfig)"/>
|
| | | <QMakeArgsList Include="CONFIG += $(QtBuildConfig) warn_off"/>
|
| | | <QMakeArgsList Condition="'$(QtPlugin)' == 'true'" Include="CONFIG += plugin"/>
|
| | | <QMakeArgsList Include="$(QMakeExtraArgs)"/>
|
| | | </ItemGroup>
|
| | | <ItemGroup>
|
| | |
| | | $(QtVarsProFileInput)
|
| | | DEFINES -= UNICODE _UNICODE
|
| | | </QtVarsProFileInput>
|
| | | <!--
|
| | | # Add dummy QML object if needed -->
|
| | | <QtVarsProFileInput Condition="$(QtModules.Contains('quick'))">
|
| | | $(QtVarsProFileInput)
|
| | | RESOURCES += qml.qrc
|
| | | </QtVarsProFileInput>
|
| | | </PropertyGroup>
|
| | |
|
| | | <!--// Write dummy QML and QRC files -->
|
| | | <WriteLinesToFile
|
| | | Condition="$(QtModules.Contains('quick'))"
|
| | | File="$(QtVarsWorkDir)\main.qml"
|
| | | Lines="
|
| | | import QtQuick
|
| | | DummyQmlObject { }
|
| | | "/>
|
| | | <WriteLinesToFile
|
| | | Condition="$(QtModules.Contains('quick'))"
|
| | | File="$(QtVarsWorkDir)\qml.qrc"
|
| | | Lines="
|
| | | <RCC>
|
| | | <qresource prefix="/">
|
| | | <file>main.qml</file>
|
| | | </qresource>
|
| | | </RCC>
|
| | | "/>
|
| | |
|
| | | <!--// Write .pro file to temp path -->
|
| | | <WriteLinesToFile
|
| | |
| | | <Cmd><![CDATA["$(QtToolsPath)/qmake" $(QMakeArgs) qtvars.pro]]></Cmd>
|
| | | </PropertyGroup>
|
| | | <HostExec
|
| | | Condition="'$(ApplicationType)' == 'Linux'"
|
| | | Command="$(Cmd)" RedirectStdOut="qtvars.log" RedirectStdErr="STDOUT"
|
| | | WorkingDirectory="@(WorkDir->'%(HostPath)')"
|
| | | Inputs="@(QMakeProj)"
|
| | |
| | | IgnoreExitCode="true">
|
| | | <Output TaskParameter="ExitCode" PropertyName="ErrorLevel"/>
|
| | | </HostExec>
|
| | |
|
| | | <!--// Run qmake in Windows: set %CD% to subfolder of %TEMP% -->
|
| | | <PropertyGroup
|
| | | Condition="'$(ApplicationType)' != 'Linux'">
|
| | | <QMakeTempDir>$(Temp)\$([System.IO.Path]::GetRandomFileName())</QMakeTempDir>
|
| | | </PropertyGroup>
|
| | | <MakeDir
|
| | | Condition="'$(ApplicationType)' != 'Linux'"
|
| | | Directories="$(QMakeTempDir)" />
|
| | | <Copy
|
| | | Condition="'$(ApplicationType)' != 'Linux'"
|
| | | SourceFiles="$(QtVarsWorkDir)\qtvars.pro"
|
| | | DestinationFolder="$(QMakeTempDir)" />
|
| | | <Copy
|
| | | Condition="'$(ApplicationType)' != 'Linux' AND Exists('$(QtVarsWorkDir)\main.qml')"
|
| | | SourceFiles="$(QtVarsWorkDir)\main.qml"
|
| | | DestinationFolder="$(QMakeTempDir)" />
|
| | | <Copy
|
| | | Condition="'$(ApplicationType)' != 'Linux' AND Exists('$(QtVarsWorkDir)\qml.qrc')"
|
| | | SourceFiles="$(QtVarsWorkDir)\qml.qrc"
|
| | | DestinationFolder="$(QMakeTempDir)" />
|
| | | <HostExec
|
| | | Condition="'$(ApplicationType)' != 'Linux'"
|
| | | Command="$(Cmd)" RedirectStdOut="qtvars.log" RedirectStdErr="STDOUT"
|
| | | WorkingDirectory="$(QMakeTempDir)"
|
| | | IgnoreExitCode="true">
|
| | | <Output TaskParameter="ExitCode" PropertyName="ErrorLevel"/>
|
| | | </HostExec>
|
| | | <ItemGroup>
|
| | | <QMakeGeneratedFiles Include="$(QMakeTempDir)\*" />
|
| | | </ItemGroup>
|
| | | <Copy
|
| | | Condition="'$(ApplicationType)' != 'Linux'"
|
| | | SkipUnchangedFiles="true"
|
| | | SourceFiles="@(QMakeGeneratedFiles)"
|
| | | DestinationFolder="$(QtVarsWorkDir)" />
|
| | | <RemoveDir
|
| | | Condition="'$(ApplicationType)' != 'Linux'"
|
| | | Directories="$(QMakeTempDir)" />
|
| | |
|
| | | <!--// Check qmake result -->
|
| | | <PropertyGroup
|
| | |
| | | <!--// In design-time, copy generated .props to randomly named file -->
|
| | | <PropertyGroup>
|
| | | <QtVarsDesignTimeNew
|
| | | Condition="'$(ErrorLevel)' == '0' AND '$(QtVSToolsBuild)' == 'true'"
|
| | | Condition="'$(ErrorLevel)' == '0' AND '$(QtDesignTimeBuild)' == 'true'"
|
| | | >$([System.IO.Path]::Combine('$(TEMP)','$([System.IO.Path]::GetRandomFileName()).designtime.props'))
|
| | | </QtVarsDesignTimeNew>
|
| | | </PropertyGroup>
|
| | | <Copy
|
| | | Condition="'$(ErrorLevel)' == '0' AND '$(QtVSToolsBuild)' == 'true'"
|
| | | Condition="'$(ErrorLevel)' == '0' AND '$(QtDesignTimeBuild)' == 'true'"
|
| | | SourceFiles="$(QtVarsFilePath)" DestinationFiles="$(QtVarsDesignTimeNew)"/>
|
| | | <WriteLinesToFile
|
| | | Condition="'$(ErrorLevel)' == '0' AND '$(QtVSToolsBuild)' == 'true'"
|
| | | Condition="'$(ErrorLevel)' == '0' AND '$(QtDesignTimeBuild)' == 'true'"
|
| | | File="$(QtVarsIndexPathDesignTime)" Overwrite="true" Lines="$(QtVarsDesignTimeNew)"/>
|
| | |
|
| | | <!--// Clean-up -->
|
| | |
| | | <QtTranslation>
|
| | | <InputFiles
|
| | | >$(QtTranslationInput)</InputFiles>
|
| | | <LUpdate
|
| | | <LUpdate Condition="'$(ApplicationType)' == 'Linux'"
|
| | | >$(QtToolsPath)/lupdate</LUpdate>
|
| | | <LRelease
|
| | | <LRelease Condition="'$(ApplicationType)' == 'Linux'"
|
| | | >$(QtToolsPath)/lrelease</LRelease>
|
| | | <LUpdate Condition="'$(ApplicationType)' != 'Linux'"
|
| | | >$(QtToolsPath)/lupdate.exe</LUpdate>
|
| | | <LRelease Condition="'$(ApplicationType)' != 'Linux'"
|
| | | >$(QtToolsPath)/lrelease.exe</LRelease>
|
| | | <TsFile
|
| | | >%(Identity)</TsFile>
|
| | | <QmFile
|
| | |
| | | <Cmd>$(Cmd.Trim())</Cmd>
|
| | | </PropertyGroup>
|
| | | <HostExec
|
| | | Condition="Exists(@(Options->'%(CmdExec)', ''))"
|
| | | Message="%(QtTranslationUpdate.UpdateDescription)"
|
| | | Command="$(Cmd)"
|
| | | Inputs="@(Options->'%(InputListFile)');@(Options->'%(InputFiles)')"
|
| | |
| | | RemoteTarget="$(ResolvedRemoteTarget)"
|
| | | RemoteProjectDir="$(_ResolvedRemoteProjectDir)">
|
| | | </HostExec>
|
| | | <Warning
|
| | | Condition="!Exists(@(Options->'%(CmdExec)', ''))"
|
| | | File="%(QtTranslationUpdate.Identity)" Text="'lupdate' not found; skipping" />
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | |
| | | <Cmd>$(Cmd.Trim())</Cmd>
|
| | | </PropertyGroup>
|
| | | <HostExec
|
| | | Condition="Exists(@(Options->'%(CmdExec)', ''))"
|
| | | Message="%(QtTranslationRelease.ReleaseDescription)"
|
| | | Command="$(Cmd)"
|
| | | Inputs="@(Options->'%(InputFile)')"
|
| | |
| | | RemoteTarget="$(ResolvedRemoteTarget)"
|
| | | RemoteProjectDir="$(_ResolvedRemoteProjectDir)">
|
| | | </HostExec>
|
| | | <Warning
|
| | | Condition="!Exists(@(Options->'%(CmdExec)', ''))"
|
| | | File="%(QtTranslationRelease.Identity)" Text="'lrelease' not found; skipping" />
|
| | |
|
| | | <!--
|
| | | ///////////////////////////////////////////////////////////////////////////////////////////////
|
| | |
| | | if (Lock) {
|
| | | // Wait until locked
|
| | | if (!buildLock.WaitOne(1000)) {
|
| | | // Issue waiting warning
|
| | | Log.LogWarning("Qt::BuildLock[{0}]: Waiting...", Name);
|
| | | var t = Stopwatch.StartNew();
|
| | | do {
|
| | | // Check for build errors
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | #region Task TaskName="QtRunTask"
|
| | |
|
| | | #region Reference
|
| | | //System.Runtime
|
| | | #endregion
|
| | |
|
| | | #region Using
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.Linq;
|
| | | using System.Reflection;
|
| | | using Microsoft.Build.Framework;
|
| | | using Microsoft.Build.Utilities;
|
| | | #endregion
|
| | |
|
| | | #region Comment
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | /// TASK QtRunTask
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Execute a task from the specified assembly, taking as input a list of items. Each item
|
| | | // metadata is copied to a task property with the same name. After the task is executed, the
|
| | | // result for each item is then stored in a new metadata for that item. The final output is the
|
| | | // list of modified items.
|
| | | // Parameters /////////////////////////////////////////////////////////////////////////////////
|
| | | // in ITaskItem[] Items........................List of source items.
|
| | | // in String AssemblyPath.................Path to assembly containing the task.
|
| | | // in String TaskName.....................Full name of task, including namespace.
|
| | | // in String TaskInput....................Name of task input property.
|
| | | // in String TaskOutput (optional)........Name of task output property.
|
| | | // If unspecified, task output is ignored.
|
| | | // in String NewMetadata (optional).......Name of new item metadata to store result.
|
| | | // If unspecified, defaults to TaskOutput.
|
| | | // out ITaskItem[] Result.......................Output list of modified items.
|
| | | // If TaskOutput is unspecified, Result will be empty.
|
| | | // Example //////////////////////////////////////////////////////////////////////////////////////
|
| | | // Items = {
|
| | | // ClCompile {
|
| | | // Identity = "main.cpp",
|
| | | // ...
|
| | | // EnforceTypeConversionRules = False,
|
| | | // ...
|
| | | // }
|
| | | // }
|
| | | // AssemblyPath = "$(VCTargetsPath)\Microsoft.Build.CPPTasks.Common.dll"
|
| | | // TaskName = "Microsoft.Build.CPPTasks.CLCommandLine"
|
| | | // TaskInput = "Sources"
|
| | | // TaskOutput = "CommandLines"
|
| | | // NewMetadata = "CommandLine"
|
| | | // Result = {
|
| | | // ClCompile_Modified {
|
| | | // Identity = "main.cpp",
|
| | | // ...
|
| | | // EnforceTypeConversionRules = False,
|
| | | // ...
|
| | | // CommandLine = "... /Zc:rvalueCast- ..."
|
| | | // }
|
| | | // }
|
| | | #endregion
|
| | |
|
| | | namespace QtVsTools.QtMsBuild.Tasks
|
| | | {
|
| | | public static class QtRunTask
|
| | | {
|
| | | public static QtMSBuild.ITaskLoggingHelper Log { get; set; }
|
| | | public static IBuildEngine BuildEngine { get; set; }
|
| | | public static ITaskHost HostObject { get; set; }
|
| | |
|
| | | public static bool Execute(
|
| | | #region Parameters
|
| | | Microsoft.Build.Framework.ITaskItem[] Items,
|
| | | System.String AssemblyPath,
|
| | | System.String TaskName,
|
| | | System.String TaskInput,
|
| | | out Microsoft.Build.Framework.ITaskItem[] Result,
|
| | | System.String TaskOutput = null,
|
| | | System.String NewMetadata = null)
|
| | | #endregion
|
| | | {
|
| | | #region Code
|
| | | var reserved = new HashSet<string>
|
| | | {
|
| | | "AccessedTime", "CreatedTime", "DefiningProjectDirectory",
|
| | | "DefiningProjectExtension", "DefiningProjectFullPath", "DefiningProjectName",
|
| | | "Directory", "Extension", "Filename", "FullPath", "Identity", "ModifiedTime",
|
| | | "RecursiveDir", "RelativeDir", "RootDir",
|
| | | };
|
| | |
|
| | | // Output default values
|
| | | Result = null;
|
| | |
|
| | | // Load specified assembly
|
| | | var taskAssembly = Assembly.LoadFile(AssemblyPath);
|
| | | if (taskAssembly == null)
|
| | | throw new ArgumentException("AssemblyPath");
|
| | |
|
| | | // Access task type
|
| | | var taskType = taskAssembly.GetType(TaskName);
|
| | | if (taskType == null)
|
| | | throw new ArgumentException("TaskName");
|
| | |
|
| | | // Task type has the following requirements:
|
| | | // * Must be a descendant of the ToolTask type
|
| | | // * Cannot be an abstract class
|
| | | // * Cannot have generic type arguments
|
| | | // * Must have a public default constructor
|
| | | if (!typeof(ToolTask).IsAssignableFrom(taskType))
|
| | | throw new NotSupportedException("Not a ToolTask derived type");
|
| | | if (taskType.IsAbstract)
|
| | | throw new NotSupportedException("Abstract class");
|
| | | if (taskType.ContainsGenericParameters)
|
| | | throw new NotSupportedException("Generic class");
|
| | | var ctorInfo = ((TypeInfo)taskType).DeclaredConstructors
|
| | | .Where(x => x.GetParameters().Length == 0)
|
| | | .FirstOrDefault();
|
| | | if (ctorInfo == null)
|
| | | throw new NotSupportedException("No default constructor");
|
| | |
|
| | | // Access input property of task type
|
| | | var inputProperty = taskType.GetProperty(TaskInput);
|
| | | if (inputProperty == null)
|
| | | throw new ArgumentException("TaskInput");
|
| | | if (inputProperty.PropertyType != typeof(ITaskItem)
|
| | | && inputProperty.PropertyType != typeof(ITaskItem[])) {
|
| | | throw new NotSupportedException("Input property type is not supported");
|
| | | }
|
| | |
|
| | | // If output was specified, access corresponding property of task type
|
| | | PropertyInfo outputProperty = null;
|
| | | if (TaskOutput != null) {
|
| | | outputProperty = taskType.GetProperty(TaskOutput);
|
| | | if (outputProperty == null)
|
| | | throw new ArgumentException("TaskOutput");
|
| | | if (outputProperty.PropertyType != typeof(string)
|
| | | && outputProperty.PropertyType != typeof(string[])
|
| | | && outputProperty.PropertyType != typeof(ITaskItem[])) {
|
| | | throw new NotSupportedException("Output property type is not supported");
|
| | | }
|
| | | if (NewMetadata == null)
|
| | | NewMetadata = TaskOutput;
|
| | | }
|
| | |
|
| | | var resultItems = new List<ITaskItem>();
|
| | | foreach (var item in Items) {
|
| | | // For each source item ...
|
| | |
|
| | | // Instantiate task
|
| | | var task = ctorInfo.Invoke(new object[0]) as ToolTask;
|
| | | task.BuildEngine = BuildEngine;
|
| | | task.HostObject = HostObject;
|
| | |
|
| | | // Set task input property to the source item
|
| | | var inputPropertyType = inputProperty.PropertyType;
|
| | | if (inputPropertyType == typeof(ITaskItem)) {
|
| | | inputProperty.SetValue(task, item);
|
| | | } else if (inputPropertyType == typeof(ITaskItem[])) {
|
| | | inputProperty.SetValue(task, new ITaskItem[] { item });
|
| | | }
|
| | |
|
| | | var names = item.MetadataNames.Cast<string>()
|
| | | .Where(x => !reserved.Contains(x));
|
| | | foreach (var name in names) {
|
| | | // For each metadata in the source item ...
|
| | |
|
| | | // Try to obtain a task property with the same name
|
| | | var taskProperty = taskType.GetProperty(name);
|
| | | if (taskProperty != null) {
|
| | | // If the property exists, set it to the metadata value
|
| | | string metadataValue = item.GetMetadata(name);
|
| | | var propertyType = taskProperty.PropertyType;
|
| | | if (propertyType == typeof(bool)) {
|
| | | taskProperty.SetValue(task, metadataValue.Equals("true",
|
| | | StringComparison.InvariantCultureIgnoreCase));
|
| | | } else if (propertyType == typeof(string)) {
|
| | | taskProperty.SetValue(task, metadataValue);
|
| | | } else if (propertyType == typeof(string[])) {
|
| | | taskProperty.SetValue(task, metadataValue.Split(';'));
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | // Run task
|
| | | if (!task.Execute())
|
| | | throw new Exception(string.Format("Task failed ({0})", item.ItemSpec));
|
| | |
|
| | | // Record task output
|
| | | if (TaskOutput != null) {
|
| | | // Create output item as copy of source item
|
| | | var resultItem = new TaskItem(item);
|
| | |
|
| | | // Set new metadata and add output item to the result list
|
| | | string outputValue;
|
| | | object propertyValue = outputProperty.GetValue(task);
|
| | | if (propertyValue == null)
|
| | | outputValue = string.Empty;
|
| | | else if (outputProperty.PropertyType == typeof(string))
|
| | | outputValue = propertyValue as string;
|
| | | else if (outputProperty.PropertyType == typeof(string[]))
|
| | | outputValue = (propertyValue as string[]).FirstOrDefault();
|
| | | else if (outputProperty.PropertyType == typeof(ITaskItem[]))
|
| | | outputValue = (propertyValue as ITaskItem[]).FirstOrDefault().ItemSpec;
|
| | | else
|
| | | outputValue = string.Empty;
|
| | | if (NewMetadata != null)
|
| | | resultItem.SetMetadata(NewMetadata, outputValue);
|
| | | resultItems.Add(resultItem);
|
| | | }
|
| | | }
|
| | |
|
| | | // Return the list of output items
|
| | | Result = resultItems.ToArray();
|
| | |
|
| | | #endregion
|
| | |
|
| | | return true;
|
| | | }
|
| | | }
|
| | | }
|
| | | #endregion
|
| | |
| | | /// <summary>
|
| | | /// Name of reusable macro
|
| | | /// </summary>
|
| | | public string Name { get; private set; }
|
| | | private string Name { get; set; }
|
| | |
|
| | | /// <summary>
|
| | | /// True if macro compilation was successful
|
| | |
| | | /// </summary>
|
| | | public bool QuitWhenDone { get; private set; }
|
| | |
|
| | | AsyncPackage Package { get; set; }
|
| | | EnvDTE80.DTE2 Dte { get; set; }
|
| | | AsyncPackage Package { get; }
|
| | | EnvDTE80.DTE2 Dte { get; }
|
| | | IntPtr MainWindowHWnd { get; }
|
| | |
|
| | | AutomationElement UiRoot => AutomationElement.RootElement;
|
| | |
|
| | |
| | | get
|
| | | {
|
| | | if (_UiVsRoot == null)
|
| | | #if VS2022
|
| | | _UiVsRoot = AutomationElement.FromHandle(Dte.MainWindow.HWnd);
|
| | | #else
|
| | | _UiVsRoot = AutomationElement.FromHandle(new IntPtr(Dte.MainWindow.HWnd));
|
| | | #endif
|
| | | _UiVsRoot = AutomationElement.FromHandle(MainWindowHWnd);
|
| | | return _UiVsRoot;
|
| | | }
|
| | | }
|
| | |
|
| | | JoinableTaskFactory JoinableTaskFactory { get; set; }
|
| | | CancellationToken ServerLoop { get; set; }
|
| | | JoinableTaskFactory JoinableTaskFactory { get; }
|
| | | CancellationToken ServerLoop { get; }
|
| | |
|
| | | string Message { get; set; }
|
| | |
|
| | | static MacroParser Parser { get; set; }
|
| | | MacroLines MacroLines { get; set; }
|
| | |
|
| | | List<string> SelectedAssemblies { get { return _SelectedAssemblies; } }
|
| | | List<string> _SelectedAssemblies =
|
| | | new List<string>
|
| | | {
|
| | | "QtVsTest",
|
| | | "System.Core",
|
| | | };
|
| | | private List<string> SelectedAssemblies { get; } = new List<string>
|
| | | {
|
| | | typeof(Macro).Assembly.FullName,
|
| | | typeof(EnvDTE.DTE).Assembly.FullName,
|
| | | typeof(AutomationElement).Assembly.FullName,
|
| | | "System.Core",
|
| | | };
|
| | |
|
| | | IEnumerable<string> RefAssemblies { get; set; }
|
| | |
|
| | | List<string> Namespaces { get { return _Namespaces; } }
|
| | | List<string> _Namespaces =
|
| | | new List<string>
|
| | | {
|
| | | "System",
|
| | | "System.Linq",
|
| | | "System.Reflection",
|
| | | "Task = System.Threading.Tasks.Task",
|
| | | "System.Windows.Automation",
|
| | | "EnvDTE",
|
| | | "EnvDTE80",
|
| | | };
|
| | | private List<string> Namespaces { get; } = new List<string>
|
| | | {
|
| | | "System",
|
| | | "System.Linq",
|
| | | "System.Reflection",
|
| | | "Task = System.Threading.Tasks.Task",
|
| | | "System.Windows.Automation",
|
| | | "EnvDTE",
|
| | | "EnvDTE80",
|
| | | };
|
| | |
|
| | | Dictionary<string, VSServiceRef> ServiceRefs { get { return _ServiceRefs; } }
|
| | | Dictionary<string, VSServiceRef> _ServiceRefs =
|
| | | new Dictionary<string, VSServiceRef>
|
| | | private Dictionary<string, VSServiceRef> ServiceRefs { get; } = new Dictionary<string, VSServiceRef>
|
| | | {
|
| | | {
|
| | | {
|
| | | "Dte", new VSServiceRef
|
| | | "Dte", new VSServiceRef
|
| | | { Name = "Dte", Interface = "DTE2", Type = "DTE" }
|
| | | },
|
| | | };
|
| | | },
|
| | | };
|
| | |
|
| | | Dictionary<string, GlobalVar> GlobalVars { get { return _GlobalVars; } }
|
| | | Dictionary<string, GlobalVar> _GlobalVars =
|
| | | new Dictionary<string, GlobalVar>
|
| | | private Dictionary<string, GlobalVar> GlobalVars { get; } = new Dictionary<string, GlobalVar>
|
| | | {
|
| | | {
|
| | | {
|
| | | "Result", new GlobalVar
|
| | | "Result", new GlobalVar
|
| | | { Type = "string", Name = "Result", InitialValueExpr = "string.Empty" }
|
| | | },
|
| | | };
|
| | | },
|
| | | };
|
| | |
|
| | | string CSharpMethodCode { get; set; }
|
| | | string CSharpClassCode { get; set; }
|
| | |
| | | const BindingFlags PUBLIC_STATIC = BindingFlags.Public | BindingFlags.Static;
|
| | | const StringComparison IGNORE_CASE = StringComparison.InvariantCultureIgnoreCase;
|
| | |
|
| | | static ConcurrentDictionary<string, Macro> Macros
|
| | | static readonly ConcurrentDictionary<string, Macro> Macros
|
| | | = new ConcurrentDictionary<string, Macro>();
|
| | |
|
| | | static ConcurrentDictionary<string, object> Globals
|
| | | static readonly ConcurrentDictionary<string, object> Globals
|
| | | = new ConcurrentDictionary<string, object>();
|
| | |
|
| | | /// <summary>
|
| | |
| | | public Macro(
|
| | | AsyncPackage package,
|
| | | EnvDTE80.DTE2 dte,
|
| | | IntPtr mainWindowHWnd,
|
| | | JoinableTaskFactory joinableTaskFactory,
|
| | | CancellationToken serverLoop)
|
| | | {
|
| | |
| | | JoinableTaskFactory = joinableTaskFactory;
|
| | | ServerLoop = serverLoop;
|
| | | Dte = dte;
|
| | | MainWindowHWnd = mainWindowHWnd;
|
| | | ErrorMsg("Uninitialized");
|
| | | }
|
| | |
|
| | |
| | | return false;
|
| | | break;
|
| | | }
|
| | |
|
| | | csharp.AppendLine();
|
| | | return true;
|
| | | }
|
| | |
|
| | |
| | |
|
| | | csharp.AppendFormat(@"
|
| | | await WaitExpr({0}, () => UiContext = {1});", timeout, context);
|
| | |
|
| | | } else if (s.Args[0].Equals("find", IGNORE_CASE)) {
|
| | | //# ui find [all] [_var_name_] [_timeout_] => <_scope_>, <_condition_>
|
| | |
|
| | | var args = new Queue<string>(s.Args.Skip(1));
|
| | |
|
| | | bool findAll = false;
|
| | | if (args.Any() && args.Peek().Equals("all", IGNORE_CASE)) {
|
| | | findAll = true;
|
| | | args.Dequeue();
|
| | | }
|
| | | string funcName = findAll ? "FindAll" : "FindFirst";
|
| | | string varType = findAll ? "AutomationElementCollection" : "AutomationElement";
|
| | |
|
| | | string varName = null;
|
| | | if (args.Any() && !char.IsDigit(args.Peek()[0]))
|
| | | varName = args.Dequeue();
|
| | | if (findAll && string.IsNullOrEmpty(varName))
|
| | | return ErrorMsg("Invalid #ui statement");
|
| | |
|
| | | int timeout = 3000;
|
| | | if (args.Any() && char.IsDigit(args.Peek()[0]))
|
| | | timeout = int.Parse(args.Dequeue());
|
| | |
|
| | | if (varName == null) {
|
| | | varName = "UiContext";
|
| | | } else {
|
| | | csharp.Append($@"
|
| | | {varType} {varName} = null;");
|
| | | }
|
| | | csharp.Append($@"
|
| | | await WaitExpr({timeout}, () => {varName} = UiContext.{funcName}({s.Code}));");
|
| | |
|
| | | } else if (s.Args[0].Equals("pattern", IGNORE_CASE)) {
|
| | | //# ui pattern <_TypeName_> <_VarName_> [ => _string_ [, _string_, ... ] ]
|
| | |
| | | File.Delete(macroDllPath);
|
| | | return ErrorMsg(string.Join("\r\n",
|
| | | CompilerResults.Errors.Cast<CompilerError>()
|
| | | .Select(x => x.ErrorText)));
|
| | | .Select(x => $"{x.Line}: {x.ErrorText}")
|
| | | .Append(CSharpClassCode)
|
| | | .Union(RefAssemblies)));
|
| | | }
|
| | |
|
| | | MacroAssembly = AppDomain.CurrentDomain.Load(File.ReadAllBytes(macroDllPath));
|
| | |
| | | foreach (var globalVar in GlobalVars.Values) {
|
| | | string varName = globalVar.Name;
|
| | | Type varType = globalVar.FieldInfo.FieldType;
|
| | | object value;
|
| | | if (Globals.TryGetValue(varName, out value)) {
|
| | | if (Globals.TryGetValue(varName, out object value)) {
|
| | | Type valueType = value.GetType();
|
| | | if (!varType.IsAssignableFrom(valueType)) {
|
| | | throw new InvalidCastException(string.Format(
|
| | |
| | |
|
| | | static Macro GetMacro(string name)
|
| | | {
|
| | | Macro macro;
|
| | | if (!Macros.TryGetValue(name, out macro))
|
| | | if (!Macros.TryGetValue(name, out Macro macro))
|
| | | return null;
|
| | | return macro;
|
| | | }
|
| | |
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Collections;
|
| | | using System.Collections.Generic;
|
| | | using System.Linq;
|
| | | using QtVsTools.SyntaxAnalysis;
|
| | |
|
| | | namespace QtVsTest.Macros
|
| | | {
|
| | | using System.Collections;
|
| | | using static QtVsTools.SyntaxAnalysis.RegExpr;
|
| | | using static RegExpr;
|
| | |
|
| | | class MacroLines : IEnumerable<MacroLine>
|
| | | {
|
| | | List<MacroLine> Lines = new List<MacroLine>();
|
| | | readonly List<MacroLine> Lines = new List<MacroLine>();
|
| | |
|
| | | public void Add(MacroLine line) { Lines.Add(line); }
|
| | |
|
| | |
| | |
|
| | | public class CodeLine : MacroLine
|
| | | {
|
| | | public string Code;
|
| | | public readonly string Code;
|
| | | public CodeLine(string code)
|
| | | {
|
| | | Code = code;
|
| | |
| | | /// </summary>
|
| | | class MacroServer
|
| | | {
|
| | | public CancellationTokenSource Loop { get; private set; }
|
| | | public CancellationTokenSource Loop { get; }
|
| | |
|
| | | AsyncPackage Package { get; set; }
|
| | | JoinableTaskFactory JoinableTaskFactory { get; set; }
|
| | | AsyncPackage Package { get; }
|
| | | JoinableTaskFactory JoinableTaskFactory { get; }
|
| | |
|
| | | /// <summary>
|
| | | /// Macro server constructor
|
| | |
| | | {
|
| | | await JoinableTaskFactory.SwitchToMainThreadAsync(Loop.Token);
|
| | | var DTE = await Package.GetServiceAsync(typeof(DTE)) as DTE2;
|
| | | var mainWindowHWnd = new IntPtr((long)DTE.MainWindow.HWnd);
|
| | | await TaskScheduler.Default;
|
| | |
|
| | | var pipeName = string.Format("QtVSTest_{0}", Process.GetCurrentProcess().Id);
|
| | |
| | | if (Loop.Token.IsCancellationRequested)
|
| | | break;
|
| | |
|
| | | var macro = new Macro(Package, DTE, JoinableTaskFactory, Loop.Token);
|
| | | var macro = new Macro(
|
| | | Package, DTE, mainWindowHWnd, JoinableTaskFactory, Loop.Token);
|
| | | await macro.CompileAsync(Encoding.UTF8.GetString(data));
|
| | | if (macro.AutoRun)
|
| | | await macro.RunAsync();
|
| | |
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.IO;
|
| | | using System.Runtime.InteropServices;
|
| | | using System.Threading;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | |
| | | namespace QtVsTest
|
| | | {
|
| | | using Macros;
|
| | | using System.IO;
|
| | |
|
| | | [Guid(PackageGuidString)]
|
| | | [InstalledProductRegistration(
|
| | |
| | | public sealed class QtVsTest : AsyncPackage
|
| | | {
|
| | | public const string PackageGuidString = "0e258dce-fc8a-49a2-81c5-c9e138bfe500";
|
| | | MacroServer MacroServer { get; set; }
|
| | | MacroServer MacroServer { get; }
|
| | |
|
| | | public QtVsTest()
|
| | | {
|
| | |
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2021 The Qt Company Ltd.
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | |
| | | <DefineConstants>DEBUG;TRACE</DefineConstants>
|
| | | <ErrorReport>prompt</ErrorReport>
|
| | | <WarningLevel>4</WarningLevel>
|
| | | <PlatformTarget Condition="'$(VisualStudioVersion)' == '17.0'">x64</PlatformTarget>
|
| | | <PlatformTarget Condition="'$(VisualStudioVersion)' != '17.0'">x86</PlatformTarget>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
| | | <DebugType>pdbonly</DebugType>
|
| | |
| | | <Reference Include="System" />
|
| | | <Reference Include="System.Design" />
|
| | | <Reference Include="System.Drawing" />
|
| | | <Reference Include="Microsoft.VisualStudio.ProjectSystem">
|
| | | <HintPath>$(VsInstallRoot)\Common7\IDE\CommonExtensions\Microsoft\Project\Microsoft.VisualStudio.ProjectSystem.dll</HintPath>
|
| | | </Reference>
|
| | | <Reference Include="Microsoft.VisualStudio.Composition">
|
| | | <HintPath>$(VsInstallRoot)\Common7\IDE\PrivateAssemblies\Microsoft.VisualStudio.Composition.dll</HintPath>
|
| | | </Reference>
|
| | | </ItemGroup>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Version specific references
|
| | | // General package references
|
| | | // -->
|
| | | <Import Project="$(SolutionDir)\references.props" />
|
| | | <ItemGroup>
|
| | | <PackageReference Include="System.ComponentModel.Composition"
|
| | | Version="$(Version_System_ComponentModel_Composition)" />
|
| | | <PackageReference Include="Stub.System.Data.SQLite.Core.NetFramework"
|
| | | Version="$(Version_Stub_System_Data_SQLite_Core_NetFramework)" />
|
| | | <PackageReference Include="Newtonsoft.Json"
|
| | | Version="$(Version_Newtonsoft_Json)" />
|
| | | <PackageReference Include="Microsoft.Build"
|
| | | Version="$(Version_Microsoft_Build)" />
|
| | | <PackageReference Include="Microsoft.Build.Framework"
|
| | | Version="$(Version_Microsoft_Build_Framework)" />
|
| | | <PackageReference Include="Microsoft.Build.Tasks.Core"
|
| | | Version="$(Version_Microsoft_Build_Tasks_Core)" />
|
| | | <PackageReference Include="Microsoft.VisualStudio.SDK"
|
| | | Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
|
| | | <PackageReference Include="Microsoft.VSSDK.BuildTools"
|
| | | Version="$(Version_Microsoft_VSSDK_BuildTools)" />
|
| | | <PackageReference Include="Microsoft.VisualStudio.Shell.Framework"
|
| | | Version="$(Version_Microsoft_VisualStudio_Shell_Framework)" />
|
| | | <PackageReference Include="Microsoft.VisualStudio.Validation"
|
| | | Version="$(Version_Microsoft_VisualStudio_Validation)" />
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_Threading)"
|
| | | Version="$(Version_Microsoft_VisualStudio_Threading)" />
|
| | | <PackageReference Include="System.Collections.Immutable"
|
| | | Version="$(Version_System_Collections_Immutable)" />
|
| | | <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_ProjectSystem)" Version="$(Version_Microsoft_VisualStudio_ProjectSystem)" />
|
| | | </ItemGroup>
|
| | | <ItemGroup Condition="'$(VisualStudioVersion)'=='17.0'">
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)"
|
| | | Version="$(Version_Microsoft_VisualStudio_VCProjectEngine)" />
|
| | | </ItemGroup>
|
| | | <ItemGroup Condition="'$(VisualStudioVersion)'=='16.0'">
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)"
|
| | | Version="$(Version_Microsoft_VisualStudio_VCProjectEngine)" />
|
| | | </ItemGroup>
|
| | | <ItemGroup Condition="'$(VisualStudioVersion)'=='15.0'">
|
| | | <Reference Include="Microsoft.VisualStudio.VCProjectEngine" />
|
| | | </ItemGroup>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Version specific package references
|
| | | // -->
|
| | | <Choose>
|
| | | <When Condition="'$(VisualStudioVersion)'=='17.0'">
|
| | | <ItemGroup>
|
| | | </ItemGroup>
|
| | | </When>
|
| | | <When Condition="'$(VisualStudioVersion)'=='16.0'">
|
| | | <ItemGroup>
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
|
| | | </ItemGroup>
|
| | | </When>
|
| | | <When Condition="'$(VisualStudioVersion)'=='15.0'">
|
| | | <ItemGroup>
|
| | | </ItemGroup>
|
| | | </When>
|
| | | </Choose>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Solution project references
|
| | |
| | | </Content>
|
| | | </ItemGroup>
|
| | | <Choose>
|
| | | <When Condition="Exists('$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.22000.0')">
|
| | | <PropertyGroup>
|
| | | <Win10SDKPath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.22000.0</Win10SDKPath>
|
| | | </PropertyGroup>
|
| | | </When>
|
| | | <When Condition="Exists('$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.20348.0')">
|
| | | <PropertyGroup>
|
| | | <Win10SDKPath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.20348.0</Win10SDKPath>
|
| | | </PropertyGroup>
|
| | | </When>
|
| | | <When Condition="Exists('$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.19041.0')">
|
| | | <PropertyGroup>
|
| | | <Win10SDKPath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.19041.0</Win10SDKPath>
|
| | | </PropertyGroup>
|
| | | </When>
|
| | | <When Condition="Exists('$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.18362.0')">
|
| | | <PropertyGroup>
|
| | | <Win10SDKPath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.18362.0</Win10SDKPath>
|
| | | </PropertyGroup>
|
| | | </When>
|
| | | <When Condition="Exists('$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.17763.0')">
|
| | | <PropertyGroup>
|
| | | <Win10SDKPath>$(MSBuildProgramFiles32)\Windows Kits\10\bin\10.0.17763.0</Win10SDKPath>
|
| | |
| | | </When>
|
| | | </Choose>
|
| | | <PropertyGroup Condition="'$(Win10SDKPath)' != ''">
|
| | | <UIAVerifyPath>$(Win10SDKPath)\x86\UIAVerify</UIAVerifyPath>
|
| | | <UIAVerifyPath>$(Win10SDKPath)\$(PlatformTarget)\UIAVerify</UIAVerifyPath>
|
| | | </PropertyGroup>
|
| | | <ItemGroup Condition="'$(UIAVerifyPath)' != ''">
|
| | | <Reference Include="Interop.UIAutomationClient">
|
| | |
| | | <Aliases>global</Aliases>
|
| | | <EmbedInteropTypes>False</EmbedInteropTypes>
|
| | | </Reference>
|
| | | </ItemGroup>
|
| | | <ItemGroup>
|
| | | <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
|
| | | </ItemGroup>
|
| | | <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
| | | <Import Project="$(SolutionDir)\transform.targets" />
|
| | |
| | | {
|
| | | public struct BuildConfig
|
| | | {
|
| | | public const uint Both = 0x03;
|
| | | public const uint Release = 0x01;
|
| | | public const uint Debug = 0x02;
|
| | |
|
| | |
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.Diagnostics;
|
| | | using System.IO;
|
| | | using System.Linq;
|
| | | using System.Text;
|
| | | using System.Text.RegularExpressions;
|
| | | using System.IO;
|
| | |
|
| | | namespace QtVsTools.Core.CommandLine
|
| | | {
|
| | |
| | |
|
| | | public class Parser
|
| | | {
|
| | |
|
| | | List<Option> commandLineOptionList = new List<Option>();
|
| | | Dictionary<string, int> nameHash = new Dictionary<string, int>();
|
| | | Dictionary<int, List<string>> optionValuesHash = new Dictionary<int, List<string>>();
|
| | | List<string> optionNames = new List<string>();
|
| | | List<string> positionalArgumentList = new List<string>();
|
| | | List<string> unknownOptionNames = new List<string>();
|
| | | readonly List<Option> commandLineOptionList = new List<Option>();
|
| | | readonly Dictionary<string, int> nameHash = new Dictionary<string, int>();
|
| | | readonly Dictionary<int, List<string>> optionValuesHash = new Dictionary<int, List<string>>();
|
| | | readonly List<string> optionNames = new List<string>();
|
| | | readonly List<string> positionalArgumentList = new List<string>();
|
| | | readonly List<string> unknownOptionNames = new List<string>();
|
| | | bool needsParsing = true;
|
| | |
|
| | | public enum SingleDashWordOptionMode
|
| | |
| | |
|
| | | IEnumerable<string> Aliases(string optionName)
|
| | | {
|
| | | int optionIndex;
|
| | | if (!nameHash.TryGetValue(optionName, out optionIndex)) {
|
| | | if (!nameHash.TryGetValue(optionName, out int optionIndex)) {
|
| | | return new List<string>();
|
| | | }
|
| | | return commandLineOptionList[optionIndex].Names;
|
| | |
| | | IEnumerator<string> argumentEnumerator, ref bool atEnd)
|
| | | {
|
| | | const char assignChar = '=';
|
| | | int optionOffset;
|
| | | if (nameHash.TryGetValue(optionName, out optionOffset)) {
|
| | | if (nameHash.TryGetValue(optionName, out int optionOffset)) {
|
| | | int assignPos = argument.IndexOf(assignChar);
|
| | | bool withValue = !string.IsNullOrEmpty(
|
| | | commandLineOptionList[optionOffset].ValueName);
|
| | |
| | | var optFilePath = macros.ExpandString(argData.Substring(1));
|
| | | string[] additionalArgs = File.ReadAllLines(
|
| | | Path.Combine(workingDir, optFilePath));
|
| | | if (additionalArgs != null) {
|
| | | if (additionalArgs.Length != 0) {
|
| | | var additionalArgsString = string.Join(" ", additionalArgs
|
| | | .Select(x => "\"" + x.Replace("\"", "\\\"") + "\""));
|
| | | arguments.AddRange(TokenizeArgs(additionalArgsString, macros));
|
| | |
| | | if (!RegisterFoundOption(optionName)) {
|
| | | error = true;
|
| | | } else {
|
| | | int optionOffset;
|
| | | Trace.Assert(nameHash.TryGetValue(
|
| | | optionName,
|
| | | out optionOffset));
|
| | | out int optionOffset));
|
| | | bool withValue = !string.IsNullOrEmpty(
|
| | | commandLineOptionList[optionOffset].ValueName);
|
| | | if (withValue) {
|
| | |
| | | if (argument.Length > 2) {
|
| | | string possibleShortOptionStyleName = argument.Substring(1, 1);
|
| | |
|
| | | int shortOptionIdx;
|
| | | if (nameHash.TryGetValue(
|
| | | possibleShortOptionStyleName,
|
| | | out shortOptionIdx)) {
|
| | | out int shortOptionIdx)) {
|
| | | var arg = commandLineOptionList[shortOptionIdx];
|
| | | if ((arg.Flags & Option.Flag.ShortOptionStyle) != 0) {
|
| | | RegisterFoundOption(possibleShortOptionStyleName);
|
| | |
| | | public IEnumerable<string> Values(string optionName)
|
| | | {
|
| | | CheckParsed("Values");
|
| | | int optionOffset;
|
| | | if (nameHash.TryGetValue(optionName, out optionOffset)) {
|
| | | if (nameHash.TryGetValue(optionName, out int optionOffset)) {
|
| | | var values = optionValuesHash[optionOffset];
|
| | | return values;
|
| | | }
|
| | |
| | | public IEnumerable<string> Names
|
| | | {
|
| | | get;
|
| | | private set;
|
| | | }
|
| | |
|
| | | public string ValueName
|
| | |
| | |
|
| | | static class Lexer
|
| | | {
|
| | | static Regex lexer = new Regex(
|
| | | static readonly Regex lexer = new Regex(
|
| | | /* Newline */ @"(\n)" +
|
| | | /* Unquoted */ @"|((?:(?:[^\s\""])|(?:(?<=\\)\""))+)" +
|
| | | /* Quoted */ @"|(?:\""((?:(?:[^\""])|(?:(?<=\\)\""))+)\"")" +
|
| | |
| | | /// </summary>
|
| | | public static class EnumExt
|
| | | {
|
| | | static LazyFactory StaticLazy { get; } = new LazyFactory();
|
| | |
|
| | | /// <summary>
|
| | | /// Wrapper for enum cast values.
|
| | | /// </summary>
|
| | |
| | | [AttributeUsage(AttributeTargets.All)]
|
| | | public sealed class StringAttribute : Attribute, ICast<string>
|
| | | {
|
| | | public string Value { get; private set; }
|
| | | public string Value { get; }
|
| | | public StringAttribute(string str) { Value = str; }
|
| | | }
|
| | |
|
| | |
| | | /// </summary>
|
| | | public static TEnum Cast<T, TEnum>(this T valueT, TEnum defaultValue) where TEnum : struct
|
| | | {
|
| | | TEnum value;
|
| | | return TryCast(valueT, out value) ? value : defaultValue;
|
| | | return TryCast(valueT, out TEnum value) ? value : defaultValue;
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | |
| | | .FirstOrDefault();
|
| | | }
|
| | |
|
| | | static IEnumerable<Type> _CastAttribTypes;
|
| | | /// <summary>
|
| | | /// List of cast attribute types.
|
| | | /// </summary>
|
| | | /// <remarks>
|
| | | /// Future cast attribute types need to be added to this list.
|
| | | /// </remarks>
|
| | | static IEnumerable<Type> CastAttribTypes => _CastAttribTypes
|
| | | ?? (_CastAttribTypes = new[]
|
| | | static IEnumerable<Type> CastAttribTypes => StaticLazy.Get(() =>
|
| | | CastAttribTypes, () => new[]
|
| | | {
|
| | | typeof(StringAttribute)
|
| | | });
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Collections.Concurrent;
|
| | | using System.Diagnostics;
|
| | | using System.Linq.Expressions;
|
| | | using System.Reflection;
|
| | |
|
| | | namespace QtVsTools.Common
|
| | | {
|
| | | public class LazyFactory
|
| | | {
|
| | | private Lazy<ConcurrentDictionary<PropertyInfo, Lazy<object>>> LazyObjs { get; }
|
| | | private ConcurrentDictionary<PropertyInfo, Lazy<object>> Objs => LazyObjs.Value;
|
| | |
|
| | | public LazyFactory()
|
| | | {
|
| | | LazyObjs = new Lazy<ConcurrentDictionary<PropertyInfo, Lazy<object>>>();
|
| | | }
|
| | |
|
| | | public T Get<T>(Expression<Func<T>> propertyRef, Func<T> initFunc) where T : class
|
| | | {
|
| | | var lazyPropertyExpr = propertyRef?.Body as MemberExpression;
|
| | | var lazyProperty = lazyPropertyExpr?.Member as PropertyInfo;
|
| | | if (lazyProperty == null)
|
| | | throw new ArgumentException("Invalid property reference", "propertyRef");
|
| | | var lazyObj = Objs.GetOrAdd(lazyProperty, (_) => new Lazy<object>(() => initFunc()));
|
| | | return lazyObj.Value as T;
|
| | | }
|
| | | }
|
| | | }
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using Microsoft.Win32;
|
| | | using QtVsTools.Core;
|
| | |
|
| | | namespace QtVsTools.Common
|
| | | {
|
| | | public static class QtVSIPSettingsShared
|
| | | {
|
| | | private static readonly Dictionary<string, string> mocDirCache
|
| | | = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
| | | private static readonly Dictionary<string, string> uicDirCache
|
| | | = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
| | | private static readonly Dictionary<string, string> rccDirCache
|
| | | = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
| | |
|
| | | public static string GetDirectory(EnvDTE.Project project, string type)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | // check for directory in following order:
|
| | | // - stored in project
|
| | | // - stored in cache
|
| | | // - retrieve from moc/uic steps
|
| | | // - fall-back on hard-coded directory
|
| | |
|
| | | var fullName = project?.FullName;
|
| | | if (string.IsNullOrEmpty(fullName))
|
| | | return GetDirectory(type); // - fall-back on hard-coded directory
|
| | |
|
| | | if (project.Globals.get_VariablePersists(type)) // - stored in project
|
| | | return HelperFunctions.NormalizeRelativeFilePath(project.Globals[type] as string);
|
| | |
|
| | | switch (type) { // - stored in cache
|
| | | case Resources.mocDirKeyword:
|
| | | if (mocDirCache.ContainsKey(fullName))
|
| | | return mocDirCache[fullName];
|
| | | break;
|
| | | case Resources.uicDirKeyword:
|
| | | if (uicDirCache.ContainsKey(fullName))
|
| | | return uicDirCache[fullName];
|
| | | break;
|
| | | case Resources.rccDirKeyword:
|
| | | if (rccDirCache.ContainsKey(fullName))
|
| | | return rccDirCache[fullName];
|
| | | break;
|
| | | default:
|
| | | return GetDirectory(type); // - fall-back on hard-coded directory
|
| | | }
|
| | |
|
| | | try {
|
| | | string configName = null;
|
| | | string platformName = null;
|
| | | QtCustomBuildTool tool = null;
|
| | | foreach (VCFile vcfile in (project.Object as VCProject).Files as IVCCollection) {
|
| | | var name = vcfile?.Name;
|
| | | if (string.IsNullOrEmpty(name))
|
| | | continue;
|
| | | if (!(HelperFunctions.IsHeaderFile(name) || HelperFunctions.IsMocFile(name)
|
| | | || HelperFunctions.IsUicFile(name) || HelperFunctions.IsQrcFile(name)))
|
| | | continue;
|
| | |
|
| | | foreach (VCFileConfiguration config in vcfile?.FileConfigurations as IVCCollection) {
|
| | | tool = new QtCustomBuildTool(config);
|
| | | if (tool == null)
|
| | | continue;
|
| | | configName = config.Name.Remove(config.Name.IndexOf('|'));
|
| | | var vcConfig = config.ProjectConfiguration as VCConfiguration;
|
| | | platformName = (vcConfig.Platform as VCPlatform).Name;
|
| | | var cmd = tool.CommandLine;
|
| | | if (cmd.Contains("moc.exe") || cmd.Contains("uic.exe") || cmd.Contains("rcc.exe"))
|
| | | break;
|
| | | tool = null;
|
| | | }
|
| | |
|
| | | if (tool != null)
|
| | | break;
|
| | | }
|
| | |
|
| | | if (tool == null)
|
| | | return GetDirectory(type); // - fall-back on hard-coded directory
|
| | |
|
| | | var dir = ".";
|
| | | var lastindex = tool.Outputs.LastIndexOf('\\');
|
| | | if (tool.Outputs.LastIndexOf('/') > lastindex)
|
| | | lastindex = tool.Outputs.LastIndexOf('/');
|
| | |
|
| | | if (lastindex != -1)
|
| | | dir = tool.Outputs.Substring(0, lastindex);
|
| | | dir = dir.Replace("\"", "");
|
| | |
|
| | | if (type == Resources.mocDirKeyword) {
|
| | | int index = dir.IndexOf(configName, StringComparison.OrdinalIgnoreCase);
|
| | | if (index != -1)
|
| | | dir = dir.Replace(dir.Substring(index, configName.Length), "$(ConfigurationName)");
|
| | |
|
| | | index = dir.IndexOf(platformName, StringComparison.OrdinalIgnoreCase);
|
| | | if (index != -1)
|
| | | dir = dir.Replace(dir.Substring(index, platformName.Length), "$(PlatformName)");
|
| | | dir = HelperFunctions.NormalizeRelativeFilePath(dir);
|
| | |
|
| | | mocDirCache.Add(fullName, dir);
|
| | | } else if (type == Resources.uicDirKeyword) {
|
| | | dir = HelperFunctions.NormalizeRelativeFilePath(dir);
|
| | | uicDirCache.Add(fullName, dir);
|
| | | } else if (type == Resources.rccDirKeyword) {
|
| | | dir = HelperFunctions.NormalizeRelativeFilePath(dir);
|
| | | rccDirCache.Add(fullName, dir);
|
| | | } else {
|
| | | dir = HelperFunctions.NormalizeRelativeFilePath(dir);
|
| | | }
|
| | |
|
| | | CleanUpCache(project);
|
| | | return dir; // - retrieved from moc/uic/rcc steps
|
| | | } catch { }
|
| | | return GetDirectory(type); // - fall-back on hard-coded directory
|
| | | }
|
| | |
|
| | | private const string registryPath = "SOFTWARE\\" + Resources.registryPackagePath;
|
| | |
|
| | | public static string GetDirectory(string type)
|
| | | {
|
| | | try {
|
| | | var key = Registry.CurrentUser.OpenSubKey(registryPath);
|
| | | if (key != null) {
|
| | | if (key.GetValue(type, null) is string path)
|
| | | return HelperFunctions.NormalizeRelativeFilePath(path);
|
| | | }
|
| | | } catch { }
|
| | | if (type == Resources.mocDirKeyword)
|
| | | return Resources.generatedFilesDir + "\\$(ConfigurationName)";
|
| | | return Resources.generatedFilesDir;
|
| | | }
|
| | |
|
| | | public static string GetOption(EnvDTE.Project project, string type)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | // check for directory in following order:
|
| | | // - stored in project
|
| | | // - globally defined default option
|
| | | // - empty options
|
| | | if (project != null && project.Globals.get_VariablePersists(type))
|
| | | return project.Globals[type] as string;
|
| | | return GetOption(type);
|
| | | }
|
| | |
|
| | | public static string GetOption(string type)
|
| | | {
|
| | | try {
|
| | | var key = Registry.CurrentUser.OpenSubKey(registryPath);
|
| | | if (key != null) {
|
| | | if (key.GetValue(type, null) is string opt)
|
| | | return opt;
|
| | | }
|
| | | } catch { }
|
| | | return null;
|
| | | }
|
| | |
|
| | | public static bool GetBoolValue(EnvDTE.Project project, string type)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | // check for directory in following order:
|
| | | // - stored in project
|
| | | // - globally defined default option
|
| | | // - empty options
|
| | | if (project != null && project.Globals.get_VariablePersists(type))
|
| | | return Convert.ToInt32(project.Globals[type] as string) > 0;
|
| | | return GetBoolValue(type, false);
|
| | | }
|
| | |
|
| | | public static bool GetBoolValue(string key, bool defaultValue)
|
| | | {
|
| | | var regKey = Registry.CurrentUser.OpenSubKey(registryPath);
|
| | | if (regKey == null)
|
| | | return defaultValue;
|
| | | return ((int)regKey.GetValue(key, defaultValue ? 1 : 0)) > 0;
|
| | | }
|
| | |
|
| | | public static bool ValueExists(string key)
|
| | | {
|
| | | var regKey = Registry.CurrentUser.OpenSubKey(registryPath);
|
| | | if (regKey != null) {
|
| | | foreach (var s in regKey.GetValueNames()) {
|
| | | if (s == key)
|
| | | return true;
|
| | | }
|
| | | }
|
| | | return false;
|
| | | }
|
| | |
|
| | | public static string GetProjectQtSetting(EnvDTE.Project project, string propertyName)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var activeConfig = project?.ConfigurationManager?.ActiveConfiguration;
|
| | | if (activeConfig == null)
|
| | | return null;
|
| | | var activeConfigId = $"{activeConfig.ConfigurationName}|{activeConfig.PlatformName}";
|
| | |
|
| | | try {
|
| | | var props = project.Object as VCProject as IVCBuildPropertyStorage;
|
| | | return props?.GetPropertyValue(propertyName, activeConfigId, "ProjectFile");
|
| | | } catch {
|
| | | return null;
|
| | | }
|
| | | }
|
| | |
|
| | | public static void CleanUpCache(EnvDTE.Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var projects = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
| | | foreach (var p in HelperFunctions.ProjectsInSolution(project.DTE))
|
| | | projects.Add(p.FullName);
|
| | |
|
| | | mocDirCache.RemoveValues(projects);
|
| | | uicDirCache.RemoveValues(projects);
|
| | | rccDirCache.RemoveValues(projects);
|
| | | }
|
| | |
|
| | | static void RemoveValues(this Dictionary<string, string> cache, HashSet<string> projects)
|
| | | {
|
| | | foreach (var key in cache.Keys) {
|
| | | if (projects.Contains(key))
|
| | | cache.Remove(key);
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.IO;
|
| | | using System.Reflection;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | |
| | | /// Using VCCLCompilerTool directly will break the VS integration for Win CE.
|
| | | class CompilerToolWrapper
|
| | | {
|
| | | private VCCLCompilerTool compilerTool;
|
| | | private readonly VCCLCompilerTool compilerTool;
|
| | | private readonly Object compilerObj;
|
| | | private readonly Type compilerType;
|
| | |
|
| | |
| | | return GetStringProperty("AdditionalIncludeDirectories");
|
| | | }
|
| | |
|
| | | public string GetPrecompiledHeaderFile()
|
| | | {
|
| | | if (compilerTool != null)
|
| | | return compilerTool.PrecompiledHeaderFile;
|
| | | return GetStringProperty("PrecompiledHeaderFile");
|
| | | }
|
| | |
|
| | | public string GetPrecompiledHeaderThrough()
|
| | | {
|
| | | if (compilerTool != null)
|
| | |
| | | if (obj == null)
|
| | | return pchOption.pchNone;
|
| | | return (pchOption)obj;
|
| | | }
|
| | |
|
| | | public void SetDebugInformationFormat(debugOption value)
|
| | | {
|
| | | if (compilerTool != null) {
|
| | | compilerTool.DebugInformationFormat = value;
|
| | | } else {
|
| | | compilerType.InvokeMember(
|
| | | "DebugInformationFormat",
|
| | | BindingFlags.SetProperty,
|
| | | null,
|
| | | compilerObj,
|
| | | new object[] { value });
|
| | | }
|
| | | }
|
| | |
|
| | | public runtimeLibraryOption RuntimeLibrary
|
| | |
| | | } else {
|
| | | compilerTool.RuntimeLibrary = value;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | public void SetOptimization(optimizeOption value)
|
| | | {
|
| | | if (compilerTool != null) {
|
| | | compilerTool.Optimization = value;
|
| | | } else {
|
| | | compilerType.InvokeMember(
|
| | | "Optimization",
|
| | | BindingFlags.SetProperty,
|
| | | null,
|
| | | compilerObj,
|
| | | new object[] { value });
|
| | | }
|
| | | }
|
| | |
|
| | | public void SetTreatWChar_tAsBuiltInType(bool value)
|
| | | {
|
| | | if (compilerTool != null) {
|
| | | compilerTool.TreatWChar_tAsBuiltInType = value;
|
| | | } else {
|
| | | compilerType.InvokeMember(
|
| | | "TreatWChar_tAsBuiltInType",
|
| | | BindingFlags.SetProperty,
|
| | | null,
|
| | | compilerObj,
|
| | | new object[] { value });
|
| | | }
|
| | | }
|
| | |
|
| | | public void SetPrecompiledHeaderFile(string file)
|
| | | {
|
| | | if (compilerTool != null) {
|
| | | compilerTool.PrecompiledHeaderFile = file;
|
| | | } else {
|
| | | compilerType.InvokeMember(
|
| | | "PrecompiledHeaderFile",
|
| | | BindingFlags.SetProperty,
|
| | | null,
|
| | | compilerObj,
|
| | | new object[] { file });
|
| | | }
|
| | | }
|
| | |
|
| | | public void SetPrecompiledHeaderThrough(string value)
|
| | | {
|
| | | if (compilerTool != null) {
|
| | | compilerTool.PrecompiledHeaderThrough = value;
|
| | | } else {
|
| | | compilerType.InvokeMember(
|
| | | "PrecompiledHeaderThrough",
|
| | | BindingFlags.SetProperty,
|
| | | null,
|
| | | compilerObj,
|
| | | new object[] { value });
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | Normal, Comment, String
|
| | | }
|
| | | private State state = State.Normal;
|
| | | private StreamReader sr;
|
| | | private readonly StreamReader sr;
|
| | | private string partialLine;
|
| | | bool disposed;
|
| | |
|
| | | int _lineNum;
|
| | | string[] _lines;
|
| | | readonly string[] _lines;
|
| | |
|
| | | public CxxStreamReader(string[] lines)
|
| | | {
|
| | |
| | | optionTextBox.Text = "";
|
| | | openCheckBox.Text = SR.GetString("ExportProjectDialog_Open");
|
| | | createPriFileCheckBox.Text = SR.GetString("ExportProjectDialog_CreatePri");
|
| | |
|
| | | if (SR.LanguageName == "de")
|
| | | Size = new Size(470, 300);
|
| | | else
|
| | | Size = new Size(400, 300);
|
| | | Size = new Size(400, 300);
|
| | |
|
| | | ShowInTaskbar = false;
|
| | | Shown += ExportProjectDialog_Shown;
|
| | |
| | | {
|
| | | public static class Extensions
|
| | | {
|
| | | public static string Quoute(this string input)
|
| | | {
|
| | | if (!input.StartsWith("\"", StringComparison.Ordinal))
|
| | | input = "\"" + input;
|
| | | if (!input.EndsWith("\"", StringComparison.Ordinal))
|
| | | input += "\"";
|
| | | return input;
|
| | | }
|
| | |
|
| | | public static string Replace(this string original, string oldValue, string newValue,
|
| | | StringComparison comparison)
|
| | | {
|
| | |
| | | public string Filter { get; set; }
|
| | | public string UniqueIdentifier { get; set; }
|
| | |
|
| | | private bool parseFiles = true;
|
| | | public bool ParseFiles
|
| | | {
|
| | | get { return parseFiles; }
|
| | | set { parseFiles = value; }
|
| | | }
|
| | | public bool ParseFiles { get; set; } = true;
|
| | | }
|
| | | }
|
| | |
| | | };
|
| | | }
|
| | |
|
| | | public static FakeFilter TranslationFiles()
|
| | | {
|
| | | return new FakeFilter
|
| | | {
|
| | | UniqueIdentifier = "{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}",
|
| | | Name = SR.GetString("Resources_TranslationFiles"),
|
| | | Filter = "ts",
|
| | | ParseFiles = false
|
| | | };
|
| | | }
|
| | |
|
| | | public static FakeFilter GeneratedFiles()
|
| | | {
|
| | | return new FakeFilter
|
| | |
| | | UniqueIdentifier = "{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}",
|
| | | Name = SR.GetString("Resources_GeneratedFiles"),
|
| | | Filter = "moc;h;cpp",
|
| | | };
|
| | | }
|
| | |
|
| | | public static FakeFilter OtherFiles()
|
| | | {
|
| | | return new FakeFilter
|
| | | {
|
| | | UniqueIdentifier = "{B67473BF-9FA1-4674-831E-CB28F72D4791}",
|
| | | Name = SR.GetString("Resources_OtherFiles"),
|
| | | Filter = "*",
|
| | | };
|
| | | }
|
| | | }
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using EnvDTE;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using Microsoft.Win32;
|
| | | using QtVsTools.Core.QtMsBuild;
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.Diagnostics;
|
| | |
| | | using System.Text;
|
| | | using System.Text.RegularExpressions;
|
| | | using System.Windows.Forms;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | #if VS2017
|
| | | using Microsoft.Win32;
|
| | | #endif
|
| | | using EnvDTE;
|
| | |
|
| | | using Process = System.Diagnostics.Process;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | | using QtMsBuild;
|
| | |
|
| | | public static class HelperFunctions
|
| | | {
|
| | | public static string FindQtDirWithTools(Project project)
|
| | | {
|
| | | var versionManager = QtVersionManager.The();
|
| | | string projectQtVersion = null;
|
| | | if (IsQtProject(project))
|
| | | projectQtVersion = versionManager.GetProjectQtVersion(project);
|
| | | return FindQtDirWithTools(projectQtVersion);
|
| | | }
|
| | |
|
| | | public static string FindQtDirWithTools(string projectQtVersion)
|
| | | {
|
| | | string tool = null;
|
| | | return FindQtDirWithTools(tool, projectQtVersion);
|
| | | }
|
| | |
|
| | | public static string FindQtDirWithTools(string tool, string projectQtVersion)
|
| | | {
|
| | | if (!string.IsNullOrEmpty(tool)) {
|
| | | if (!tool.StartsWith("\\bin\\", StringComparison.OrdinalIgnoreCase))
|
| | | tool = "\\bin\\" + tool;
|
| | | if (!tool.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
|
| | | tool += ".exe";
|
| | | }
|
| | |
|
| | | var versionManager = QtVersionManager.The();
|
| | | string qtDir = null;
|
| | | if (projectQtVersion != null)
|
| | | qtDir = versionManager.GetInstallPath(projectQtVersion);
|
| | |
|
| | | if (qtDir == null)
|
| | | qtDir = Environment.GetEnvironmentVariable("QTDIR");
|
| | |
|
| | | var found = false;
|
| | | if (tool == null) {
|
| | | found = File.Exists(qtDir + "\\bin\\designer.exe")
|
| | | && File.Exists(qtDir + "\\bin\\linguist.exe");
|
| | | } else {
|
| | | found = File.Exists(qtDir + tool);
|
| | | }
|
| | | if (!found) {
|
| | | VersionInformation exactlyMatchingVersion = null;
|
| | | VersionInformation matchingVersion = null;
|
| | | VersionInformation somehowMatchingVersion = null;
|
| | | var viProjectQtVersion = versionManager.GetVersionInfo(projectQtVersion);
|
| | | foreach (var qtVersion in versionManager.GetVersions()) {
|
| | | var vi = versionManager.GetVersionInfo(qtVersion);
|
| | | if (tool == null) {
|
| | | found = File.Exists(vi.qtDir + "\\bin\\designer.exe")
|
| | | && File.Exists(vi.qtDir + "\\bin\\linguist.exe");
|
| | | } else {
|
| | | found = File.Exists(vi.qtDir + tool);
|
| | | }
|
| | | if (!found)
|
| | | continue;
|
| | |
|
| | | if (viProjectQtVersion != null
|
| | | && vi.qtMajor == viProjectQtVersion.qtMajor
|
| | | && vi.qtMinor == viProjectQtVersion.qtMinor) {
|
| | | exactlyMatchingVersion = vi;
|
| | | break;
|
| | | }
|
| | | if (matchingVersion == null
|
| | | && viProjectQtVersion != null
|
| | | && vi.qtMajor == viProjectQtVersion.qtMajor) {
|
| | | matchingVersion = vi;
|
| | | }
|
| | | if (somehowMatchingVersion == null)
|
| | | somehowMatchingVersion = vi;
|
| | | }
|
| | |
|
| | | if (exactlyMatchingVersion != null)
|
| | | qtDir = exactlyMatchingVersion.qtDir;
|
| | | else if (matchingVersion != null)
|
| | | qtDir = matchingVersion.qtDir;
|
| | | else if (somehowMatchingVersion != null)
|
| | | qtDir = somehowMatchingVersion.qtDir;
|
| | | else
|
| | | qtDir = null;
|
| | | }
|
| | | return qtDir;
|
| | | }
|
| | |
|
| | | static readonly HashSet<string> _sources = new HashSet<string>(new[] { ".c", ".cpp", ".cxx" },
|
| | | StringComparer.OrdinalIgnoreCase);
|
| | | static public bool IsSourceFile(string fileName)
|
| | | public static bool IsSourceFile(string fileName)
|
| | | {
|
| | | return _sources.Contains(Path.GetExtension(fileName));
|
| | | }
|
| | |
|
| | | static readonly HashSet<string> _headers = new HashSet<string>(new[] { ".h", ".hpp", ".hxx" },
|
| | | StringComparer.OrdinalIgnoreCase);
|
| | | static public bool IsHeaderFile(string fileName)
|
| | | public static bool IsHeaderFile(string fileName)
|
| | | {
|
| | | return _headers.Contains(Path.GetExtension(fileName));
|
| | | }
|
| | |
| | | return ".qml".Equals(Path.GetExtension(fileName), StringComparison.OrdinalIgnoreCase);
|
| | | }
|
| | |
|
| | | static public void SetDebuggingEnvironment(Project prj)
|
| | | public static void SetDebuggingEnvironment(Project prj)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | SetDebuggingEnvironment(prj, string.Empty);
|
| | | }
|
| | |
|
| | | static public void SetDebuggingEnvironment(Project prj, string solutionConfig)
|
| | | public static void SetDebuggingEnvironment(Project prj, string solutionConfig)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | SetDebuggingEnvironment(prj, "PATH=$(QTDIR)\\bin;$(PATH)", false, solutionConfig);
|
| | | }
|
| | |
|
| | | static public void SetDebuggingEnvironment(Project prj, string envpath, bool overwrite)
|
| | | public static void SetDebuggingEnvironment(Project prj, string envpath, bool overwrite)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | SetDebuggingEnvironment(prj, envpath, overwrite, string.Empty);
|
| | | }
|
| | |
|
| | | static public void SetDebuggingEnvironment(Project prj, string envpath, bool overwrite, string solutionConfig)
|
| | | public static void SetDebuggingEnvironment(Project prj, string envpath, bool overwrite, string solutionConfig)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (QtProject.GetFormatVersion(prj) >= Resources.qtMinFormatVersion_Settings)
|
| | | return;
|
| | |
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | public static bool IsProjectInSolution(DTE dteObject, string fullName)
|
| | | public static Project ProjectFromSolution(DTE dteObject, string fullName)
|
| | | {
|
| | | var fi = new FileInfo(fullName);
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | fullName = new FileInfo(fullName).FullName;
|
| | | foreach (var p in ProjectsInSolution(dteObject)) {
|
| | | if (p.FullName.ToLower() == fi.FullName.ToLower())
|
| | | return true;
|
| | | if (p.FullName.Equals(fullName, StringComparison.OrdinalIgnoreCase))
|
| | | return p;
|
| | | }
|
| | | return false;
|
| | | return null;
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// Returns the normalized file path of a given file.
|
| | | /// </summary>
|
| | | /// <param name="name">file name</param>
|
| | | static public string NormalizeFilePath(string name)
|
| | | public static string NormalizeFilePath(string name)
|
| | | {
|
| | | var fi = new FileInfo(name);
|
| | | return fi.FullName;
|
| | | }
|
| | |
|
| | | static public string NormalizeRelativeFilePath(string path)
|
| | | public static string NormalizeRelativeFilePath(string path)
|
| | | {
|
| | | if (path == null)
|
| | | return ".\\";
|
| | |
| | | return path;
|
| | | }
|
| | |
|
| | | static public bool IsAbsoluteFilePath(string path)
|
| | | public static bool IsAbsoluteFilePath(string path)
|
| | | {
|
| | | path = path.Trim();
|
| | | if (path.Length >= 2 && path[1] == ':')
|
| | |
| | | /// </summary>
|
| | | /// <param name="streamReader"></param>
|
| | | /// <returns>the composite string</returns>
|
| | | static private string ReadProFileLine(StreamReader streamReader)
|
| | | private static string ReadProFileLine(StreamReader streamReader)
|
| | | {
|
| | | var line = streamReader.ReadLine();
|
| | | if (line == null)
|
| | |
| | | /// </summary>
|
| | | /// <param name="profile">full name of .pro file to read</param>
|
| | | /// <returns>true if this is a subdirs file</returns>
|
| | | static public bool IsSubDirsFile(string profile)
|
| | | public static bool IsSubDirsFile(string profile)
|
| | | {
|
| | | StreamReader sr = null;
|
| | | try {
|
| | |
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// Replaces a string in the commandLine, description, outputs and additional dependencies
|
| | | /// in all Custom build tools of the project
|
| | | /// </summary>
|
| | | /// <param name="project">Project</param>
|
| | | /// <param name="oldString">String, which is going to be replaced</param>
|
| | | /// <param name="oldString">String, which is going to replace the other one</param>
|
| | | /// <returns></returns>
|
| | | public static void ReplaceInCustomBuildTools(Project project, string oldString, string replaceString)
|
| | | {
|
| | | var vcPro = (VCProject)project.Object;
|
| | | if (vcPro == null)
|
| | | return;
|
| | |
|
| | | var qtMsBuild = new QtMsBuildContainer(new VCPropertyStorageProvider());
|
| | | qtMsBuild.BeginSetItemProperties();
|
| | | foreach (VCFile vcfile in (IVCCollection)vcPro.Files) {
|
| | | foreach (VCFileConfiguration config in (IVCCollection)vcfile.FileConfigurations) {
|
| | | try {
|
| | | if (vcfile.ItemType == "CustomBuild") {
|
| | | var tool = GetCustomBuildTool(config);
|
| | | if (tool == null)
|
| | | continue;
|
| | |
|
| | | tool.CommandLine = tool.CommandLine
|
| | | .Replace(oldString, replaceString,
|
| | | StringComparison.OrdinalIgnoreCase);
|
| | | tool.Description = tool.Description
|
| | | .Replace(oldString, replaceString,
|
| | | StringComparison.OrdinalIgnoreCase);
|
| | | tool.Outputs = tool.Outputs
|
| | | .Replace(oldString, replaceString,
|
| | | StringComparison.OrdinalIgnoreCase);
|
| | | tool.AdditionalDependencies = tool.AdditionalDependencies
|
| | | .Replace(oldString, replaceString,
|
| | | StringComparison.OrdinalIgnoreCase);
|
| | | } else {
|
| | | var tool = new QtCustomBuildTool(config, qtMsBuild);
|
| | | tool.CommandLine = tool.CommandLine
|
| | | .Replace(oldString, replaceString,
|
| | | StringComparison.OrdinalIgnoreCase);
|
| | | }
|
| | | } catch (Exception) {
|
| | | }
|
| | | }
|
| | | }
|
| | | qtMsBuild.EndSetItemProperties();
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// Since VS2010 it is possible to have VCCustomBuildTools without commandlines
|
| | | /// for certain filetypes. We are not interested in them and thus try to read the
|
| | | /// tool's commandline. If this causes an exception, we ignore it.
|
| | |
| | | /// </summary>
|
| | | /// <param name="config">File configuration</param>
|
| | | /// <returns></returns>
|
| | | static public VCCustomBuildTool GetCustomBuildTool(VCFileConfiguration config)
|
| | | public static VCCustomBuildTool GetCustomBuildTool(VCFileConfiguration config)
|
| | | {
|
| | | var file = config.File as VCFile;
|
| | | if (file == null || file.ItemType != "CustomBuild")
|
| | | return null;
|
| | |
|
| | | var tool = config.Tool as VCCustomBuildTool;
|
| | | if (tool == null)
|
| | | return null;
|
| | |
|
| | | try {
|
| | | // TODO: The return value is not used at all?
|
| | | var cmdLine = tool.CommandLine;
|
| | | } catch {
|
| | | return null;
|
| | | if (config.File is VCFile file
|
| | | && file.ItemType == "CustomBuild"
|
| | | && config.Tool is VCCustomBuildTool tool) {
|
| | | try {
|
| | | _ = tool.CommandLine;
|
| | | } catch {
|
| | | return null;
|
| | | }
|
| | | return tool;
|
| | | }
|
| | | return tool;
|
| | | return null;
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | |
| | | /// has to be "CustomBuild"
|
| | | /// </summary>
|
| | | /// <param name="projectItem">Project Item which needs to have custom build tool</param>
|
| | | static public void EnsureCustomBuildToolAvailable(ProjectItem projectItem)
|
| | | public static void EnsureCustomBuildToolAvailable(ProjectItem projectItem)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | foreach (Property prop in projectItem.Properties) {
|
| | | if (prop.Name == "ItemType") {
|
| | | if ((string)prop.Value != "CustomBuild")
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// As Qmake -tp vc Adds the full path to the additional dependencies
|
| | | /// we need to do the same when toggling project kind to qmake generated.
|
| | | /// </summary>
|
| | | /// <returns></returns>
|
| | | private static string AddFullPathToAdditionalDependencies(string qtDir, string additionalDependencies)
|
| | | {
|
| | | var returnString = additionalDependencies;
|
| | | returnString =
|
| | | Regex.Replace(returnString, "Qt(\\S+5?)\\.lib", qtDir + "\\lib\\Qt${1}.lib");
|
| | | returnString =
|
| | | Regex.Replace(returnString, "(qtmaind?5?)\\.lib", qtDir + "\\lib\\${1}.lib");
|
| | | returnString =
|
| | | Regex.Replace(returnString, "(enginiod?5?)\\.lib", qtDir + "\\lib\\${1}.lib");
|
| | | return returnString;
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// Toggles the kind of a project. If the project is a QMake generated project (qmake -tp vc)
|
| | | /// it is transformed to an Qt VS Tools project and vice versa.
|
| | | /// </summary>
|
| | | /// <param name="project">Project</param>
|
| | | /// <returns></returns>
|
| | | public static void ToggleProjectKind(Project project)
|
| | | {
|
| | | if (QtProject.GetFormatVersion(project) >= Resources.qtMinFormatVersion_Settings)
|
| | | return;
|
| | |
|
| | | string qtDir = null;
|
| | | var vcPro = (VCProject)project.Object;
|
| | | if (!IsQMakeProject(project))
|
| | | return;
|
| | | if (IsQtProject(project)) {
|
| | | // TODO: qtPro is never used.
|
| | | var qtPro = QtProject.Create(project);
|
| | | var vm = QtVersionManager.The();
|
| | | qtDir = vm.GetInstallPath(project);
|
| | |
|
| | | foreach (var global in (string[])project.Globals.VariableNames) {
|
| | | if (global.StartsWith("Qt5Version", StringComparison.Ordinal))
|
| | | project.Globals.set_VariablePersists(global, false);
|
| | | }
|
| | |
|
| | | foreach (VCConfiguration config in (IVCCollection)vcPro.Configurations) {
|
| | | var compiler = CompilerToolWrapper.Create(config);
|
| | | var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
|
| | | var librarian = (VCLibrarianTool)((IVCCollection)config.Tools).Item("VCLibrarianTool");
|
| | | if (compiler != null) {
|
| | | var additionalIncludes = compiler.GetAdditionalIncludeDirectories();
|
| | | additionalIncludes = additionalIncludes.Replace("$(QTDIR)", qtDir,
|
| | | StringComparison.OrdinalIgnoreCase);
|
| | | compiler.SetAdditionalIncludeDirectories(additionalIncludes);
|
| | | }
|
| | | if (linker != null) {
|
| | | linker.AdditionalLibraryDirectories = linker.AdditionalLibraryDirectories.
|
| | | Replace("$(QTDIR)", qtDir, StringComparison.OrdinalIgnoreCase);
|
| | | linker.AdditionalDependencies = AddFullPathToAdditionalDependencies(qtDir, linker.AdditionalDependencies);
|
| | | } else {
|
| | | librarian.AdditionalLibraryDirectories = librarian.AdditionalLibraryDirectories
|
| | | .Replace("$(QTDIR)", qtDir, StringComparison.OrdinalIgnoreCase);
|
| | | librarian.AdditionalDependencies = AddFullPathToAdditionalDependencies(qtDir, librarian.AdditionalDependencies);
|
| | | }
|
| | | }
|
| | |
|
| | | ReplaceInCustomBuildTools(project, "$(QTDIR)", qtDir);
|
| | | } else {
|
| | | qtDir = GetQtDirFromQMakeProject(project);
|
| | |
|
| | | var vm = QtVersionManager.The();
|
| | | var qtVersion = vm.GetQtVersionFromInstallDir(qtDir);
|
| | | if (qtVersion == null)
|
| | | qtVersion = vm.GetDefaultVersion();
|
| | | if (qtDir == null)
|
| | | qtDir = vm.GetInstallPath(qtVersion);
|
| | | var vi = vm.GetVersionInfo(qtVersion);
|
| | | var platformName = vi.GetVSPlatformName();
|
| | | vm.SaveProjectQtVersion(project, qtVersion, platformName);
|
| | | var qtPro = QtProject.Create(project);
|
| | | if (!qtPro.SelectSolutionPlatform(platformName) || !qtPro.HasPlatform(platformName)) {
|
| | | var newProject = false;
|
| | | qtPro.CreatePlatform("Win32", platformName, null, vi, ref newProject);
|
| | | if (!qtPro.SelectSolutionPlatform(platformName))
|
| | | Messages.Print("Can't select the platform " + platformName + ".");
|
| | | }
|
| | |
|
| | | var activeConfig = project.ConfigurationManager.ActiveConfiguration.ConfigurationName;
|
| | | var activeVCConfig = (VCConfiguration)((IVCCollection)qtPro.VCProject.Configurations).Item(activeConfig);
|
| | | if (activeVCConfig.ConfigurationType == ConfigurationTypes.typeDynamicLibrary) {
|
| | | var compiler = CompilerToolWrapper.Create(activeVCConfig);
|
| | | var linker = (VCLinkerTool)((IVCCollection)activeVCConfig.Tools).Item("VCLinkerTool");
|
| | | var ppdefs = compiler.GetPreprocessorDefinitions();
|
| | | if (ppdefs != null
|
| | | && ppdefs.IndexOf("QT_PLUGIN", StringComparison.Ordinal) > -1
|
| | | && ppdefs.IndexOf("QDESIGNER_EXPORT_WIDGETS", StringComparison.Ordinal) > -1
|
| | | && ppdefs.IndexOf("QtDesigner", StringComparison.Ordinal) > -1
|
| | | && linker.AdditionalDependencies != null
|
| | | && linker.AdditionalDependencies.IndexOf("QtDesigner", StringComparison.Ordinal) > -1) {
|
| | | qtPro.MarkAsDesignerPluginProject();
|
| | | }
|
| | | }
|
| | |
|
| | | CleanupQMakeDependencies(project);
|
| | |
|
| | | foreach (VCConfiguration config in (IVCCollection)vcPro.Configurations) {
|
| | | var compiler = CompilerToolWrapper.Create(config);
|
| | | var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
|
| | |
|
| | | if (compiler != null) {
|
| | | var additionalIncludes = compiler.AdditionalIncludeDirectories;
|
| | | if (additionalIncludes != null) {
|
| | | ReplaceDirectory(ref additionalIncludes, qtDir, "$(QTDIR)", project);
|
| | | compiler.AdditionalIncludeDirectories = additionalIncludes;
|
| | | }
|
| | | }
|
| | | if (linker != null) {
|
| | | var linkerToolWrapper = new LinkerToolWrapper(linker);
|
| | | var paths = linkerToolWrapper.AdditionalLibraryDirectories;
|
| | | if (paths != null) {
|
| | | ReplaceDirectory(ref paths, qtDir, "$(QTDIR)", project);
|
| | | linkerToolWrapper.AdditionalLibraryDirectories = paths;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | ReplaceInCustomBuildTools(project, qtDir, "$(QTDIR)");
|
| | | qtPro.TranslateFilterNames();
|
| | | }
|
| | | project.Save(project.FullName);
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// Replaces every occurrence of oldDirectory with replacement in the array of strings.
|
| | | /// Parameter oldDirectory must be an absolute path.
|
| | | /// This function converts relative directories to absolute paths internally
|
| | | /// and replaces them, if necessary. If no replacement is done, the path isn't altered.
|
| | | /// </summary>
|
| | | /// <param name="project">The project is needed to convert relative paths to absolute paths.</param>
|
| | | private static void ReplaceDirectory(ref List<string> paths, string oldDirectory, string replacement, Project project)
|
| | | {
|
| | | for (var i = 0; i < paths.Count; ++i) {
|
| | | var dirName = paths[i];
|
| | | if (dirName.StartsWith("\"", StringComparison.Ordinal) && dirName.EndsWith("\"", StringComparison.Ordinal)) {
|
| | | dirName = dirName.Substring(1, dirName.Length - 2);
|
| | | }
|
| | | if (!Path.IsPathRooted(dirName)) {
|
| | | // convert to absolute path
|
| | | dirName = Path.Combine(Path.GetDirectoryName(project.FullName), dirName);
|
| | | dirName = Path.GetFullPath(dirName);
|
| | | var alteredDirName = dirName.Replace(oldDirectory, replacement, StringComparison
|
| | | .OrdinalIgnoreCase);
|
| | | if (alteredDirName == dirName)
|
| | | continue;
|
| | | dirName = alteredDirName;
|
| | | } else {
|
| | | dirName = dirName.Replace(oldDirectory, replacement, StringComparison
|
| | | .OrdinalIgnoreCase);
|
| | | }
|
| | | paths[i] = dirName;
|
| | | }
|
| | | }
|
| | |
|
| | | public static string GetQtDirFromQMakeProject(Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var vcProject = project.Object as VCProject;
|
| | | if (vcProject == null)
|
| | | return null;
|
| | |
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// Return true if the project is a Qt project, otherwise false.
|
| | | /// Return true if the project is a VS tools project; false otherwise.
|
| | | /// </summary>
|
| | | /// <param name="proj">project</param>
|
| | | /// <returns></returns>
|
| | | public static bool IsQtProject(VCProject proj)
|
| | | public static bool IsVsToolsProject(Project proj)
|
| | | {
|
| | | if (!IsQMakeProject(proj))
|
| | | ThreadHelper.ThrowIfNotOnUIThread(); // C++ Project Type GUID
|
| | | if (proj == null || proj.Kind != "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")
|
| | | return false;
|
| | | return IsVsToolsProject(proj.Object as VCProject);
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// Return true if the project is a VS tools project; false otherwise.
|
| | | /// </summary>
|
| | | /// <param name="proj">project</param>
|
| | | public static bool IsVsToolsProject(VCProject proj)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | if (!IsQtProject(proj))
|
| | | return false;
|
| | |
|
| | | if (QtProject.GetFormatVersion(proj) >= Resources.qtMinFormatVersion_Settings)
|
| | |
| | | return false;
|
| | |
|
| | | foreach (var global in envPro.Globals.VariableNames as string[]) {
|
| | | if (global.StartsWith("Qt5Version", StringComparison.Ordinal) && envPro.Globals.get_VariablePersists(global))
|
| | | if (global.StartsWith("Qt5Version", StringComparison.Ordinal)
|
| | | && envPro.Globals.get_VariablePersists(global)) {
|
| | | return true;
|
| | | }
|
| | | }
|
| | | return false;
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// Returns true if the specified project is a Qt Project.
|
| | | /// Return true if the project is a Qt project; false otherwise.
|
| | | /// </summary>
|
| | | /// <param name="proj">project</param>
|
| | | public static bool IsQtProject(Project proj)
|
| | | {
|
| | | try {
|
| | | if (proj != null && proj.Kind == "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")
|
| | | return IsQtProject(proj.Object as VCProject);
|
| | | } catch { }
|
| | | return false;
|
| | | ThreadHelper.ThrowIfNotOnUIThread(); //C++ Project Type GUID
|
| | | if (proj == null || proj.Kind != "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")
|
| | | return false;
|
| | | return IsQtProject(proj.Object as VCProject);
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// Return true if the project is a QMake -tp vc project, otherwise false.
|
| | | /// Return true if the project is a Qt project; false otherwise.
|
| | | /// </summary>
|
| | | /// <param name="proj">project</param>
|
| | | /// <returns></returns>
|
| | | public static bool IsQMakeProject(VCProject proj)
|
| | | public static bool IsQtProject(VCProject proj)
|
| | | {
|
| | | if (proj == null)
|
| | | return false;
|
| | | var keyword = proj.keyword;
|
| | | if (keyword == null ||
|
| | | (!keyword.StartsWith(Resources.qtProjectV2Keyword, StringComparison.Ordinal)
|
| | | && !keyword.StartsWith(Resources.qtProjectKeyword, StringComparison.Ordinal))) {
|
| | | if (string.IsNullOrEmpty(keyword))
|
| | | return false;
|
| | | }
|
| | |
|
| | | return true;
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// Returns true if the specified project is a QMake -tp vc Project.
|
| | | /// </summary>
|
| | | /// <param name="proj">project</param>
|
| | | public static bool IsQMakeProject(Project proj)
|
| | | {
|
| | | try {
|
| | | if (proj != null && proj.Kind == "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}")
|
| | | return IsQMakeProject(proj.Object as VCProject);
|
| | | } catch { }
|
| | | return false;
|
| | | }
|
| | |
|
| | | public static void CleanupQMakeDependencies(Project project)
|
| | | {
|
| | | var vcPro = (VCProject)project.Object;
|
| | | // clean up qmake mess
|
| | | var rxp1 = new Regex("\\bQt\\w+d?5?\\.lib\\b");
|
| | | var rxp2 = new Regex("\\bQAx\\w+\\.lib\\b");
|
| | | var rxp3 = new Regex("\\bqtmaind?.lib\\b");
|
| | | var rxp4 = new Regex("\\benginiod?.lib\\b");
|
| | | foreach (VCConfiguration cfg in (IVCCollection)vcPro.Configurations) {
|
| | | var linker = (VCLinkerTool)((IVCCollection)cfg.Tools).Item("VCLinkerTool");
|
| | | if (linker == null || linker.AdditionalDependencies == null)
|
| | | continue;
|
| | | var linkerWrapper = new LinkerToolWrapper(linker);
|
| | | var deps = linkerWrapper.AdditionalDependencies;
|
| | | var newDeps = new List<string>();
|
| | | foreach (var lib in deps) {
|
| | | var m1 = rxp1.Match(lib);
|
| | | var m2 = rxp2.Match(lib);
|
| | | var m3 = rxp3.Match(lib);
|
| | | var m4 = rxp4.Match(lib);
|
| | | if (m1.Success)
|
| | | newDeps.Add(m1.ToString());
|
| | | else if (m2.Success)
|
| | | newDeps.Add(m2.ToString());
|
| | | else if (m3.Success)
|
| | | newDeps.Add(m3.ToString());
|
| | | else if (m4.Success)
|
| | | newDeps.Add(m4.ToString());
|
| | | else
|
| | | newDeps.Add(lib);
|
| | | }
|
| | | // Remove Duplicates
|
| | | var uniques = new Dictionary<string, int>();
|
| | | foreach (var dep in newDeps)
|
| | | uniques[dep] = 1;
|
| | | var uniqueList = new List<string>(uniques.Keys);
|
| | | linkerWrapper.AdditionalDependencies = uniqueList;
|
| | | }
|
| | | return keyword.StartsWith(Resources.qtProjectKeyword, StringComparison.Ordinal)
|
| | | || keyword.StartsWith(Resources.qtProjectV2Keyword, StringComparison.Ordinal);
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// Converts all directory separators of the path to the alternate character
|
| | | /// directory separator. For instance, FromNativeSeparators("c:\\winnt\\system32")
|
| | | /// returns "c:/winnt/system32".
|
| | | /// </summary>
|
| | | /// <param name="path">The path to convert.</param>
|
| | | /// <returns>Returns path using '/' as file separator.</returns>
|
| | | public static string FromNativeSeparators(string path)
|
| | | {
|
| | | return path.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// Converts all alternate directory separators characters of the path to the native
|
| | | /// directory separator. For instance, ToNativeSeparators("c:/winnt/system32")
|
| | | /// returns "c:\\winnt\\system32".
|
| | | /// </summary>
|
| | | /// <param name="path">The path to convert.</param>
|
| | | /// <returns>Returns path using '\' as file separator.</returns>
|
| | | public static string ToNativeSeparator(string path)
|
| | | {
|
| | | return path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
| | | }
|
| | |
|
| | | public static string ChangePathFormat(string path)
|
| | | {
|
| | | return path.Replace('\\', '/');
|
| | |
| | |
|
| | | public static void CollapseFilter(UIHierarchyItem item, UIHierarchy hierarchy, string nodeToCollapseFilter)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (string.IsNullOrEmpty(nodeToCollapseFilter))
|
| | | return;
|
| | |
|
| | |
| | |
|
| | | public static void CollapseFilter(UIHierarchyItem item, UIHierarchy hierarchy)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var subItems = item.UIHierarchyItems;
|
| | | if (subItems != null) {
|
| | | foreach (UIHierarchyItem innerItem in subItems) {
|
| | |
| | |
|
| | | public static List<string> GetProjectFiles(Project pro, FilesToList filter)
|
| | | {
|
| | | var fileList = new List<string>();
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | VCProject vcpro;
|
| | | try {
|
| | |
| | | return null;
|
| | | }
|
| | |
|
| | | var fileList = new List<string>();
|
| | | var configurationName = pro.ConfigurationManager.ActiveConfiguration.ConfigurationName;
|
| | |
|
| | | foreach (VCFile vcfile in (IVCCollection)vcpro.Files) {
|
| | |
| | | /// <param name="fileName"></param>
|
| | | public static void RemoveFileInProject(VCProject vcpro, string fileName)
|
| | | {
|
| | | var qtProj = QtProject.Create(vcpro);
|
| | | var fi = new FileInfo(fileName);
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | fileName = new FileInfo(fileName).FullName;
|
| | | foreach (VCFile vcfile in (IVCCollection)vcpro.Files) {
|
| | | if (vcfile.FullPath.ToLower() == fi.FullName.ToLower()) {
|
| | | if (vcfile.FullPath.Equals(fileName, StringComparison.OrdinalIgnoreCase)) {
|
| | | vcpro.RemoveFile(vcfile);
|
| | | qtProj.MoveFileToDeletedFolder(vcfile);
|
| | | QtProject.Create(vcpro)?.MoveFileToDeletedFolder(vcfile);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | public static Project GetSelectedProject(DTE dteObject)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (dteObject == null)
|
| | | return null;
|
| | |
|
| | | Array prjs = null;
|
| | | try {
|
| | | prjs = (Array)dteObject.ActiveSolutionProjects;
|
| | |
| | | return null;
|
| | |
|
| | | // don't handle multiple selection... use the first one
|
| | | if (prjs.GetValue(0) is Project)
|
| | | return (Project)prjs.GetValue(0);
|
| | | if (prjs.GetValue(0) is Project project)
|
| | | return project;
|
| | | return null;
|
| | | }
|
| | |
|
| | | public static Project GetActiveDocumentProject(DTE dteObject)
|
| | | {
|
| | | if (dteObject == null)
|
| | | return null;
|
| | | var doc = dteObject.ActiveDocument;
|
| | | if (doc == null)
|
| | | return null;
|
| | |
|
| | | if (doc.ProjectItem == null)
|
| | | return null;
|
| | |
|
| | | return doc.ProjectItem.ContainingProject;
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return dteObject?.ActiveDocument?.ProjectItem?.ContainingProject;
|
| | | }
|
| | |
|
| | | public static Project GetSingleProjectInSolution(DTE dteObject)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var projectList = ProjectsInSolution(dteObject);
|
| | | if (dteObject == null || dteObject.Solution == null ||
|
| | | projectList.Count != 1)
|
| | | if (projectList.Count != 1)
|
| | | return null; // no way to know which one to select
|
| | |
|
| | | return projectList[0];
|
| | |
| | | /// </summary>
|
| | | public static Project GetSelectedQtProject(DTE dteObject)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | // can happen sometimes shortly after starting VS
|
| | | if (dteObject == null || dteObject.Solution == null
|
| | | || ProjectsInSolution(dteObject).Count == 0)
|
| | | if (ProjectsInSolution(dteObject).Count == 0)
|
| | | return null;
|
| | |
|
| | | Project pro;
|
| | |
|
| | | if ((pro = GetSelectedProject(dteObject)) == null) {
|
| | | var pro = GetSelectedProject(dteObject);
|
| | | if (pro == null) {
|
| | | if ((pro = GetSingleProjectInSolution(dteObject)) == null)
|
| | | pro = GetActiveDocumentProject(dteObject);
|
| | | }
|
| | | return IsQtProject(pro) ? pro : null;
|
| | | return IsVsToolsProject(pro) ? pro : null;
|
| | | }
|
| | |
|
| | | public static VCFile[] GetSelectedFiles(DTE dteObject)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (GetSelectedQtProject(dteObject) == null)
|
| | | return null;
|
| | |
|
| | |
| | |
|
| | | public static RccOptions ParseRccOptions(string cmdLine, VCFile qrcFile)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var pro = VCProjectToProject((VCProject)qrcFile.project);
|
| | |
|
| | | var rccOpts = new RccOptions(pro, qrcFile);
|
| | |
| | |
|
| | | public static Project VCProjectToProject(VCProject vcproj)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return (Project)vcproj.Object;
|
| | | }
|
| | |
|
| | | public static List<Project> ProjectsInSolution(DTE dteObject)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (dteObject == null)
|
| | | return new List<Project>();
|
| | |
|
| | | var projects = new List<Project>();
|
| | | var solution = dteObject.Solution;
|
| | | if (solution != null) {
|
| | |
| | |
|
| | | private static void addSubProjects(Project prj, ref List<Project> projects)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | // If the actual object of the project is null then the project was probably unloaded.
|
| | | if (prj.Object == null)
|
| | | return;
|
| | |
| | |
|
| | | private static void addSubProjects(ProjectItems subItems, ref List<Project> projects)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (subItems == null)
|
| | | return;
|
| | |
|
| | |
| | | return true;
|
| | | }
|
| | |
|
| | | public static string FindFileInPATH(string fileName)
|
| | | {
|
| | | var envPATH = Environment.ExpandEnvironmentVariables("%PATH%");
|
| | | var directories = envPATH.Split(';');
|
| | | foreach (var directory in directories) {
|
| | | var fullFilePath = directory;
|
| | | if (!fullFilePath.EndsWith("\\", StringComparison.Ordinal))
|
| | | fullFilePath += '\\';
|
| | | fullFilePath += fileName;
|
| | | if (File.Exists(fullFilePath))
|
| | | return fullFilePath;
|
| | | }
|
| | | return null;
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// This method copies the specified directory and all its child directories and files to
|
| | | /// the specified destination. The destination directory is created if it does not exist.
|
| | |
| | | string platformName,
|
| | | string filePath = null)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (project == null
|
| | | || string.IsNullOrEmpty(configName)
|
| | | || string.IsNullOrEmpty(platformName))
|
| | | return false;
|
| | |
|
| | | var vcProject = project.Object as VCProject;
|
| | |
|
| | | if (filePath == null) {
|
| | | var vcConfig = (from VCConfiguration _config
|
| | | in (IVCCollection)vcProject.Configurations
|
| | |
| | | VCProject vcProj = null;
|
| | | VCFile vcFile = null;
|
| | | string configName = "", platformName = "";
|
| | | var vcConfig = config as VCConfiguration;
|
| | | if (vcConfig != null) {
|
| | | if (config is VCConfiguration vcConfig) {
|
| | | vcProj = vcConfig.project as VCProject;
|
| | | configName = vcConfig.ConfigurationName;
|
| | | var vcPlatform = vcConfig.Platform as VCPlatform;
|
| | | if (vcPlatform != null)
|
| | | if (vcConfig.Platform is VCPlatform vcPlatform)
|
| | | platformName = vcPlatform.Name;
|
| | | try {
|
| | | expanded = vcConfig.Evaluate(expanded);
|
| | |
| | | vcFile = vcFileConfig.File as VCFile;
|
| | | if (vcFile != null)
|
| | | vcProj = vcFile.project as VCProject;
|
| | | var vcProjConfig = vcFileConfig.ProjectConfiguration as VCConfiguration;
|
| | | if (vcProjConfig != null) {
|
| | | if (vcFileConfig.ProjectConfiguration is VCConfiguration vcProjConfig) {
|
| | | configName = vcProjConfig.ConfigurationName;
|
| | | var vcPlatform = vcProjConfig.Platform as VCPlatform;
|
| | | if (vcPlatform != null)
|
| | | if (vcProjConfig.Platform is VCPlatform vcPlatform)
|
| | | platformName = vcPlatform.Name;
|
| | | }
|
| | | try {
|
| | |
| | | return true;
|
| | | }
|
| | |
|
| | | #if VS2017
|
| | | private static string GetRegistrySoftwareString(string subKeyName, string valueName)
|
| | | {
|
| | | var keyName = new StringBuilder();
|
| | |
| | | if (System.Environment.Is64BitOperatingSystem && IntPtr.Size == 4)
|
| | | keyName.Append(@"WOW6432Node\");
|
| | | keyName.Append(subKeyName);
|
| | |
|
| | | try {
|
| | | using (var key = Registry.LocalMachine.OpenSubKey(keyName.ToString(), false)) {
|
| | | if (key == null)
|
| | | return ""; //key not found
|
| | |
|
| | | RegistryValueKind valueKind = key.GetValueKind(valueName);
|
| | | if (valueKind != RegistryValueKind.String
|
| | | && valueKind != RegistryValueKind.ExpandString) {
|
| | | return ""; //wrong value kind
|
| | | }
|
| | |
|
| | | Object objValue = key.GetValue(valueName);
|
| | | if (objValue == null)
|
| | | return ""; //error getting value
|
| | |
|
| | | return objValue.ToString();
|
| | | }
|
| | | } catch {
|
| | | return "";
|
| | | }
|
| | | }
|
| | | #endif
|
| | |
|
| | | public static string GetWindows10SDKVersion()
|
| | | {
|
| | |
| | | string vcPath = Path.Combine(vsPath, "VC");
|
| | | #endif
|
| | | return vcPath;
|
| | | }
|
| | |
|
| | | public static bool SetVCVars(ProcessStartInfo startInfo)
|
| | | {
|
| | | return SetVCVars(null, startInfo);
|
| | | }
|
| | |
|
| | | public static bool SetVCVars(VersionInformation VersionInfo, ProcessStartInfo startInfo)
|
| | |
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | // Get PATH
|
| | | string envPath = startInfo.EnvironmentVariables["PATH"];
|
| | | string clPath = envPath.Split(';')
|
| | |
|
| | | // Remove invalid chars
|
| | | envPath = string.Join("", envPath.Split(Path.GetInvalidPathChars()));
|
| | |
|
| | | // Split into list of paths
|
| | | var paths = envPath
|
| | | .Split(';')
|
| | | .Where(x => !string.IsNullOrEmpty(x))
|
| | | .Select(x => x.Trim());
|
| | |
|
| | | // Check if cl.exe is in PATH
|
| | | string clPath = paths
|
| | | .Select(path => Path.Combine(path, "cl.exe"))
|
| | | .Where(pathToCl => File.Exists(pathToCl))
|
| | | .FirstOrDefault();
|
| | |
| | | } else {
|
| | | return canonicalPath;
|
| | | }
|
| | | }
|
| | |
|
| | | public static bool PathEquals(string path1, string path2)
|
| | | {
|
| | | return (CanonicalPath(path1).Equals(CanonicalPath(path2),
|
| | | StringComparison.InvariantCultureIgnoreCase));
|
| | | }
|
| | |
|
| | | public static bool PathIsRelativeTo(string path, string subPath)
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System.Collections.Generic;
|
| | | using System.Linq;
|
| | | using System.Windows.Forms;
|
| | | using EnvDTE;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | |
|
| | | namespace QtVsTools.Core.Legacy
|
| | | {
|
| | | using Core;
|
| | |
|
| | | public static class QtProject
|
| | | {
|
| | | public static void MarkAsDesignerPluginProject(Core.QtProject qtPro)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | qtPro.Project.Globals["IsDesignerPlugin"] = true.ToString();
|
| | | if (!qtPro.Project.Globals.get_VariablePersists("IsDesignerPlugin"))
|
| | | qtPro.Project.Globals.set_VariablePersists("IsDesignerPlugin", true);
|
| | | }
|
| | |
|
| | | public static bool PromptChangeQtVersion(Project project, string oldVersion, string newVersion)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var versionManager = Core.QtVersionManager.The();
|
| | | var viOld = versionManager.GetVersionInfo(oldVersion);
|
| | | var viNew = versionManager.GetVersionInfo(newVersion);
|
| | |
|
| | | if (viOld == null || viNew == null)
|
| | | return true;
|
| | |
|
| | | var oldIsWinRt = viOld.isWinRT();
|
| | | var newIsWinRt = viNew.isWinRT();
|
| | |
|
| | | if (newIsWinRt == oldIsWinRt || newIsWinRt == IsWinRT(project))
|
| | | return true;
|
| | |
|
| | | var caption = string.Format("Change Qt Version ({0})", project.Name);
|
| | | var text = string.Format(
|
| | | "Changing Qt version from {0} to {1}.\r\n" +
|
| | | "Project might not build. Are you sure?",
|
| | | newIsWinRt ? "Win32" : "WinRT",
|
| | | newIsWinRt ? "WinRT" : "Win32"
|
| | | );
|
| | |
|
| | | return MessageBox.Show(text, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Warning)
|
| | | == DialogResult.Yes;
|
| | | }
|
| | |
|
| | | public static bool HasModule(Project project, int id, string qtVersion = null)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var foundInIncludes = false;
|
| | | var foundInLibs = false;
|
| | |
|
| | | var vm = Core.QtVersionManager.The();
|
| | | var versionInfo = qtVersion != null ? vm.GetVersionInfo(qtVersion)
|
| | | : vm.GetVersionInfo(project);
|
| | | if (versionInfo == null)
|
| | | versionInfo = vm.GetVersionInfo(vm.GetDefaultVersion());
|
| | | if (versionInfo == null)
|
| | | return false; // neither a default or project Qt version
|
| | | var info = QtModules.Instance.Module(id, versionInfo.qtMajor);
|
| | | if (info == null)
|
| | | return false;
|
| | |
|
| | | var vcPro = project.Object as VCProject;
|
| | | foreach (VCConfiguration config in (IVCCollection)vcPro.Configurations) {
|
| | | var compiler = CompilerToolWrapper.Create(config);
|
| | | var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
|
| | |
|
| | | if (compiler != null) {
|
| | | if (compiler.GetAdditionalIncludeDirectories() == null)
|
| | | continue;
|
| | | var incPathList = info.GetIncludePath();
|
| | | var includeDirs = compiler.GetAdditionalIncludeDirectoriesList();
|
| | | foundInIncludes = (incPathList.Count > 0);
|
| | | foreach (var incPath in incPathList) {
|
| | | var fixedIncludeDir = FixFilePathForComparison(incPath);
|
| | | if (!includeDirs.Any(dir =>
|
| | | FixFilePathForComparison(dir) == fixedIncludeDir)) {
|
| | | foundInIncludes = false;
|
| | | break;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | if (foundInIncludes)
|
| | | break;
|
| | |
|
| | | List<string> libs = null;
|
| | | if (linker != null) {
|
| | | var linkerWrapper = new LinkerToolWrapper(linker);
|
| | | libs = linkerWrapper.AdditionalDependencies;
|
| | | }
|
| | |
|
| | | if (libs != null) {
|
| | | var moduleLibs = info.GetLibs(IsDebugConfiguration(config), versionInfo);
|
| | | foundInLibs = moduleLibs.All(moduleLib => libs.Contains(moduleLib));
|
| | | }
|
| | | }
|
| | | return foundInIncludes || foundInLibs;
|
| | | }
|
| | |
|
| | | public static void AddModule(Project project, int id)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (HasModule(project, id))
|
| | | return;
|
| | |
|
| | | var vm = Core.QtVersionManager.The();
|
| | | var versionInfo = vm.GetVersionInfo(project);
|
| | | if (versionInfo == null)
|
| | | versionInfo = vm.GetVersionInfo(vm.GetDefaultVersion());
|
| | |
|
| | | var vcPro = project.Object as VCProject;
|
| | | foreach (VCConfiguration config in vcPro.Configurations as IVCCollection) {
|
| | |
|
| | | var info = QtModules.Instance.Module(id, versionInfo.qtMajor);
|
| | | if (Core.QtProject.GetFormatVersion(project) >= Resources.qtMinFormatVersion_Settings) {
|
| | | var config3 = config as VCConfiguration3;
|
| | | if (config3 == null)
|
| | | continue;
|
| | | if (!string.IsNullOrEmpty(info.proVarQT)) {
|
| | | var qtModulesValue = config.GetUnevaluatedPropertyValue("QtModules");
|
| | | var qtModules = new HashSet<string>(
|
| | | !string.IsNullOrEmpty(qtModulesValue)
|
| | | ? qtModulesValue.Split(';')
|
| | | : new string[] { });
|
| | | qtModules.UnionWith(info.proVarQT.Split(' '));
|
| | | config3.SetPropertyValue(Resources.projLabelQtSettings, true,
|
| | | "QtModules", string.Join(";", qtModules));
|
| | | }
|
| | | // In V3 project format, compiler and linker options
|
| | | // required by modules are set by Qt/MSBuild.
|
| | | continue;
|
| | | }
|
| | |
|
| | | var compiler = CompilerToolWrapper.Create(config);
|
| | | var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
|
| | |
|
| | | if (compiler != null) {
|
| | | foreach (var define in info.Defines)
|
| | | compiler.AddPreprocessorDefinition(define);
|
| | |
|
| | | var incPathList = info.GetIncludePath();
|
| | | foreach (var incPath in incPathList)
|
| | | compiler.AddAdditionalIncludeDirectories(incPath);
|
| | | }
|
| | | if (linker != null) {
|
| | | var moduleLibs = info.GetLibs(IsDebugConfiguration(config), versionInfo);
|
| | | var linkerWrapper = new LinkerToolWrapper(linker);
|
| | | var additionalDeps = linkerWrapper.AdditionalDependencies;
|
| | | var dependenciesChanged = false;
|
| | | if (additionalDeps == null || additionalDeps.Count == 0) {
|
| | | additionalDeps = moduleLibs;
|
| | | dependenciesChanged = true;
|
| | | } else {
|
| | | foreach (var moduleLib in moduleLibs) {
|
| | | if (!additionalDeps.Contains(moduleLib)) {
|
| | | additionalDeps.Add(moduleLib);
|
| | | dependenciesChanged = true;
|
| | | }
|
| | | }
|
| | | }
|
| | | if (dependenciesChanged)
|
| | | linkerWrapper.AdditionalDependencies = additionalDeps;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | public static void RemoveModule(Project project, int id)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var vm = Core.QtVersionManager.The();
|
| | | var versionInfo = vm.GetVersionInfo(project);
|
| | | if (versionInfo == null)
|
| | | versionInfo = vm.GetVersionInfo(vm.GetDefaultVersion());
|
| | |
|
| | | var vcPro = project.Object as VCProject;
|
| | | foreach (VCConfiguration config in (IVCCollection)vcPro.Configurations) {
|
| | | var compiler = CompilerToolWrapper.Create(config);
|
| | | var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
|
| | |
|
| | | var info = QtModules.Instance.Module(id, versionInfo.qtMajor);
|
| | | if (compiler != null) {
|
| | | foreach (var define in info.Defines)
|
| | | compiler.RemovePreprocessorDefinition(define);
|
| | | var additionalIncludeDirs = compiler.AdditionalIncludeDirectories;
|
| | | if (additionalIncludeDirs != null) {
|
| | | var lst = new List<string>(additionalIncludeDirs);
|
| | | foreach (var includePath in info.IncludePath) {
|
| | | lst.Remove(includePath);
|
| | | lst.Remove('\"' + includePath + '\"');
|
| | | }
|
| | | compiler.AdditionalIncludeDirectories = lst;
|
| | | }
|
| | | }
|
| | | if (linker != null && linker.AdditionalDependencies != null) {
|
| | | var linkerWrapper = new LinkerToolWrapper(linker);
|
| | | var moduleLibs = info.GetLibs(IsDebugConfiguration(config), versionInfo);
|
| | | var additionalDependencies = linkerWrapper.AdditionalDependencies;
|
| | | var dependenciesChanged = false;
|
| | | foreach (var moduleLib in moduleLibs)
|
| | | dependenciesChanged |= additionalDependencies.Remove(moduleLib);
|
| | | if (dependenciesChanged)
|
| | | linkerWrapper.AdditionalDependencies = additionalDependencies;
|
| | | }
|
| | | }
|
| | | }
|
| | | |
| | | internal static bool IsDesignerPluginProject(Core.QtProject qtPro)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var b = false;
|
| | | if (qtPro.Project.Globals.get_VariablePersists("IsDesignerPlugin")) {
|
| | | var s = qtPro.Project.Globals["IsDesignerPlugin"] as string;
|
| | | try {
|
| | | b = bool.Parse(s);
|
| | | } catch { }
|
| | | }
|
| | | return b;
|
| | | }
|
| | |
|
| | |
|
| | | private static bool IsWinRT(Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | try {
|
| | | var vcProject = project.Object as VCProject;
|
| | | var vcConfigs = vcProject.Configurations as IVCCollection;
|
| | | var vcConfig = vcConfigs.Item(1) as VCConfiguration;
|
| | | var appType = vcConfig.GetEvaluatedPropertyValue("ApplicationType");
|
| | | if (appType == "Windows Store")
|
| | | return true;
|
| | | } catch { }
|
| | | return false;
|
| | | }
|
| | |
|
| | | private static string FixFilePathForComparison(string path)
|
| | | {
|
| | | return HelperFunctions.NormalizeRelativeFilePath(path).ToLower();
|
| | | }
|
| | |
|
| | | private static bool IsDebugConfiguration(VCConfiguration conf)
|
| | | {
|
| | | var tool = CompilerToolWrapper.Create(conf);
|
| | | if (tool != null) {
|
| | | return tool.RuntimeLibrary == runtimeLibraryOption.rtMultiThreadedDebug
|
| | | || tool.RuntimeLibrary == runtimeLibraryOption.rtMultiThreadedDebugDLL;
|
| | | }
|
| | | return false;
|
| | | }
|
| | | }
|
| | | }
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using QtVsTools.Common;
|
| | |
|
| | | namespace QtVsTools.Core.Legacy
|
| | | {
|
| | | public static class QtVSIPSettings
|
| | | {
|
| | | #region UIC
|
| | |
|
| | | public static string GetUicDirectory(EnvDTE.Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return QtVSIPSettingsShared.GetDirectory(project, Resources.uicDirKeyword);
|
| | | }
|
| | |
|
| | | public static void SaveUicDirectory(EnvDTE.Project project, string directory)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (directory == null)
|
| | | directory = QtVSIPSettingsShared.GetDirectory(project, Resources.uicDirKeyword);
|
| | | SaveDirectory(project, Resources.uicDirKeyword, directory);
|
| | | }
|
| | | #endregion
|
| | |
|
| | | #region MOC
|
| | |
|
| | | public static string GetMocDirectory(EnvDTE.Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return QtVSIPSettingsShared.GetDirectory(project, Resources.mocDirKeyword);
|
| | | }
|
| | |
|
| | | public static void SaveMocDirectory(EnvDTE.Project project, string directory)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (directory == null)
|
| | | directory = QtVSIPSettingsShared.GetDirectory(project, Resources.mocDirKeyword);
|
| | | SaveDirectory(project, Resources.mocDirKeyword, directory);
|
| | | }
|
| | |
|
| | | public static string GetMocOptions()
|
| | | {
|
| | | return QtVSIPSettingsShared.GetOption(Resources.mocOptionsKeyword);
|
| | | }
|
| | |
|
| | | public static string GetMocOptions(EnvDTE.Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return QtVSIPSettingsShared.GetOption(project, Resources.mocOptionsKeyword);
|
| | | }
|
| | |
|
| | | public static void SaveMocOptions(EnvDTE.Project project, string options)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (options == null)
|
| | | options = GetMocOptions();
|
| | |
|
| | | SaveOption(project, Resources.mocOptionsKeyword, options);
|
| | | }
|
| | | #endregion
|
| | |
|
| | | #region LUpdate
|
| | |
|
| | | public static bool GetLUpdateOnBuild(EnvDTE.Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (QtVSIPSettingsShared.GetProjectQtSetting(project, "QtRunLUpdateOnBuild") == "true")
|
| | | return true;
|
| | | return QtVSIPSettingsShared.GetBoolValue(project, Resources.lupdateKeyword);
|
| | | }
|
| | |
|
| | | public static void SaveLUpdateOnBuild(EnvDTE.Project project, bool value)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | SetBoolValue(project, Resources.lupdateKeyword, value);
|
| | | }
|
| | |
|
| | | public static string GetLUpdateOptions()
|
| | | {
|
| | | return QtVSIPSettingsShared.GetOption(Resources.lupdateOptionsKeyword);
|
| | | }
|
| | |
|
| | | public static string GetLUpdateOptions(EnvDTE.Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | string qtLUpdateOptions = QtVSIPSettingsShared.GetProjectQtSetting(project, "QtLUpdateOptions");
|
| | | if (!string.IsNullOrEmpty(qtLUpdateOptions))
|
| | | return qtLUpdateOptions;
|
| | | return QtVSIPSettingsShared.GetOption(project, Resources.lupdateOptionsKeyword);
|
| | | }
|
| | |
|
| | | public static void SaveLUpdateOptions(EnvDTE.Project project, string options)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (options == null)
|
| | | options = GetLUpdateOptions();
|
| | |
|
| | | SaveOption(project, Resources.lupdateOptionsKeyword, options);
|
| | | }
|
| | | #endregion
|
| | |
|
| | | #region LRelease
|
| | |
|
| | | public static string GetLReleaseOptions()
|
| | | {
|
| | | return QtVSIPSettingsShared.GetOption(Resources.lreleaseOptionsKeyword);
|
| | | }
|
| | |
|
| | | public static string GetLReleaseOptions(EnvDTE.Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | string qtLReleaseOptions = QtVSIPSettingsShared.GetProjectQtSetting(project, "QtLReleaseOptions");
|
| | | if (!string.IsNullOrEmpty(qtLReleaseOptions))
|
| | | return qtLReleaseOptions;
|
| | | return QtVSIPSettingsShared.GetOption(project, Resources.lreleaseOptionsKeyword);
|
| | | }
|
| | |
|
| | | public static void SaveLReleaseOptions(EnvDTE.Project project, string options)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (options == null)
|
| | | options = GetLReleaseOptions();
|
| | |
|
| | | SaveOption(project, Resources.lreleaseOptionsKeyword, options);
|
| | | }
|
| | | #endregion
|
| | |
|
| | | #region RCC
|
| | |
|
| | | public static string GetRccDirectory(EnvDTE.Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return QtVSIPSettingsShared.GetDirectory(project, Resources.rccDirKeyword);
|
| | | }
|
| | |
|
| | | public static void SaveRccDirectory(EnvDTE.Project project, string directory)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (directory == null)
|
| | | directory = QtVSIPSettingsShared.GetDirectory(project, Resources.rccDirKeyword);
|
| | | SaveDirectory(project, Resources.rccDirKeyword, directory);
|
| | | }
|
| | | #endregion
|
| | |
|
| | | #region QML
|
| | |
|
| | | public static bool GetQmlDebug(EnvDTE.Project project)
|
| | | {
|
| | | return Core.QtProject.Create(project).QmlDebug;
|
| | | }
|
| | |
|
| | | public static void SaveQmlDebug(EnvDTE.Project project, bool enabled)
|
| | | {
|
| | | Core.QtProject.Create(project).QmlDebug = enabled;
|
| | | }
|
| | | #endregion
|
| | |
|
| | | private static void SaveDirectory(EnvDTE.Project project, string type, string dir)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | dir = HelperFunctions.NormalizeRelativeFilePath(dir);
|
| | | project.Globals[type] = dir;
|
| | | if (!project.Globals.get_VariablePersists(type))
|
| | | project.Globals.set_VariablePersists(type, true);
|
| | |
|
| | | QtVSIPSettingsShared.CleanUpCache(project);
|
| | | }
|
| | |
|
| | | private static void SaveOption(EnvDTE.Project project, string type, string option)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | project.Globals[type] = option;
|
| | | if (!project.Globals.get_VariablePersists(type))
|
| | | project.Globals.set_VariablePersists(type, true);
|
| | | }
|
| | |
|
| | | private static void SetBoolValue(EnvDTE.Project project, string type, bool value)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | project.Globals[type] = Convert.ToInt32(value).ToString();
|
| | | if (!project.Globals.get_VariablePersists(type))
|
| | | project.Globals.set_VariablePersists(type, true);
|
| | | }
|
| | | }
|
| | | }
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using Microsoft.VisualStudio.Shell;
|
| | |
|
| | | namespace QtVsTools.Core.Legacy
|
| | | {
|
| | | public static class QtVersionManager
|
| | | {
|
| | | public static string GetSolutionQtVersion(EnvDTE.Solution solution)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (solution == null)
|
| | | return null;
|
| | |
|
| | | if (solution.Globals.get_VariableExists("Qt5Version")) {
|
| | | var version = (string)solution.Globals["Qt5Version"];
|
| | | return Core.QtVersionManager.The().VerifyIfQtVersionExists(version) ? version : null;
|
| | | }
|
| | |
|
| | | return null;
|
| | | }
|
| | |
|
| | | public static bool SaveSolutionQtVersion(EnvDTE.Solution solution, string version)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (!Core.QtVersionManager.The().IsVersionAvailable(version) && version != "$(DefaultQtVersion)")
|
| | | return false;
|
| | |
|
| | | solution.Globals["Qt5Version"] = version;
|
| | | if (!solution.Globals.get_VariablePersists("Qt5Version"))
|
| | | solution.Globals.set_VariablePersists("Qt5Version", true);
|
| | | return true;
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.IO;
|
| | | using System.Text.RegularExpressions;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | |
| | | /// </summary>
|
| | | public class LinkerToolWrapper
|
| | | {
|
| | | private VCLinkerTool linker;
|
| | | private readonly VCLinkerTool linker;
|
| | |
|
| | | public LinkerToolWrapper(VCLinkerTool linkerTool)
|
| | | {
|
| | |
| | |
|
| | | using System;
|
| | | using System.Windows.Forms;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | | public class MainWinWrapper : IWin32Window
|
| | | {
|
| | | private readonly EnvDTE.DTE dteObject;
|
| | | public IntPtr Handle { get; }
|
| | |
|
| | | public MainWinWrapper(EnvDTE.DTE dte)
|
| | | {
|
| | | dteObject = dte;
|
| | | }
|
| | |
|
| | | public IntPtr Handle
|
| | | {
|
| | | get
|
| | | {
|
| | | if (dteObject != null)
|
| | | #if VS2022
|
| | | return dteObject.MainWindow.HWnd;
|
| | | #else
|
| | | return new IntPtr(dteObject.MainWindow.HWnd);
|
| | | #endif
|
| | | return new IntPtr(0);
|
| | | }
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | Handle = new IntPtr((long)dte.MainWindow.HWnd);
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using EnvDTE;
|
| | | using System;
|
| | | using System.Collections.Concurrent;
|
| | | using System.Diagnostics;
|
| | | using System.Linq;
|
| | | using System.Threading;
|
| | | using Thread = System.Threading.Thread;
|
| | | using System.Windows.Forms;
|
| | | using System.Threading.Tasks;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Threading;
|
| | | using QtVsTools.VisualStudio;
|
| | |
|
| | | using Task = System.Threading.Tasks.Task;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | | using VisualStudio;
|
| | |
|
| | | public static class Messages
|
| | | {
|
| | | private static OutputWindow Window { get; set; }
|
| | | private static OutputWindowPane Pane { get; set; }
|
| | |
|
| | | private static OutputWindowPane _BuildPane;
|
| | | private static OutputWindowPane BuildPane
|
| | | {
|
| | | get
|
| | | {
|
| | | return _BuildPane ?? (_BuildPane = Window.OutputWindowPanes.Cast<OutputWindowPane>()
|
| | | .Where(pane => pane.Guid == "{1BD8A850-02D1-11D1-BEE7-00A0C913D1F8}")
|
| | | .FirstOrDefault());
|
| | | }
|
| | | }
|
| | | private static readonly string PaneName = "Qt VS Tools";
|
| | | private static readonly Guid PaneGuid = new Guid("8f6a1e44-fa0b-49e5-9934-1c050555350e");
|
| | |
|
| | | /// <summary>
|
| | | /// Show a message on the output pane.
|
| | |
| | | FlushMessages();
|
| | | }
|
| | |
|
| | | static void OutputWindowPane_Print(string text)
|
| | | public static void Log(this Exception exception, bool clear = false, bool activate = false)
|
| | | {
|
| | | OutputWindowPane_Init();
|
| | | Pane.OutputString(text + "\r\n");
|
| | | // show buildPane if a build is in progress
|
| | | if (Dte.Solution.SolutionBuild.BuildState == vsBuildState.vsBuildStateInProgress)
|
| | | BuildPane?.Activate();
|
| | | msgQueue.Enqueue(new Msg()
|
| | | {
|
| | | Clear = clear,
|
| | | Text = ExceptionToString(exception),
|
| | | Activate = activate
|
| | | });
|
| | | FlushMessages();
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | |
| | | FlushMessages();
|
| | | }
|
| | |
|
| | | static void OutputWindowPane_Activate()
|
| | | static async Task OutputWindowPane_ActivateAsync()
|
| | | {
|
| | | OutputWindowPane_Init();
|
| | | Pane?.Activate();
|
| | | await OutputWindowPane_InitAsync();
|
| | | await Pane?.ActivateAsync();
|
| | | }
|
| | |
|
| | | private static string ExceptionToString(System.Exception e)
|
| | | private static string ExceptionToString(System.Exception exception)
|
| | | {
|
| | | return e.Message + "\r\n" + "(" + e.StackTrace.Trim() + ")";
|
| | | return $"An exception ({exception.GetType().Name}) occurred.\r\n"
|
| | | + $"Message:\r\n {exception.Message}\r\n"
|
| | | + $"Stack Trace:\r\n {exception.StackTrace.Trim()}\r\n";
|
| | | }
|
| | |
|
| | | private static readonly string ErrorString = SR.GetString("Messages_ErrorOccured");
|
| | | private static readonly string WarningString = SR.GetString("Messages_Warning");
|
| | | private static readonly string SolutionString = SR.GetString("Messages_SolveProblem");
|
| | |
|
| | | static public void DisplayCriticalErrorMessage(System.Exception e)
|
| | | {
|
| | | MessageBox.Show(ErrorString +
|
| | | ExceptionToString(e),
|
| | | SR.GetString("Resources_QtVsTools"), MessageBoxButtons.OK, MessageBoxIcon.Error);
|
| | | }
|
| | |
|
| | | static public void DisplayCriticalErrorMessage(string msg)
|
| | | public static void DisplayCriticalErrorMessage(string msg)
|
| | | {
|
| | | MessageBox.Show(ErrorString +
|
| | | msg,
|
| | | SR.GetString("Resources_QtVsTools"), MessageBoxButtons.OK, MessageBoxIcon.Error);
|
| | | }
|
| | |
|
| | | static public void DisplayErrorMessage(System.Exception e)
|
| | | public static void DisplayErrorMessage(System.Exception e)
|
| | | {
|
| | | MessageBox.Show(ErrorString +
|
| | | ExceptionToString(e),
|
| | | MessageBox.Show(ExceptionToString(e),
|
| | | SR.GetString("Resources_QtVsTools"), MessageBoxButtons.OK, MessageBoxIcon.Error);
|
| | | }
|
| | |
|
| | | static public void DisplayErrorMessage(string msg)
|
| | | public static void DisplayErrorMessage(string msg)
|
| | | {
|
| | | MessageBox.Show(ErrorString +
|
| | | msg,
|
| | | SR.GetString("Resources_QtVsTools"), MessageBoxButtons.OK, MessageBoxIcon.Error);
|
| | | }
|
| | |
|
| | | static public void DisplayWarningMessage(System.Exception e, string solution)
|
| | | public static void DisplayWarningMessage(System.Exception e, string solution)
|
| | | {
|
| | | MessageBox.Show(WarningString +
|
| | | ExceptionToString(e) +
|
| | |
| | | SR.GetString("Resources_QtVsTools"), MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
| | | }
|
| | |
|
| | | static public void DisplayWarningMessage(string msg)
|
| | | public static void DisplayWarningMessage(string msg)
|
| | | {
|
| | | MessageBox.Show(WarningString +
|
| | | msg,
|
| | |
| | | FlushMessages();
|
| | | }
|
| | |
|
| | | static void OutputWindowPane_Clear()
|
| | | static async Task OutputWindowPane_ClearAsync()
|
| | | {
|
| | | OutputWindowPane_Init();
|
| | | Pane?.Clear();
|
| | | await OutputWindowPane_InitAsync();
|
| | | await Pane?.ClearAsync();
|
| | | }
|
| | |
|
| | | class Msg
|
| | |
| | | public bool Activate { get; set; } = false;
|
| | | }
|
| | |
|
| | | static bool shuttingDown = false;
|
| | | static ConcurrentQueue<Msg> msgQueue = new ConcurrentQueue<Msg>();
|
| | | static DTE Dte { get; set; } = null;
|
| | | static readonly ConcurrentQueue<Msg> msgQueue = new ConcurrentQueue<Msg>();
|
| | |
|
| | | private static void OnBeginShutdown()
|
| | | private static async Task OutputWindowPane_InitAsync()
|
| | | {
|
| | | shuttingDown = true;
|
| | | }
|
| | |
|
| | | private static void OutputWindowPane_Init()
|
| | | {
|
| | | if (Dte == null)
|
| | | Dte = VsServiceProvider.GetService<DTE>();
|
| | | var t = Stopwatch.StartNew();
|
| | | while (Pane == null && t.ElapsedMilliseconds < 5000) {
|
| | | try {
|
| | | Window = Dte.Windows.Item(Constants.vsWindowKindOutput).Object as OutputWindow;
|
| | | Pane = Window?.OutputWindowPanes.Add(SR.GetString("Resources_QtVsTools"));
|
| | | } catch {
|
| | | }
|
| | | try {
|
| | | if (Pane == null)
|
| | | Thread.Yield();
|
| | | Pane = await OutputWindowPane.CreateAsync(PaneName, PaneGuid);
|
| | | } catch (Exception ex) {
|
| | | System.Diagnostics.Debug.WriteLine(ex);
|
| | | }
|
| | | Dte.Events.DTEEvents.OnBeginShutdown += OnBeginShutdown;
|
| | | }
|
| | |
|
| | | public static JoinableTaskFactory JoinableTaskFactory { get; set; }
|
| | |
|
| | | static readonly object staticCriticalSection = new object();
|
| | | static Task FlushTask { get; set; }
|
| | | static EventWaitHandle MessageReady { get; set; }
|
| | |
| | | MessageReady = new EventWaitHandle(false, EventResetMode.AutoReset);
|
| | | FlushTask = Task.Run(async () =>
|
| | | {
|
| | | while (!shuttingDown) {
|
| | | var package = VsServiceProvider.Instance as Package;
|
| | | while (!package.Zombied) {
|
| | | if (!await MessageReady.ToTask(3000))
|
| | | continue;
|
| | | while (!msgQueue.IsEmpty) {
|
| | | Msg msg;
|
| | | if (!msgQueue.TryDequeue(out msg)) {
|
| | | if (!msgQueue.TryDequeue(out Msg msg)) {
|
| | | await Task.Yield();
|
| | | continue;
|
| | | }
|
| | | ////////////////////////////////////////////////////////////////////
|
| | | // Switch to main (UI) thread
|
| | | await JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | if (msg.Clear)
|
| | | OutputWindowPane_Clear();
|
| | | await OutputWindowPane_ClearAsync();
|
| | | if (msg.Text != null)
|
| | | OutputWindowPane_Print(msg.Text);
|
| | | await OutputWindowPane_PrintAsync(msg.Text);
|
| | | if (msg.Activate)
|
| | | OutputWindowPane_Activate();
|
| | | ////////////////////////////////////////////////////////////////////
|
| | | // Switch to background thread
|
| | | await TaskScheduler.Default;
|
| | | await OutputWindowPane_ActivateAsync();
|
| | | }
|
| | | }
|
| | | });
|
| | |
| | | }
|
| | | MessageReady.Set();
|
| | | }
|
| | |
|
| | | static async Task OutputWindowPane_PrintAsync(string text)
|
| | | {
|
| | | var active = await OutputWindowPane.GetActiveAsync();
|
| | |
|
| | | await OutputWindowPane_InitAsync();
|
| | | await Pane.PrintAsync(text);
|
| | |
|
| | | (active?.ActivateAsync()).Forget();
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | {
|
| | | class MocCmdChecker
|
| | | {
|
| | | private Regex backslashRegEx = new Regex(@"\\+\.?\\+");
|
| | | private Regex endRegEx = new Regex(@"\\\.?$");
|
| | | private readonly Regex backslashRegEx = new Regex(@"\\+\.?\\+");
|
| | | private readonly Regex endRegEx = new Regex(@"\\\.?$");
|
| | |
|
| | | private string NormalizePath(string path)
|
| | | {
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2017 The Qt Company Ltd.
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | |
| | | using System.IO;
|
| | | using System.Collections.Generic;
|
| | | using System.Text;
|
| | | using System.Text.RegularExpressions;
|
| | | using System.Linq;
|
| | | using System.Xml;
|
| | | using System.Xml.Linq;
|
| | | using QtVsTools.Core.QtMsBuild;
|
| | | using System.Text.RegularExpressions;
|
| | | using Microsoft.Build.Construction;
|
| | | using Microsoft.Build.Execution;
|
| | | using Microsoft.Build.Evaluation;
|
| | | using QtVsTools.VisualStudio;
|
| | | using QtVsTools.SyntaxAnalysis;
|
| | | using EnvDTE;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | | using QtMsBuild;
|
| | | using SyntaxAnalysis;
|
| | |
|
| | | using static HelperFunctions;
|
| | | using static RegExpr;
|
| | | using static SyntaxAnalysis.RegExpr;
|
| | |
|
| | | public class MsBuildProject
|
| | | {
|
| | |
| | | User,
|
| | | Count
|
| | | }
|
| | | MsBuildXmlFile[] files = new MsBuildXmlFile[(int)Files.Count];
|
| | |
|
| | | readonly MsBuildXmlFile[] files = new MsBuildXmlFile[(int)Files.Count];
|
| | |
|
| | | MsBuildProject()
|
| | | {
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | private static XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
|
| | | private static readonly XNamespace ns = "http://schemas.microsoft.com/developer/msbuild/2003";
|
| | |
|
| | | public static MsBuildProject Load(string pathToProject)
|
| | | {
|
| | |
| | | if (ConfigCondition == null)
|
| | | return false;
|
| | |
|
| | | // Get default Qt dir
|
| | | string defaultQtDir = null;
|
| | | var defaultVersionName = QtVersionManager.The().GetDefaultVersion();
|
| | | var defaultVersion = QtVersionManager.The().GetVersionInfo(defaultVersionName);
|
| | | if (defaultVersion != null)
|
| | | defaultQtDir = defaultVersion.qtDir;
|
| | |
|
| | | // Get project configurations
|
| | | var configs = this[Files.Project].xml
|
| | |
| | | .FirstOrDefault();
|
| | | if (globals == null)
|
| | | return false;
|
| | |
|
| | | // Get project configuration properties
|
| | | var configProps = this[Files.Project].xml
|
| | | .Elements(ns + "Project")
|
| | | .Elements(ns + "PropertyGroup")
|
| | | .Where(pg =>
|
| | | (string)pg.Attribute("Label") == "Configuration"
|
| | | && pg.Attribute("Condition") != null)
|
| | | .ToDictionary(pg => (string)pg.Attribute("Condition"));
|
| | |
|
| | | // Set Qt project format version
|
| | | var projKeyword = globals
|
| | |
| | | foreach (var pg in uncategorizedPropertyGroups) {
|
| | | foreach (var p in pg.Elements().ToList()) {
|
| | | var condition = p.Attribute("Condition") ?? pg.Attribute("Condition");
|
| | | XElement configPropertyGroup = null;
|
| | | if (condition != null)
|
| | | propertyGroups.TryGetValue((string)condition, out configPropertyGroup);
|
| | | if (configPropertyGroup != null) {
|
| | | if (condition != null && propertyGroups
|
| | | .TryGetValue((string)condition, out XElement configPropertyGroup)) {
|
| | | p.Remove();
|
| | | p.SetAttributeValue("Condition", null);
|
| | | configPropertyGroup.Add(p);
|
| | |
| | | foreach (var configQtSettings in qtSettings) {
|
| | | var configCondition = (string)configQtSettings.Attribute("Condition");
|
| | |
|
| | | XElement oldConfigQtInstall;
|
| | | if (oldQtInstall.TryGetValue(configCondition, out oldConfigQtInstall))
|
| | | if (oldQtInstall.TryGetValue(configCondition, out XElement oldConfigQtInstall))
|
| | | configQtSettings.Add(oldConfigQtInstall);
|
| | |
|
| | | XElement oldConfigQtSettings;
|
| | | if (oldQtSettings.TryGetValue(configCondition, out oldConfigQtSettings)) {
|
| | | if (oldQtSettings.TryGetValue(configCondition, out XElement oldConfigQtSettings)) {
|
| | | foreach (var qtSetting in oldConfigQtSettings.Elements())
|
| | | configQtSettings.Add(qtSetting);
|
| | | }
|
| | |
| | | .Elements(ns + "ItemDefinitionGroup")
|
| | | .Elements(ns + "Link");
|
| | |
|
| | | var resourceCompiler = this[Files.Project].xml
|
| | | .Elements(ns + "Project")
|
| | | .Elements(ns + "ItemDefinitionGroup")
|
| | | .Elements(ns + "ResourceCompile");
|
| | |
|
| | | // Qt module names, to copy to QtModules property
|
| | | var moduleNames = new HashSet<string>();
|
| | |
|
| | |
| | | var moduleLibs = new HashSet<string>();
|
| | |
|
| | | // Go through all known Qt modules and check which ones are currently being used
|
| | | foreach (var module in QtModules.Instance.GetAvailableModules()) {
|
| | | foreach (var module in QtModules.Instance.GetAvailableModules(defaultVersion.qtMajor)) {
|
| | |
|
| | | if (IsModuleUsed(module, compiler, linker)) {
|
| | | if (IsModuleUsed(module, compiler, linker, resourceCompiler)) {
|
| | |
|
| | | // Qt module names, to copy to QtModules property
|
| | | if (!string.IsNullOrEmpty(module.proVarQT))
|
| | |
| | | .Select(x => Unquote(x))
|
| | | // Exclude paths rooted on $(QTDIR)
|
| | | .Where(x => !x.StartsWith("$(QTDIR)", IGNORE_CASE))));
|
| | | }
|
| | |
|
| | | // Remove Qt module macros from resource compiler properties
|
| | | foreach (var defines in resourceCompiler.Elements(ns + "PreprocessorDefinitions")) {
|
| | | defines.SetValue(string.Join(";", defines.Value.Split(';')
|
| | | .Where(x => !moduleDefines.Contains(x))));
|
| | | }
|
| | |
|
| | | // Add Qt module names to QtModules project property
|
| | |
| | | bool IsModuleUsed(
|
| | | QtModule module,
|
| | | IEnumerable<XElement> compiler,
|
| | | IEnumerable<XElement> linker)
|
| | | IEnumerable<XElement> linker,
|
| | | IEnumerable<XElement> resourceCompiler)
|
| | | {
|
| | | // Module .lib is present in linker additional dependencies
|
| | | if (linker.Elements(ns + "AdditionalDependencies")
|
| | |
| | | return true;
|
| | | }
|
| | |
|
| | | // Module macro is present in pre-processor definitions
|
| | | // Module macro is present in the compiler pre-processor definitions
|
| | | if (compiler.Elements(ns + "PreprocessorDefinitions")
|
| | | .SelectMany(x => x.Value.Split(';'))
|
| | | .Any(x => module.Defines.Contains(x))) {
|
| | | return true;
|
| | | }
|
| | |
|
| | | // Module macro is present in resource compiler pre-processor definitions
|
| | | if (resourceCompiler.Elements(ns + "PreprocessorDefinitions")
|
| | | .SelectMany(x => x.Value.Split(';'))
|
| | | .Any(x => module.Defines.Contains(x))) {
|
| | | return true;
|
| | |
| | | commandLine = replace(row.itemName, commandLine);
|
| | | //
|
| | | // * Configuration/platform, e.g. x64\Debug --> $(Platform)\$(Configuration)
|
| | | commandLine = commandLine
|
| | | .Replace(configName, "$(Configuration)",
|
| | | StringComparison.InvariantCultureIgnoreCase)
|
| | | // * ignore any word other than the expected configuration, e.g. lrelease.exe
|
| | | commandLine = Regex.Replace(commandLine, @"\b" + configName + @"\b",
|
| | | "$(Configuration)", RegexOptions.IgnoreCase)
|
| | | .Replace(platformName, "$(Platform)",
|
| | | StringComparison.InvariantCultureIgnoreCase);
|
| | |
|
| | |
| | | evaluator.Properties.Add(configProp.Name.LocalName, (string)configProp);
|
| | | if (!qtMsBuild.SetCommandLine(itemType, item, commandLine, evaluator)) {
|
| | | int lineNumber = 1;
|
| | | var errorLine = row.command as IXmlLineInfo;
|
| | | if (errorLine != null && errorLine.HasLineInfo())
|
| | | if (row.command is IXmlLineInfo errorLine && errorLine.HasLineInfo())
|
| | | lineNumber = errorLine.LineNumber;
|
| | |
|
| | | Messages.Print(string.Format(
|
| | |
| | | return (string)cbt.Attribute("Include");
|
| | | }
|
| | | }
|
| | | string ouputFile;
|
| | | if (!properties.TryGetValue(QtMoc.Property.InputFile, out ouputFile))
|
| | | if (!properties.TryGetValue(QtMoc.Property.InputFile, out string ouputFile))
|
| | | return (string)cbt.Attribute("Include");
|
| | | return ouputFile;
|
| | | }
|
| | |
| | | Path.IsPathRooted(x) ? x : Path.Combine(projDir, x)));
|
| | | var outputItems = new List<XElement>();
|
| | | foreach (var outputFile in outputFiles) {
|
| | | List<XElement> mocOutput = null;
|
| | | if (projItemsByPath.TryGetValue(outputFile, out mocOutput)) {
|
| | | if (projItemsByPath.TryGetValue(outputFile, out List<XElement> mocOutput)) {
|
| | | outputItems.AddRange(mocOutput);
|
| | | hasGeneratedFiles |= hasGeneratedFiles ? true : mocOutput
|
| | | .Where(x => !x.Elements(ns + "ExcludedFromBuild")
|
| | |
| | |
|
| | | class MSBuildEvaluator : IVSMacroExpander, IDisposable
|
| | | {
|
| | | MsBuildXmlFile projFile;
|
| | | string tempProjFilePath;
|
| | | XElement evaluateTarget;
|
| | | XElement evaluateProperty;
|
| | | ProjectRootElement projRoot;
|
| | | public Dictionary<string, string> expansionCache;
|
| | | private readonly MsBuildXmlFile projFile;
|
| | | private string tempProjFilePath;
|
| | | private XElement evaluateTarget;
|
| | | private XElement evaluateProperty;
|
| | | private ProjectRootElement projRoot;
|
| | | private readonly Dictionary<string, string> expansionCache;
|
| | |
|
| | | public Dictionary<string, string> Properties
|
| | | {
|
| | | get;
|
| | | private set;
|
| | | }
|
| | |
|
| | | public MSBuildEvaluator(MsBuildXmlFile projFile)
|
| | |
| | |
|
| | | public string ExpandString(string stringToExpand)
|
| | | {
|
| | | string expandedString;
|
| | | if (TryExpansionCache(stringToExpand, out expandedString))
|
| | | if (TryExpansionCache(stringToExpand, out string expandedString))
|
| | | return expandedString;
|
| | |
|
| | | if (evaluateTarget == null) {
|
| | |
| | | return true;
|
| | | }
|
| | |
|
| | | static Regex ConditionParser =
|
| | | static readonly Regex ConditionParser =
|
| | | new Regex(@"\'\$\(Configuration[^\)]*\)\|\$\(Platform[^\)]*\)\'\=\=\'([^\']+)\'");
|
| | |
|
| | | class MsBuildConverterProvider : IPropertyStorageProvider
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Threading.Tasks;
|
| | | using Microsoft.VisualStudio;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | | using Microsoft.VisualStudio.Threading;
|
| | |
|
| | | using Task = System.Threading.Tasks.Task;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | | using VisualStudio;
|
| | |
|
| | | public class OutputWindowPane
|
| | | {
|
| | | public enum VSOutputWindowPane
|
| | | {
|
| | | General,
|
| | | Build,
|
| | | Debug,
|
| | | }
|
| | |
|
| | | public static Task<OutputWindowPane> GetVSOutputWindowPaneAsync(VSOutputWindowPane pane)
|
| | | {
|
| | | switch (pane) {
|
| | | case VSOutputWindowPane.General:
|
| | | return GetAsync(VSConstants.OutputWindowPaneGuid.GeneralPane_guid);
|
| | | case VSOutputWindowPane.Build:
|
| | | return GetAsync(VSConstants.OutputWindowPaneGuid.BuildOutputPane_guid);
|
| | | case VSOutputWindowPane.Debug:
|
| | | return GetAsync(VSConstants.OutputWindowPaneGuid.DebugPane_guid);
|
| | | default:
|
| | | throw new InvalidOperationException("Unsupported Visual Studio output pane");
|
| | | };
|
| | | }
|
| | |
|
| | | public static async Task<OutputWindowPane> GetAsync(Guid guid)
|
| | | {
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | try {
|
| | | IVsOutputWindow w = null;
|
| | | if (guid == VSConstants.OutputWindowPaneGuid.GeneralPane_guid) {
|
| | | w = await VsServiceProvider.GetServiceAsync<SVsGeneralOutputWindowPane,
|
| | | IVsOutputWindow>();
|
| | | } else {
|
| | | w = await VsServiceProvider.GetServiceAsync<SVsOutputWindow, IVsOutputWindow>();
|
| | | }
|
| | | ErrorHandler.ThrowOnFailure(w.GetPane(guid, out IVsOutputWindowPane pane));
|
| | |
|
| | | return new OutputWindowPane(guid, pane);
|
| | | } catch (Exception ex) {
|
| | | System.Diagnostics.Debug.WriteLine(ex);
|
| | | return null;
|
| | | }
|
| | | }
|
| | |
|
| | | public static async Task<OutputWindowPane> CreateAsync(string name, Guid guid)
|
| | | {
|
| | | if (string.IsNullOrEmpty(name))
|
| | | throw new ArgumentNullException($"{ nameof(name) } cannot be null");
|
| | |
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | try {
|
| | | var w = await VsServiceProvider.GetServiceAsync<SVsOutputWindow, IVsOutputWindow>();
|
| | |
|
| | | const int visible = 1, clear = 1;
|
| | | ErrorHandler.ThrowOnFailure(w.CreatePane(guid, name, visible, clear));
|
| | | ErrorHandler.ThrowOnFailure(w.GetPane(guid, out IVsOutputWindowPane pane));
|
| | |
|
| | | return new OutputWindowPane(guid, pane);
|
| | | } catch (Exception ex) {
|
| | | System.Diagnostics.Debug.WriteLine(ex);
|
| | | return null;
|
| | | }
|
| | | }
|
| | |
|
| | | public static async Task<OutputWindowPane> GetActiveAsync()
|
| | | {
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | try {
|
| | | var w2 = await VsServiceProvider
|
| | | .GetServiceAsync<SVsOutputWindow, IVsOutputWindow>() as IVsOutputWindow2;
|
| | | ErrorHandler.ThrowOnFailure(w2.GetActivePaneGUID(out Guid guid));
|
| | |
|
| | | IVsOutputWindow w = w2 as IVsOutputWindow;
|
| | | ErrorHandler.ThrowOnFailure(w.GetPane(guid, out IVsOutputWindowPane pane));
|
| | |
|
| | | return new OutputWindowPane(guid, pane);
|
| | | } catch (Exception ex) {
|
| | | System.Diagnostics.Debug.WriteLine(ex);
|
| | | return null;
|
| | | }
|
| | | }
|
| | |
|
| | | private Guid Guid { get; }
|
| | | private IVsOutputWindowPane Pane { get; set; } = null;
|
| | |
|
| | | private OutputWindowPane(Guid guid, IVsOutputWindowPane pane)
|
| | | {
|
| | | Guid = guid;
|
| | | Pane = pane;
|
| | | }
|
| | |
|
| | | public async Task ActivateAsync()
|
| | | {
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | if (Pane == null)
|
| | | throw new InvalidOperationException($"{ nameof(Pane) } cannot be null");
|
| | | Pane.Activate();
|
| | | }
|
| | |
|
| | | public async Task HideAsync()
|
| | | {
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | if (Pane == null)
|
| | | throw new InvalidOperationException($"{ nameof(Pane) } cannot be null");
|
| | | Pane.Hide();
|
| | | }
|
| | |
|
| | | public async Task ClearAsync()
|
| | | {
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | if (Pane == null)
|
| | | throw new InvalidOperationException($"{ nameof(Pane) } cannot be null");
|
| | | Pane.Clear();
|
| | | }
|
| | |
|
| | | public void Print()
|
| | | {
|
| | | ThreadHelper.JoinableTaskFactory.Run(async () => { await PrintAsync(""); });
|
| | | }
|
| | |
|
| | | public void Print(string value)
|
| | | {
|
| | | ThreadHelper.JoinableTaskFactory.Run(async () => { await PrintAsync(value); });
|
| | | }
|
| | |
|
| | | public Task PrintAsync()
|
| | | {
|
| | | return PrintAsync("");
|
| | | }
|
| | |
|
| | | public async Task PrintAsync(string value)
|
| | | {
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | if (Pane is IVsOutputWindowPaneNoPump noPumpPane)
|
| | | noPumpPane.OutputStringNoPump(value + Environment.NewLine);
|
| | | else
|
| | | ErrorHandler.ThrowOnFailure(Pane.OutputStringThreadSafe(value + Environment.NewLine));
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | {
|
| | | public ProFileContent(VCProject proj)
|
| | | {
|
| | | export = true;
|
| | | vcproj = proj;
|
| | | options = new List<ProFileOption>();
|
| | | Export = true;
|
| | | Project = proj;
|
| | | Options = new List<ProFileOption>();
|
| | | }
|
| | |
|
| | | public override string ToString()
|
| | | {
|
| | | return vcproj.Name;
|
| | | return Project.Name;
|
| | | }
|
| | |
|
| | | public VCProject Project
|
| | | {
|
| | | get
|
| | | {
|
| | | return vcproj;
|
| | | }
|
| | | }
|
| | | public VCProject Project { get; }
|
| | |
|
| | | public bool Export
|
| | | {
|
| | | get
|
| | | {
|
| | | return export;
|
| | | }
|
| | | set
|
| | | {
|
| | | export = value;
|
| | | }
|
| | | }
|
| | | public bool Export { get; set; }
|
| | |
|
| | | public List<ProFileOption> Options
|
| | | {
|
| | | get
|
| | | {
|
| | | return options;
|
| | | }
|
| | | }
|
| | |
|
| | | private VCProject vcproj;
|
| | | private bool export;
|
| | | private List<ProFileOption> options;
|
| | | public List<ProFileOption> Options { get; }
|
| | | }
|
| | | }
|
| | |
| | | {
|
| | | public ProFileOption(string optname)
|
| | | {
|
| | | name = optname;
|
| | | astype = AssignType.AT_PlusEquals;
|
| | | comment = null;
|
| | | shortComment = "Default";
|
| | | incComment = false;
|
| | | newOpt = " \\\r\n ";
|
| | | list = new List<string>();
|
| | | Name = optname;
|
| | | AssignSymbol = AssignType.AT_PlusEquals;
|
| | | Comment = null;
|
| | | ShortComment = "Default";
|
| | | IncludeComment = false;
|
| | | NewOption = " \\\r\n ";
|
| | | List = new List<string>();
|
| | | }
|
| | |
|
| | | public override string ToString()
|
| | | {
|
| | | return shortComment;
|
| | | return ShortComment;
|
| | | }
|
| | |
|
| | | public string Comment
|
| | | {
|
| | | get
|
| | | {
|
| | | return comment;
|
| | | }
|
| | | set
|
| | | {
|
| | | comment = value;
|
| | | }
|
| | | }
|
| | | public string Comment { get; set; }
|
| | |
|
| | | public string ShortComment
|
| | | {
|
| | | get
|
| | | {
|
| | | return shortComment;
|
| | | }
|
| | | set
|
| | | {
|
| | | shortComment = value;
|
| | | }
|
| | | }
|
| | | public string ShortComment { get; set; }
|
| | |
|
| | | public AssignType AssignSymbol
|
| | | {
|
| | | get
|
| | | {
|
| | | return astype;
|
| | | }
|
| | | set
|
| | | {
|
| | | astype = value;
|
| | | }
|
| | | }
|
| | | public AssignType AssignSymbol { get; set; }
|
| | |
|
| | | public string NewOption
|
| | | {
|
| | | get
|
| | | {
|
| | | return newOpt;
|
| | | }
|
| | | set
|
| | | {
|
| | | newOpt = value;
|
| | | }
|
| | | }
|
| | | public string NewOption { get; set; }
|
| | |
|
| | | public string Name
|
| | | {
|
| | | get
|
| | | {
|
| | | return name;
|
| | | }
|
| | | }
|
| | | public string Name { get; }
|
| | |
|
| | | public List<string> List
|
| | | {
|
| | | get
|
| | | {
|
| | | return list;
|
| | | }
|
| | | }
|
| | | public List<string> List { get; }
|
| | |
|
| | | public bool IncludeComment
|
| | | {
|
| | | get
|
| | | {
|
| | | return incComment;
|
| | | }
|
| | | set
|
| | | {
|
| | | incComment = value;
|
| | | }
|
| | | }
|
| | | public bool IncludeComment { get; set; }
|
| | |
|
| | | public enum AssignType
|
| | | {
|
| | |
| | | AT_MinusEquals = 3,
|
| | | AT_Function = 4
|
| | | }
|
| | |
|
| | | private AssignType astype;
|
| | | private string shortComment;
|
| | | private bool incComment;
|
| | | private string comment;
|
| | | private string newOpt;
|
| | | private string name;
|
| | | private List<string> list;
|
| | | }
|
| | | }
|
| | |
| | | {
|
| | | public ProSolution(Solution sln)
|
| | | {
|
| | | prosln = sln;
|
| | | proFiles = new List<ProFileContent>();
|
| | | ProjectSolution = sln;
|
| | | ProFiles = new List<ProFileContent>();
|
| | | }
|
| | |
|
| | | public List<ProFileContent> ProFiles
|
| | | {
|
| | | get
|
| | | {
|
| | | return proFiles;
|
| | | }
|
| | | }
|
| | | public List<ProFileContent> ProFiles { get; }
|
| | |
|
| | | public Solution ProjectSolution
|
| | | {
|
| | | get
|
| | | {
|
| | | return prosln;
|
| | | }
|
| | | }
|
| | |
|
| | | private List<ProFileContent> proFiles;
|
| | | private Solution prosln;
|
| | | public Solution ProjectSolution { get; }
|
| | | }
|
| | | }
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using EnvDTE;
|
| | | using EnvDTE80;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using System;
|
| | | using System.Collections;
|
| | | using System.Collections.Generic;
|
| | | using System.IO;
|
| | | using System.Text.RegularExpressions;
|
| | | using System.Windows.Forms;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using EnvDTE;
|
| | | using EnvDTE80;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | |
| | | /// </summary>
|
| | | public class ProjectExporter
|
| | | {
|
| | | private DTE dteObject;
|
| | | private readonly DTE dteObject;
|
| | |
|
| | | public ProjectExporter(DTE dte)
|
| | | {
|
| | |
| | |
|
| | | private ProSolution CreateProFileSolution(Solution sln)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | ProFileContent content;
|
| | | var prosln = new ProSolution(sln);
|
| | |
|
| | | foreach (var proj in HelperFunctions.ProjectsInSolution(sln.DTE)) {
|
| | | try {
|
| | | // only add qt projects
|
| | | if (HelperFunctions.IsQtProject(proj)) {
|
| | | if (HelperFunctions.IsVsToolsProject(proj)) {
|
| | | content = CreateProFileContent(proj);
|
| | | prosln.ProFiles.Add(content);
|
| | | } else if (proj.Kind == ProjectKinds.vsProjectKindSolutionFolder) {
|
| | |
| | |
|
| | | private void addProjectsInFolder(Project solutionFolder, ProSolution sln)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | foreach (ProjectItem pi in solutionFolder.ProjectItems) {
|
| | | var containedProject = pi.Object as Project;
|
| | | if (HelperFunctions.IsQtProject(containedProject)) {
|
| | | if (HelperFunctions.IsVsToolsProject(containedProject)) {
|
| | | var content = CreateProFileContent(containedProject);
|
| | | sln.ProFiles.Add(content);
|
| | | } else if (containedProject.Kind == ProjectKinds.vsProjectKindSolutionFolder) {
|
| | |
| | |
|
| | | private static ProFileContent CreateProFileContent(Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | ProFileOption option;
|
| | | var qtPro = QtProject.Create(project);
|
| | | var content = new ProFileContent(qtPro.VCProject);
|
| | |
| | | if (config.ConfigurationType == ConfigurationTypes.typeStaticLibrary)
|
| | | option.List.Add("staticlib");
|
| | | if (linker != null) {
|
| | | var linkerRule = linker as IVCRulePropertyStorage;
|
| | | var generateDebugInformation = (linkerRule != null) ?
|
| | | var generateDebugInformation = (linker is IVCRulePropertyStorage linkerRule) ?
|
| | | linkerRule.GetUnevaluatedPropertyValue("GenerateDebugInformation") : null;
|
| | | if (generateDebugInformation != "false")
|
| | | option.List.Add("debug");
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | if (qtPro.IsDesignerPluginProject()) {
|
| | | option.List.Add("designer");
|
| | | var legacyDesigner = Legacy.QtProject.IsDesignerPluginProject(qtPro);
|
| | | var plugin = legacyDesigner | Core.QtProject.IsQtPlugin(qtPro);
|
| | | if (plugin)
|
| | | option.List.Add("plugin");
|
| | | }
|
| | | if (legacyDesigner)
|
| | | option.List.Add("designer");
|
| | |
|
| | | // add defines
|
| | | option = new ProFileOption("DEFINES");
|
| | |
| | | option.List.Add(project.Name + ".rc");
|
| | | }
|
| | |
|
| | | if (qtPro.IsDesignerPluginProject()) {
|
| | | if (plugin) {
|
| | | option = new ProFileOption("target.path");
|
| | | option.ShortComment = "Install the plugin in the designer plugins directory.";
|
| | | if (legacyDesigner)
|
| | | option.ShortComment = "Installs the plugin in the designer plugins directory.";
|
| | | else
|
| | | option.ShortComment = "Installs the plugin in the plugins directory.";
|
| | | option.IncludeComment = true;
|
| | | option.AssignSymbol = ProFileOption.AssignType.AT_Equals;
|
| | | option.List.Add("$$[QT_INSTALL_PLUGINS]/designer");
|
| | | if (legacyDesigner)
|
| | | option.List.Add("$$[QT_INSTALL_PLUGINS]/designer");
|
| | | else
|
| | | option.List.Add("$$[QT_INSTALL_PLUGINS]");
|
| | | content.Options.Add(option);
|
| | |
|
| | | option = new ProFileOption("INSTALLS");
|
| | |
| | |
|
| | | private static ProFileContent CreatePriFileContent(Project project, string priFileDirectory)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | ProFileOption option;
|
| | | var qtPro = QtProject.Create(project);
|
| | | var content = new ProFileContent(qtPro.VCProject);
|
| | |
| | |
|
| | | private static void AddIncludePaths(Project project, ProFileOption option, string includePaths)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (QtProject.GetFormatVersion(project) >= Resources.qtMinFormatVersion_ClProperties)
|
| | | return;
|
| | |
|
| | |
| | | if (!d.StartsWith("$(qtdir)\\include", StringComparison.OrdinalIgnoreCase) &&
|
| | | !d.StartsWith(qtDir + "\\include", StringComparison.OrdinalIgnoreCase) &&
|
| | | !d.EndsWith("win32-msvc2005", StringComparison.OrdinalIgnoreCase)) {
|
| | |
|
| | | var vcConfig = project.ConfigurationManager.ActiveConfiguration.Object
|
| | | as VCConfiguration;
|
| | | if (vcConfig != null)
|
| | | if (project.ConfigurationManager.ActiveConfiguration.Object is VCConfiguration vcConfig)
|
| | | HelperFunctions.ExpandString(ref d, vcConfig);
|
| | | if (HelperFunctions.IsAbsoluteFilePath(d))
|
| | | d = HelperFunctions.GetRelativePath(project.FullName, d);
|
| | |
| | | qtDir = Environment.GetEnvironmentVariable("QTDIR");
|
| | | if (qtDir == null)
|
| | | qtDir = "";
|
| | |
|
| | | qtDir = HelperFunctions.NormalizeRelativeFilePath(qtDir);
|
| | |
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (paths != null) {
|
| | | foreach (var s in paths.Split(';', ',')) {
|
| | |
| | |
|
| | | private static void AddModules(QtProject qtPrj, ProFileOption optionQT, ProFileOption optionCONFIG)
|
| | | {
|
| | | foreach (var module in QtModules.Instance.GetAvailableModules()) {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var vm = QtVersionManager.The();
|
| | | var versionInfo = vm.GetVersionInfo(qtPrj.Project);
|
| | | if (versionInfo == null)
|
| | | versionInfo = vm.GetVersionInfo(vm.GetDefaultVersion());
|
| | |
|
| | | foreach (var module in QtModules.Instance.GetAvailableModules(versionInfo.qtMajor)) {
|
| | | if (!qtPrj.HasModule(module.Id))
|
| | | continue;
|
| | |
|
| | |
| | |
|
| | | private void WriteProSolution(ProSolution prosln, bool openFile)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var sln = prosln.ProjectSolution;
|
| | | if (string.IsNullOrEmpty(sln.FileName))
|
| | | return;
|
| | |
| | |
|
| | | private void WriteProFile(ProFileContent content, string proFile, string priFileToInclude, bool openFile)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | StreamWriter sw;
|
| | | if (File.Exists(proFile)) {
|
| | | if (MessageBox.Show(SR.GetString("ExportProject_ExistsOverwriteQuestion", proFile),
|
| | |
| | | WriteProFileOptions(sw, content.Options);
|
| | | }
|
| | |
|
| | | // open the file in vs
|
| | | if (openFile)
|
| | | if (openFile) // open the file in vs
|
| | | dteObject.OpenFile(Constants.vsViewKindTextView, proFile).Activate();
|
| | | }
|
| | |
|
| | |
| | | public static void SyncIncludeFiles(VCProject vcproj, List<string> priFiles,
|
| | | List<string> projFiles, DTE dte, bool flat, FakeFilter fakeFilter)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var cmpPriFiles = new List<string>(priFiles.Count);
|
| | | foreach (var s in priFiles)
|
| | | cmpPriFiles.Add(HelperFunctions.NormalizeFilePath(s).ToLower());
|
| | |
| | |
|
| | | public void ExportToProFile()
|
| | | {
|
| | | var expDlg = new ExportProjectDialog();
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var sln = dteObject.Solution;
|
| | | var prosln = CreateProFileSolution(sln);
|
| | |
| | | return;
|
| | | }
|
| | |
|
| | | var expDlg = new ExportProjectDialog();
|
| | | expDlg.ProFileSolution = prosln;
|
| | | expDlg.StartPosition = FormStartPosition.CenterParent;
|
| | | var ww = new MainWinWrapper(dteObject);
|
| | |
| | |
|
| | | public string ExportToPriFile(Project proj)
|
| | | {
|
| | | VCProject vcproj;
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (HelperFunctions.IsQtProject(proj)) {
|
| | | VCProject vcproj;
|
| | | if (HelperFunctions.IsVsToolsProject(proj)) {
|
| | | try {
|
| | | vcproj = (VCProject)proj.Object;
|
| | | } catch (Exception e) {
|
| | |
| | |
|
| | | public void ExportToPriFile(Project proj, string fileName)
|
| | | {
|
| | | var priFile = new FileInfo(fileName);
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var priFile = new FileInfo(fileName);
|
| | | var content = CreatePriFileContent(proj, priFile.DirectoryName);
|
| | | WritePriFile(content, priFile.FullName);
|
| | | }
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using EnvDTE;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.IO;
|
| | | using System.Windows.Forms;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using EnvDTE;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | | public class ProjectImporter
|
| | | {
|
| | | private DTE dteObject;
|
| | | private readonly DTE dteObject;
|
| | | const string projectFileExtension = ".vcxproj";
|
| | |
|
| | | public ProjectImporter(DTE dte)
|
| | |
| | |
|
| | | public void ImportProFile(string qtVersion)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | FileDialog toOpen = new OpenFileDialog();
|
| | | toOpen.FilterIndex = 1;
|
| | | toOpen.CheckFileExists = true;
|
| | |
| | |
|
| | | private void ImportSolution(FileInfo mainInfo, string qtVersion)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var versionInfo = QtVersionManager.The().GetVersionInfo(qtVersion);
|
| | | var VCInfo = RunQmake(mainInfo, ".sln", true, versionInfo);
|
| | | if (null == VCInfo)
|
| | |
| | | if (CheckQtVersion(versionInfo)) {
|
| | | dteObject.Solution.Open(VCInfo.FullName);
|
| | | if (qtVersion != null) {
|
| | | QtVersionManager.The().SaveSolutionQtVersion(dteObject.Solution, qtVersion);
|
| | | Legacy.QtVersionManager.SaveSolutionQtVersion(dteObject.Solution, qtVersion);
|
| | | foreach (var prj in HelperFunctions.ProjectsInSolution(dteObject)) {
|
| | | QtVersionManager.The().SaveProjectQtVersion(prj, qtVersion);
|
| | | var qtPro = QtProject.Create(prj);
|
| | |
| | |
|
| | | Messages.Print("--- (Import): Finished opening " + VCInfo.Name);
|
| | | } catch (Exception e) {
|
| | | Messages.DisplayCriticalErrorMessage(e);
|
| | | Messages.DisplayErrorMessage(e);
|
| | | }
|
| | | }
|
| | |
|
| | | public void ImportProject(FileInfo mainInfo, string qtVersion)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var versionInfo = QtVersionManager.The().GetVersionInfo(qtVersion);
|
| | | var VCInfo = RunQmake(mainInfo, projectFileExtension, false, versionInfo);
|
| | | if (null == VCInfo)
|
| | |
| | | try {
|
| | | if (CheckQtVersion(versionInfo)) {
|
| | | // no need to add the project again if it's already there...
|
| | | if (!HelperFunctions.IsProjectInSolution(dteObject, VCInfo.FullName)) {
|
| | | var fullName = VCInfo.FullName;
|
| | | var pro = HelperFunctions.ProjectFromSolution(dteObject, fullName);
|
| | | if (pro == null) {
|
| | | try {
|
| | | dteObject.Solution.AddFromFile(VCInfo.FullName, false);
|
| | | pro = dteObject.Solution.AddFromFile(fullName, false);
|
| | | } catch (Exception /*exception*/) {
|
| | | Messages.Print("--- (Import): Generated project could not be loaded.");
|
| | | Messages.Print("--- (Import): Please look in the output above for errors and warnings.");
|
| | |
| | | Messages.Print("Project already in Solution");
|
| | | }
|
| | |
|
| | | Project pro = null;
|
| | | foreach (var p in HelperFunctions.ProjectsInSolution(dteObject)) {
|
| | | if (p.FullName.ToLower() == VCInfo.FullName.ToLower()) {
|
| | | pro = p;
|
| | | break;
|
| | | }
|
| | | }
|
| | | if (pro != null) {
|
| | | var qtPro = QtProject.Create(pro);
|
| | | qtPro.SetQtEnvironment();
|
| | |
| | | Messages.Print("Can't select the platform " + platformName + ".");
|
| | | }
|
| | |
|
| | | // try to figure out if the project is a plugin project
|
| | | try {
|
| | | var activeConfig = pro.ConfigurationManager.ActiveConfiguration.ConfigurationName;
|
| | | var config = (VCConfiguration)((IVCCollection)qtPro.VCProject.Configurations).Item(activeConfig);
|
| | | if (config.ConfigurationType == ConfigurationTypes.typeDynamicLibrary) {
|
| | | var compiler = CompilerToolWrapper.Create(config);
|
| | | var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
|
| | | if (compiler.GetPreprocessorDefinitions().IndexOf("QT_PLUGIN", StringComparison.Ordinal) > -1
|
| | | && compiler.GetPreprocessorDefinitions().IndexOf("QDESIGNER_EXPORT_WIDGETS", StringComparison.Ordinal) > -1
|
| | | && compiler.GetAdditionalIncludeDirectories().IndexOf("QtDesigner", StringComparison.Ordinal) > -1
|
| | | && linker.AdditionalDependencies.IndexOf("QtDesigner", StringComparison.Ordinal) > -1) {
|
| | | qtPro.MarkAsDesignerPluginProject();
|
| | | }
|
| | | }
|
| | | } catch (Exception) { }
|
| | | // figure out if the imported project is a plugin project
|
| | | var tmp = qtPro.Project.ConfigurationManager.ActiveConfiguration
|
| | | .ConfigurationName;
|
| | | var vcConfig = (qtPro.VCProject.Configurations as IVCCollection).Item(tmp)
|
| | | as VCConfiguration;
|
| | | var def = CompilerToolWrapper.Create(vcConfig)?.GetPreprocessorDefinitions();
|
| | | if (!string.IsNullOrEmpty(def)
|
| | | && def.IndexOf("QT_PLUGIN", StringComparison.Ordinal) > -1) {
|
| | | QtProject.MarkAsQtPlugin(qtPro);
|
| | | }
|
| | |
|
| | | qtPro.SetQtEnvironment();
|
| | | ApplyPostImportSteps(qtPro);
|
| | |
| | | if (ok)
|
| | | ok = xmlProject.UpdateProjectFormatVersion();
|
| | |
|
| | | if (!ok) {
|
| | | Messages.Print(
|
| | | SR.GetString("ImportProject_CannotConvertProject", projectFile.Name));
|
| | | if (ok) {
|
| | | xmlProject.Save();
|
| | | // Initialize Qt variables
|
| | | xmlProject.BuildTarget("QtVarsDesignTime");
|
| | | } else {
|
| | | Messages.Print($"Could not convert project file {projectFile.Name} to Qt/MSBuild.");
|
| | | }
|
| | | xmlProject.Save();
|
| | |
|
| | | // Initialize Qt variables
|
| | | xmlProject.BuildTarget("QtVarsDesignTime");
|
| | | }
|
| | |
|
| | | private static void ApplyPostImportSteps(QtProject qtProject)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | qtProject.RemoveResFilesFromGeneratedFilesFilter();
|
| | | qtProject.TranslateFilterNames();
|
| | |
|
| | |
| | |
|
| | | private FileInfo RunQmake(FileInfo mainInfo, string ext, bool recursive, VersionInformation vi)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var name = mainInfo.Name.Remove(mainInfo.Name.IndexOf('.'));
|
| | |
|
| | | var VCInfo = new FileInfo(mainInfo.DirectoryName + "\\" + name + ext);
|
| | |
|
| | | if (!VCInfo.Exists || DialogResult.Yes == MessageBox.Show(SR.GetString("ExportProject_ProjectExistsRegenerateOrReuse", VCInfo.Name),
|
| | | SR.GetString("ProjectExists"), MessageBoxButtons.YesNo, MessageBoxIcon.Question)) {
|
| | | Messages.Print("--- (Import): Generating new project of " + mainInfo.Name + " file");
|
| | |
|
| | | var waitDialog = WaitDialog.Start(
|
| | | "Open Qt Project File",
|
| | | "Generating Visual Studio project...", delay: 2);
|
| | |
|
| | | var qmake = new QMakeImport(vi, mainInfo.FullName, recursive, dteObject);
|
| | | int exitCode = qmake.Run(setVCVars: true);
|
| | | waitDialog.Stop();
|
| | |
|
| | | if (exitCode == 0)
|
| | | return VCInfo;
|
| | | var vcxproj = new FileInfo(mainInfo.DirectoryName + "\\" + name + ext);
|
| | | if (vcxproj.Exists) {
|
| | | var result = MessageBox.Show($@"{vcxproj.Name} already exists. Select 'OK' to " +
|
| | | "regenerate the file or 'Cancel' to quit importing the project.",
|
| | | "Project file already exists.",
|
| | | MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
|
| | | if (result == DialogResult.Cancel)
|
| | | return null;
|
| | | }
|
| | |
|
| | | Messages.Print("--- (Import): Generating new project of " + mainInfo.Name + " file");
|
| | |
|
| | | var waitDialog = WaitDialog.Start("Open Qt Project File",
|
| | | "Generating Visual Studio project...", delay: 2);
|
| | |
|
| | | var qmake = new QMakeImport(vi, mainInfo.FullName, recursive, dteObject);
|
| | | int exitCode = qmake.Run(setVCVars: true);
|
| | |
|
| | | waitDialog.Stop();
|
| | |
|
| | | if (exitCode == 0)
|
| | | return vcxproj;
|
| | | return null;
|
| | | }
|
| | |
|
| | | private static bool CheckQtVersion(VersionInformation vi)
|
| | | {
|
| | | if (!vi.qt5Version) {
|
| | | if (vi.qtMajor < 5) {
|
| | | Messages.DisplayWarningMessage(SR.GetString("ExportProject_EditProjectFileManually"));
|
| | | return false;
|
| | | }
|
| | |
| | | using System.IO;
|
| | | using System.Linq;
|
| | | using System.Text;
|
| | | using QtVsTools.VisualStudio;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | | using VisualStudio;
|
| | |
|
| | | public abstract class QMake
|
| | | {
|
| | | public Dictionary<string, string> Vars { get; protected set; }
|
| | | public string OutputFile { get; protected set; }
|
| | | public uint DebugLevel { get; protected set; }
|
| | | private uint DebugLevel { get; set; }
|
| | | public string TemplatePrefix { get; protected set; }
|
| | | public bool Recursive { get; protected set; }
|
| | | public string ProFile { get; protected set; }
|
| | | public string Query { get; protected set; }
|
| | | public bool DisableWarnings { get; set; }
|
| | |
|
| | | protected VersionInformation QtVersion { get; private set; }
|
| | | protected EnvDTE.DTE Dte { get; private set; }
|
| | | protected VersionInformation QtVersion { get; }
|
| | | private EnvDTE.DTE Dte { get; }
|
| | |
|
| | | public QMake(VersionInformation qtVersion, EnvDTE.DTE dte = null)
|
| | | {
|
| | |
| | | exitCode = qmakeProc.ExitCode;
|
| | | InfoExit(qmakeProc);
|
| | | }
|
| | | } catch (Exception e) {
|
| | | ErrMsg(string.Format("Exception \"{0}\":\r\n{1}",
|
| | | e.Message,
|
| | | e.StackTrace));
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | }
|
| | | }
|
| | | return exitCode;
|
| | | }
|
| | |
|
| | | public static bool Exists(string path)
|
| | | {
|
| | | var possibleQMakePaths = new[] {
|
| | | // Path points to qmake.exe
|
| | | path,
|
| | | // Path points to folder containing qmake.exe
|
| | | Path.Combine(path, "qmake.exe"),
|
| | | // Path points to folder containing bin\qmake.exe
|
| | | Path.Combine(path, "bin", "qmake.exe"),
|
| | | };
|
| | | return possibleQMakePaths.Where(p => File.Exists(p)
|
| | | && Path.GetFileName(p).Equals("qmake.exe", StringComparison.OrdinalIgnoreCase))
|
| | | .Any();
|
| | | }
|
| | | }
|
| | |
|
| | | public class QMakeImport : QMake
|
| | |
| | | using System;
|
| | | using System.Collections;
|
| | | using System.IO;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | | public class QMakeConf
|
| | | {
|
| | | public Hashtable Entries { get; private set; }
|
| | | public string QMakeSpecDirectory { get; private set; }
|
| | | public Hashtable Entries { get; }
|
| | | public string QMakeSpecDirectory { get; }
|
| | |
|
| | | public QMakeConf(VersionInformation versionInfo, QMakeQuery qmakeQuery = null)
|
| | | {
|
| | |
| | |
|
| | | qmakeConf = Path.Combine(qtPrefix, qtArchData, "mkspecs", qmakeXSpec, "qmake.conf");
|
| | |
|
| | | if (!File.Exists(qmakeConf)) {
|
| | | // Check if this is a shadow build of Qt.
|
| | | qtPrefix = qmakeQuery["QT_INSTALL_PREFIX/src"];
|
| | | if (string.IsNullOrEmpty(qtPrefix))
|
| | | throw new QtVSException("qmake error: no value for QT_INSTALL_PREFIX/src");
|
| | | qtArchData = qmakeQuery["QT_INSTALL_ARCHDATA/src"];
|
| | | if (string.IsNullOrEmpty(qtArchData))
|
| | | throw new QtVSException("qmake error: no value for QT_INSTALL_ARCHDATA/src");
|
| | |
|
| | | qmakeConf = Path.Combine(qtPrefix, qtArchData, "mkspecs", qmakeXSpec, "qmake.conf");
|
| | | }
|
| | | if (!File.Exists(qmakeConf))
|
| | | throw new QtVSException("qmake.conf expected at " + qmakeConf + " not found");
|
| | | }
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.Diagnostics;
|
| | | using System.IO;
|
| | | using System.Linq;
|
| | | using System.Text;
|
| | | using System.Threading;
|
| | | using QtVsTools.SyntaxAnalysis;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | | using static RegExpr;
|
| | | using static SyntaxAnalysis.RegExpr;
|
| | |
|
| | | public class QMakeQuery : QMake
|
| | | {
|
| | |
| | |
|
| | | public Dictionary<string, string> QueryAllValues()
|
| | | {
|
| | | string result = string.Empty;
|
| | | stdOutput = new StringBuilder();
|
| | | Query = " ";
|
| | |
|
| | |
| | | {
|
| | | get
|
| | | {
|
| | | string value = string.Empty;
|
| | | if (Properties.TryGetValue(name, out value))
|
| | | if (Properties.TryGetValue(name, out string value))
|
| | | return value;
|
| | | else
|
| | | return null;
|
| | | return null;
|
| | | }
|
| | | }
|
| | |
|
| | | Dictionary<string, string> _Properties;
|
| | | Dictionary<string, string> Properties => _Properties ?? (_Properties = QueryAllValues());
|
| | | Dictionary<string, string> Properties
|
| | | {
|
| | | get
|
| | | {
|
| | | return _Properties ?? (_Properties = QueryAllValues());
|
| | | }
|
| | | }
|
| | |
|
| | | Parser _PropertyParser;
|
| | | Parser PropertyParser
|
| | |
| | | {
|
| | | public string Prefix { get; set; }
|
| | | public string Language { get; set; }
|
| | | public List<QrcItem> Items { get; private set; }
|
| | | public List<QrcItem> Items { get; }
|
| | |
|
| | | public QrcPrefix()
|
| | | {
|
| | |
| | | /// </summary>
|
| | | class QtConfig
|
| | | {
|
| | | public BuildType BuildType { get; private set; }
|
| | | public BuildType BuildType { get; }
|
| | |
|
| | | public string LibInfix { get; private set; }
|
| | | public string LibInfix { get; }
|
| | |
|
| | | public bool Is64Bit { get; private set; }
|
| | | public bool Is64Bit { get; }
|
| | |
|
| | | public string Namespace { get; private set; }
|
| | | public string Namespace { get; }
|
| | |
|
| | | public uint VersionMajor { get; private set; }
|
| | | public uint VersionMinor { get; private set; }
|
| | | public uint VersionPatch { get; private set; }
|
| | | public uint VersionMajor { get; }
|
| | | public uint VersionMinor { get; }
|
| | | public uint VersionPatch { get; }
|
| | | public string VersionString { get; }
|
| | |
|
| | | public QtConfig(string qtdir)
|
| | | {
|
| | |
| | | Is64Bit = (data == "x86_64");
|
| | | } else if (name == "QT_NAMESPACE") {
|
| | | Namespace = data;
|
| | | } else if (name == "QT_VERSION") {
|
| | | VersionString = data;
|
| | | } else if (name == "QT_MAJOR_VERSION") {
|
| | | if (uint.TryParse(data, out uint versionMajor))
|
| | | VersionMajor = versionMajor;
|
| | |
| | |
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.IO;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | |
| | | public bool Selectable;
|
| | | public List<string> Defines = new List<string>();
|
| | | public string LibraryPrefix = string.Empty;
|
| | | public bool HasDLL = true;
|
| | | public List<string> AdditionalLibraries = new List<string>();
|
| | | public List<string> AdditionalLibrariesDebug = new List<string>();
|
| | | public List<string> IncludePath = new List<string>();
|
| | | public string proVarQT;
|
| | | public string proVarCONFIG;
|
| | | private string majorVersion;
|
| | |
|
| | | public string LibRelease
|
| | | {
|
| | |
| | | {
|
| | | return
|
| | | LibraryPrefix.StartsWith("Qt", StringComparison.Ordinal)
|
| | | ? "Qt5" + LibraryPrefix.Substring(2) + ".lib"
|
| | | ? "Qt" + majorVersion + LibraryPrefix.Substring(2) + ".lib"
|
| | | : LibraryPrefix + ".lib";
|
| | | }
|
| | | }
|
| | |
| | | {
|
| | | return
|
| | | LibraryPrefix.StartsWith("Qt", StringComparison.Ordinal)
|
| | | ? "Qt5" + LibraryPrefix.Substring(2) + "d.lib"
|
| | | ? "Qt" + majorVersion + LibraryPrefix.Substring(2) + "d.lib"
|
| | | : LibraryPrefix + "d.lib";
|
| | | }
|
| | | }
|
| | |
|
| | | public QtModule(int id)
|
| | | public QtModule(int id, string major)
|
| | | {
|
| | | Id = id;
|
| | | majorVersion = major;
|
| | | }
|
| | |
|
| | | public int Id { get; } = -1;
|
| | |
| | | var libs = new List<string>();
|
| | | var libName = LibraryPrefix;
|
| | | if (libName.StartsWith("Qt", StringComparison.Ordinal))
|
| | | libName = "Qt5" + libName.Substring(2);
|
| | | libName = "Qt" + majorVersion + libName.Substring(2);
|
| | | libName += libInfix;
|
| | | if (isDebugCfg)
|
| | | libName += "d";
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | {
|
| | | public class QtModules
|
| | | {
|
| | | private static QtModules instance = new QtModules();
|
| | | private readonly Dictionary<int, QtModule> modules = new Dictionary<int, QtModule>();
|
| | | public static QtModules Instance { get; } = new QtModules();
|
| | |
|
| | | public static QtModules Instance
|
| | | {
|
| | | get { return instance; }
|
| | | }
|
| | | private List<QtModule> qt5list = null, qt6list = null;
|
| | | private readonly Dictionary<int, QtModule> qt5modules = new Dictionary<int, QtModule>();
|
| | | private readonly Dictionary<int, QtModule> qt6modules = new Dictionary<int, QtModule>();
|
| | |
|
| | | public QtModule Module(int id)
|
| | | public QtModule Module(int id, uint major)
|
| | | {
|
| | | QtModule module;
|
| | | modules.TryGetValue(id, out module);
|
| | | QtModule module = null;
|
| | | if (major < 6)
|
| | | qt5modules.TryGetValue(id, out module);
|
| | | if (major == 6)
|
| | | qt6modules.TryGetValue(id, out module);
|
| | | if (major > 6)
|
| | | throw new QtVSException("Unsupported Qt version.");
|
| | | return module;
|
| | | }
|
| | |
|
| | | public List<QtModule> GetAvailableModules()
|
| | | public List<QtModule> GetAvailableModules(uint major)
|
| | | {
|
| | | var lst = new List<QtModule>(modules.Count);
|
| | | foreach (var entry in modules)
|
| | | lst.Add(entry.Value);
|
| | | return lst;
|
| | | if (major < 6) {
|
| | | if (qt5list == null) {
|
| | | qt5list = new List<QtModule>(qt5modules.Count);
|
| | | foreach (var entry in qt5modules)
|
| | | qt5list.Add(entry.Value);
|
| | | }
|
| | | return qt5list;
|
| | | }
|
| | | if (major == 6) {
|
| | | if (qt6list == null) {
|
| | | qt6list = new List<QtModule>(qt6modules.Count);
|
| | | foreach (var entry in qt6modules)
|
| | | qt6list.Add(entry.Value);
|
| | | }
|
| | | return qt6list;
|
| | | }
|
| | | if (major > 6)
|
| | | throw new QtVSException("Unsupported Qt version.");
|
| | | return null;
|
| | | }
|
| | |
|
| | | private QtModules()
|
| | | {
|
| | | var uri = new Uri(
|
| | | System.Reflection.Assembly.GetExecutingAssembly().EscapedCodeBase);
|
| | | var pkgInstallPath = Path.GetDirectoryName(
|
| | | Uri.UnescapeDataString(uri.AbsolutePath)) + @"\";
|
| | | var uri = new Uri(System.Reflection.Assembly.GetExecutingAssembly().EscapedCodeBase);
|
| | | var pkgInstallPath = Path.GetDirectoryName(Uri.UnescapeDataString(uri.AbsolutePath));
|
| | |
|
| | | var modulesFile = Path.Combine(pkgInstallPath, "qtmodules.xml");
|
| | | FillModules(Path.Combine(pkgInstallPath, "qtmodules.xml"), "5", ref qt5modules);
|
| | | FillModules(Path.Combine(pkgInstallPath, "qt6modules.xml"), "6", ref qt6modules);
|
| | | }
|
| | |
|
| | | private void FillModules(string modulesFile, string major, ref Dictionary<int, QtModule> dict)
|
| | | {
|
| | | if (!File.Exists(modulesFile))
|
| | | return;
|
| | |
|
| | |
| | |
|
| | | foreach (var xModule in xml.Elements("QtVsTools").Elements("Module")) {
|
| | | int id = (int)xModule.Attribute("Id");
|
| | | QtModule module = new QtModule(id);
|
| | | QtModule module = new QtModule(id, major);
|
| | | module.Name = (string)xModule.Element("Name");
|
| | | module.Selectable = ((string)xModule.Element("Selectable") == "true");
|
| | | module.LibraryPrefix = (string)xModule.Element("LibraryPrefix");
|
| | | module.HasDLL = ((string)xModule.Element("HasDLL") == "true");
|
| | | module.proVarQT = (string)xModule.Element("proVarQT");
|
| | | module.proVarCONFIG = (string)xModule.Element("proVarCONFIG");
|
| | | module.IncludePath = xModule.Elements("IncludePath")
|
| | |
| | | Messages.Print("\r\nCritical error: incorrect format of qtmodules.xml");
|
| | | throw new QtVSException("qtmodules.xml");
|
| | | }
|
| | | modules.Add(id, module);
|
| | | dict.Add(id, module);
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.IO;
|
| | | using System.Linq;
|
| | | using System.Text;
|
| | | using System;
|
| | | using System.IO;
|
| | |
|
| | | using CommandLineParser = QtVsTools.Core.CommandLine.Parser;
|
| | | using CommandLineOption = QtVsTools.Core.CommandLine.Option;
|
| | |
|
| | | namespace QtVsTools.Core.QtMsBuild
|
| | | {
|
| | | using CommandLineParser = CommandLine.Parser;
|
| | | using CommandLineOption = CommandLine.Option;
|
| | |
|
| | | public interface IVSMacroExpander
|
| | | {
|
| | | string ExpandString(string stringToExpand);
|
| | |
| | |
|
| | | public class QtMsBuildContainer
|
| | | {
|
| | |
|
| | | IPropertyStorageProvider provider;
|
| | | readonly IPropertyStorageProvider provider;
|
| | | public QtMsBuildContainer(IPropertyStorageProvider provider)
|
| | | {
|
| | | this.provider = provider;
|
| | |
| | | return provider.GetProjectConfiguration(GetProject(), configName);
|
| | | }
|
| | |
|
| | | Dictionary<string, ItemPropertyChange> itemPropertyChanges
|
| | | readonly Dictionary<string, ItemPropertyChange> itemPropertyChanges
|
| | | = new Dictionary<string, ItemPropertyChange>();
|
| | | Dictionary<string, List<ItemPropertyChange>> itemPropertyChangesGrouped
|
| | | readonly Dictionary<string, List<ItemPropertyChange>> itemPropertyChangesGrouped
|
| | | = new Dictionary<string, List<ItemPropertyChange>>();
|
| | | bool pendingChanges = false;
|
| | |
|
| | | void AddChange(ItemPropertyChange newChange)
|
| | | {
|
| | | ItemPropertyChange oldChange;
|
| | | if (itemPropertyChanges.TryGetValue(newChange.Key, out oldChange)) {
|
| | | if (itemPropertyChanges.TryGetValue(newChange.Key, out ItemPropertyChange oldChange)) {
|
| | | if (oldChange.GroupKey == newChange.GroupKey) {
|
| | | oldChange.CopyFrom(newChange);
|
| | | return;
|
| | |
| | |
|
| | | #region QtRcc
|
| | | static QtRcc qtRccInstance;
|
| | | public static QtRcc QtRccInstance
|
| | |
|
| | | private static QtRcc QtRccInstance
|
| | | {
|
| | | get
|
| | | {
|
| | |
| | |
|
| | | #region QtRepc
|
| | | static QtRepc qtRepcInstance;
|
| | | public static QtRepc QtRepcInstance
|
| | |
|
| | | private static QtRepc QtRepcInstance
|
| | | {
|
| | | get
|
| | | {
|
| | |
| | |
|
| | | #region QtUic
|
| | | static QtUic qtUicInstance;
|
| | | public static QtUic QtUicInstance
|
| | |
|
| | | private static QtUic QtUicInstance
|
| | | {
|
| | | get
|
| | | {
|
| | |
| | |
|
| | | public abstract class QtTool
|
| | | {
|
| | | protected CommandLineParser parser;
|
| | | protected CommandLineOption outputOption;
|
| | | protected CommandLineOption helpOption;
|
| | | protected CommandLineOption versionOption;
|
| | | protected readonly CommandLineParser parser;
|
| | | private readonly CommandLineOption outputOption;
|
| | | private CommandLineOption helpOption;
|
| | | private CommandLineOption versionOption;
|
| | |
|
| | | protected QtTool(bool defaultInputOutput = true)
|
| | | {
|
| | |
| | | AdditionalDependencies,
|
| | | }
|
| | |
|
| | | Dictionary<Property, CommandLineOption> options
|
| | | readonly Dictionary<Property, CommandLineOption> options
|
| | | = new Dictionary<Property, CommandLineOption>();
|
| | |
|
| | | public QtMoc() : base()
|
| | |
| | | {
|
| | | properties = new Dictionary<Property, string>();
|
| | |
|
| | | string qtDir, inputPath, outputPath;
|
| | | if (!ParseCommandLine(
|
| | | commandLine,
|
| | | macros,
|
| | | ToolExecName,
|
| | | out qtDir,
|
| | | out inputPath,
|
| | | out outputPath)) {
|
| | | out string qtDir,
|
| | | out string inputPath,
|
| | | out string outputPath)) {
|
| | | return false;
|
| | | }
|
| | |
|
| | |
| | | AdditionalDependencies,
|
| | | }
|
| | |
|
| | | Dictionary<Property, CommandLineOption> options
|
| | | readonly Dictionary<Property, CommandLineOption> options
|
| | | = new Dictionary<Property, CommandLineOption>();
|
| | |
|
| | | public QtRcc() : base()
|
| | |
| | | {
|
| | | properties = new Dictionary<Property, string>();
|
| | |
|
| | | string qtDir, inputPath, outputPath;
|
| | | if (!ParseCommandLine(
|
| | | commandLine,
|
| | | macros,
|
| | | ToolExecName,
|
| | | out qtDir,
|
| | | out inputPath,
|
| | | out outputPath)) {
|
| | | out string qtDir,
|
| | | out string inputPath,
|
| | | out string outputPath)) {
|
| | | return false;
|
| | | }
|
| | |
|
| | |
| | | properties[Property.Root] = parser.Value(options[Property.Root]);
|
| | |
|
| | | if (parser.IsSet(options[Property.Compression])) {
|
| | | int level;
|
| | | if (!int.TryParse(parser.Value(options[Property.Compression]), out level))
|
| | | if (!int.TryParse(parser.Value(options[Property.Compression]), out int level))
|
| | | return false;
|
| | | if (level < 1 || 9 < level)
|
| | | return false;
|
| | |
| | | PrintDebug,
|
| | | }
|
| | |
|
| | | Dictionary<Property, CommandLineOption> options
|
| | | readonly Dictionary<Property, CommandLineOption> options
|
| | | = new Dictionary<Property, CommandLineOption>();
|
| | |
|
| | | public QtRepc() : base(defaultInputOutput: false)
|
| | |
| | | {
|
| | | properties = new Dictionary<Property, string>();
|
| | |
|
| | | string qtDir, inputPath, outputPath;
|
| | | if (!ParseCommandLine(
|
| | | commandLine,
|
| | | macros,
|
| | | ToolExecName,
|
| | | out qtDir,
|
| | | out inputPath,
|
| | | out outputPath)) {
|
| | | out string qtDir,
|
| | | out string inputPath,
|
| | | out string outputPath)) {
|
| | | return false;
|
| | | }
|
| | |
|
| | |
| | | GenerateCommandLineOption(cmd, options[Property.InputFileType], inputType);
|
| | |
|
| | | var outputType = container.GetPropertyValue(propertyStorage, Property.OutputFileType);
|
| | | if (!string.IsNullOrEmpty(inputType))
|
| | | GenerateCommandLineOption(cmd, options[Property.InputFileType], inputType);
|
| | | if (!string.IsNullOrEmpty(outputType))
|
| | | GenerateCommandLineOption(cmd, options[Property.OutputFileType], outputType);
|
| | |
|
| | | string value = container.GetPropertyValue(propertyStorage, Property.IncludePath);
|
| | | if (!string.IsNullOrEmpty(value))
|
| | |
| | | AdditionalDependencies,
|
| | | }
|
| | |
|
| | | Dictionary<Property, CommandLineOption> options
|
| | | readonly Dictionary<Property, CommandLineOption> options
|
| | | = new Dictionary<Property, CommandLineOption>();
|
| | |
|
| | | public QtUic() : base()
|
| | |
| | | {
|
| | | properties = new Dictionary<Property, string>();
|
| | |
|
| | | string qtDir, inputPath, outputPath;
|
| | | if (!ParseCommandLine(
|
| | | commandLine,
|
| | | macros,
|
| | | ToolExecName,
|
| | | out qtDir,
|
| | | out inputPath,
|
| | | out outputPath)) {
|
| | | out string qtDir,
|
| | | out string inputPath,
|
| | | out string outputPath)) {
|
| | | return false;
|
| | | }
|
| | |
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | 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.
|
| | |
| | | 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);
|
| | | }
|
| | |
|
| | |
| | |
|
| | | private QtProject(Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (project == null)
|
| | | throw new QtVSException(SR.GetString("QtProject_CannotConstructWithoutValidProject"));
|
| | | envPro = project;
|
| | |
| | | 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)
|
| | |
| | |
|
| | | public static bool IsQtMsBuildEnabled(Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (project == null)
|
| | | return false;
|
| | | return IsQtMsBuildEnabled(project.Object as VCProject);
|
| | |
| | | private bool? isQtMsBuildEnabled = null;
|
| | | public bool IsQtMsBuildEnabled()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (!isQtMsBuildEnabled.HasValue) {
|
| | | if (vcPro != null)
|
| | | isQtMsBuildEnabled = IsQtMsBuildEnabled(vcPro);
|
| | |
| | | {
|
| | | get
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var ret = false;
|
| | | if (lastConfigurationRowNames == null) {
|
| | | lastConfigurationRowNames = envPro.ConfigurationManager.ConfigurationRowNames as Array;
|
| | |
| | | /// <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)) {
|
| | |
| | | /// 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;
|
| | |
| | | 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;
|
| | |
| | | EnvDTE.Configuration dteConfig,
|
| | | string propName)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (dteProject == null || dteConfig == null)
|
| | | return null;
|
| | | return GetPropertyValue(
|
| | |
| | | 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(
|
| | |
| | | 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");
|
| | |
|
| | |
| | | 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);
|
| | | }
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | // 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(
|
| | |
| | | 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);
|
| | |
| | | /// <param name="file">file</param>
|
| | | public void AddUic4BuildStep(VCFile file)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (GetFormatVersion(vcPro) >= Resources.qtMinFormatVersion_Settings) {
|
| | | file.ItemType = QtUic.ItemTypeName;
|
| | | return;
|
| | |
| | | }
|
| | | }
|
| | | if (toolSettings == CustomTool.CustomBuildStep && !uiFileExists)
|
| | | AddFileInFilter(Filters.GeneratedFiles(), uiFile);
|
| | | AddFileInFilter(Filters.GeneratedFiles(), uiFile, false);
|
| | | } catch {
|
| | | throw new QtVSException(SR.GetString("QtProject_CannotAddUicStep", file.FullPath));
|
| | | }
|
| | |
| | | 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 { }
|
| | |
| | | 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) {
|
| | |
| | | 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));
|
| | | }
|
| | |
| | | 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;
|
| | |
| | | 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;
|
| | |
| | | string includes,
|
| | | string description)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var workFile = workFileConfig.File as VCFile;
|
| | | var mocFileName = GetMocFileName(sourceFile.FullPath);
|
| | | var mocableIsCPP = HelperFunctions.IsMocFile(mocFileName);
|
| | |
| | | + 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();
|
| | |
| | | string includes,
|
| | | string description)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var baseFileName = sourceFile.Name.Remove(sourceFile.Name.LastIndexOf('.'));
|
| | | var outputMocFile = GetRelativeMocFilePath(sourceFile.FullPath);
|
| | | var outputMocPath = Path.GetDirectoryName(outputMocFile);
|
| | |
| | | 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;
|
| | |
| | | /// <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)) {
|
| | |
| | | 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);
|
| | | }
|
| | |
|
| | |
| | |
|
| | | public bool HasMocStep(VCFile file, string mocOutDir = null)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (file.ItemType == QtMoc.ItemTypeName)
|
| | | return true;
|
| | |
|
| | |
| | |
|
| | | public void RefreshRccSteps()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | Messages.Print("\r\n=== Update rcc steps ===");
|
| | | var files = GetResourceFiles();
|
| | |
|
| | |
| | |
|
| | | public void RefreshRccSteps(string oldRccDir)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | RefreshRccSteps();
|
| | | UpdateCompilerIncludePaths(oldRccDir, QtVSIPSettings.GetRccDirectory(envPro));
|
| | | }
|
| | |
| | | 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 + "...");
|
| | |
| | | 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 + "\""
|
| | |
| | |
|
| | | public void UpdateRccStep(VCFile qrcFile, RccOptions rccOpts)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (GetFormatVersion(vcPro) >= Resources.qtMinFormatVersion_Settings) {
|
| | | qrcFile.ItemType = QtRcc.ItemTypeName;
|
| | | return;
|
| | |
| | | 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;
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | static public void ExcludeFromAllBuilds(VCFile file)
|
| | | public static void ExcludeFromAllBuilds(VCFile file)
|
| | | {
|
| | | if (file == null)
|
| | | return;
|
| | |
| | | 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"
|
| | |
| | |
|
| | | 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)) {
|
| | |
| | | /// <param name="file">file</param>
|
| | | public void RemoveMocStepCustomBuild(VCFile file)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | try {
|
| | | if (!HasMocStep(file))
|
| | | return;
|
| | |
| | | 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;
|
| | |
| | | {
|
| | | 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;
|
| | | }
|
| | | }
|
| | |
| | | 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>
|
| | |
| | | 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);
|
| | |
| | | // 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);
|
| | | }
|
| | |
| | | }
|
| | | 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}");
|
| | | }
|
| | | }
|
| | |
|
| | |
| | |
|
| | | 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>
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | 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;
|
| | |
|
| | |
| | | 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;
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | 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;
|
| | |
|
| | |
| | |
|
| | | private void UpdateCompilerIncludePaths(string oldDir, string newDir)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var fixedOldDir = FixFilePathForComparison(oldDir);
|
| | | var dirs = new[] {
|
| | | FixFilePathForComparison(QtVSIPSettings.GetUicDirectory(envPro)),
|
| | |
| | |
|
| | | 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) {
|
| | |
| | |
|
| | | 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;
|
| | |
| | | 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()
|
| | |
| | | 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) {
|
| | |
| | | /// <returns></returns>
|
| | | private VCFile GetGeneratedMocFile(string fileName, VCFileConfiguration fileConfig)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (QtVSIPSettings.HasDifferentMocFilePerConfig(envPro)
|
| | | || QtVSIPSettings.HasDifferentMocFilePerPlatform(envPro)) {
|
| | | var projectConfig = (VCConfiguration)fileConfig.ProjectConfiguration;
|
| | |
| | |
|
| | | public void RefreshMocSteps()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | // Ignore when using shared compiler properties
|
| | | if (GetFormatVersion(vcPro) >= Resources.qtMinFormatVersion_ClProperties)
|
| | | return;
|
| | |
| | |
|
| | | public void RefreshMocStep(VCFile vcfile)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | RefreshMocStep(vcfile, true);
|
| | | }
|
| | |
|
| | |
| | | /// <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;
|
| | |
| | |
|
| | | 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);
|
| | |
| | |
|
| | | public void UpdateMocSteps(string oldMocDir)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | Messages.Print("\r\n=== Update moc steps ===");
|
| | | var orgFiles = new List<VCFile>();
|
| | | var abandonedMocFiles = new List<string>();
|
| | |
| | | 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 + ".");
|
| | |
| | |
|
| | | private void Clean()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var solutionConfigs = envPro.DTE.Solution.SolutionBuild.SolutionConfigurations;
|
| | | var backup = new List<KeyValuePair<SolutionContext, bool>>();
|
| | | foreach (SolutionConfiguration config in solutionConfigs) {
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | 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>
|
| | |
| | | /// <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);
|
| | |
| | |
|
| | | 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) {
|
| | |
| | | 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);
|
| | |
| | | if (genVCFilter == null)
|
| | | return;
|
| | |
|
| | | var error = false;
|
| | | error = DeleteFilesFromFilter(genVCFilter);
|
| | | if (error)
|
| | | if (DeleteFilesFromFilter(genVCFilter))
|
| | | Messages.Print(SR.GetString("DeleteGeneratedFilesError"));
|
| | | }
|
| | |
|
| | |
| | | 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);
|
| | |
| | | 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");
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | 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+)");
|
| | |
| | |
|
| | | public void CollapseFilter(string filterName)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var solutionExplorer = (UIHierarchy)dte.Windows.Item(Constants.vsext_wk_SProjectWindow).Object;
|
| | | if (solutionExplorer.UIHierarchyItems.Count == 0)
|
| | | return;
|
| | |
| | |
|
| | | private UIHierarchyItem FindProjectHierarchyItem(UIHierarchy hierarchy)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (hierarchy.UIHierarchyItems.Count == 0)
|
| | | return null;
|
| | |
|
| | |
| | |
|
| | | private UIHierarchyItem FindProjectHierarchyItem(UIHierarchyItem root)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | UIHierarchyItem projectItem = null;
|
| | | try {
|
| | | if (root.Name == envPro.Name)
|
| | |
| | | /// </summary>
|
| | | public string GetQtVersion()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return QtVersionManager.The().GetProjectQtVersion(envPro);
|
| | | }
|
| | |
|
| | |
| | | /// </summary>
|
| | | public void SetQtEnvironment()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | SetQtEnvironment(QtVersionManager.The().GetProjectQtVersion(envPro));
|
| | | }
|
| | |
|
| | |
| | | /// </summary>
|
| | | public void SetQtEnvironment(string qtVersion)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | SetQtEnvironment(qtVersion, string.Empty);
|
| | | }
|
| | |
|
| | |
| | | /// </summary>
|
| | | public void SetQtEnvironment(string qtVersion, string solutionConfig, bool build = false)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (string.IsNullOrEmpty(qtVersion))
|
| | | return;
|
| | |
|
| | |
| | | if (qtVersion != "$(QTDIR)")
|
| | | qtDir = QtVersionManager.The().GetInstallPath(qtVersion);
|
| | | HelperFunctions.SetEnvironmentVariableEx("QTDIR", qtDir);
|
| | |
|
| | | try {
|
| | | var propertyAccess = (IVCBuildPropertyStorage)vcPro;
|
| | | var vcprj = envPro.Object as VCProject;
|
| | |
| | | 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;
|
| | | }
|
| | |
| | | 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;
|
| | | }
|
| | | }
|
| | |
| | | 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();
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | 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();
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | {
|
| | | 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;
|
| | | }
|
| | |
|
| | |
| | |
|
| | | public class VCMacroExpander : IVSMacroExpander
|
| | | {
|
| | | object config;
|
| | |
|
| | | readonly object config;
|
| | | public VCMacroExpander(object config)
|
| | | {
|
| | | this.config = config;
|
| | |
| | |
|
| | | 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)
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using Microsoft.Win32;
|
| | | using QtVsTools.Core.QtMsBuild;
|
| | | using System;
|
| | | using System.Collections;
|
| | | using QtVsTools.Common;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | |
| | | {
|
| | | public static IQtVsToolsOptions Options { get; set; }
|
| | |
|
| | | static Hashtable mocDirCache = new Hashtable();
|
| | | static Hashtable uicDirCache = new Hashtable();
|
| | | static Hashtable rccDirCache = new Hashtable();
|
| | |
|
| | | public static bool GetDisableAutoMocStepsUpdate()
|
| | | {
|
| | | return GetBoolValue(Resources.disableAutoMocStepsUpdateKeyword, false);
|
| | | }
|
| | |
|
| | | public static void SaveDisableAutoMocStepsUpdate(bool b)
|
| | | {
|
| | | SetBoolValue(Resources.disableAutoMocStepsUpdateKeyword, b);
|
| | | return QtVSIPSettingsShared.GetBoolValue(Resources.disableAutoMocStepsUpdateKeyword, false);
|
| | | }
|
| | |
|
| | | public static string GetUicDirectory(EnvDTE.Project project)
|
| | | {
|
| | | return GetDirectory(project, Resources.uicDirKeyword);
|
| | | }
|
| | |
|
| | | public static void SaveUicDirectory(EnvDTE.Project project, string directory)
|
| | | {
|
| | | if (directory == null)
|
| | | SaveDirectory(project, Resources.uicDirKeyword, GetDirectory(project, Resources.uicDirKeyword));
|
| | | else
|
| | | SaveDirectory(project, Resources.uicDirKeyword, directory);
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return QtVSIPSettingsShared.GetDirectory(project, Resources.uicDirKeyword);
|
| | | }
|
| | |
|
| | | public static string GetMocDirectory()
|
| | | {
|
| | | return GetDirectory(Resources.mocDirKeyword);
|
| | | return QtVSIPSettingsShared.GetDirectory(Resources.mocDirKeyword);
|
| | | }
|
| | |
|
| | | public static string GetMocDirectory(EnvDTE.Project project)
|
| | | {
|
| | | return GetDirectory(project, Resources.mocDirKeyword);
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return QtVSIPSettingsShared.GetDirectory(project, Resources.mocDirKeyword);
|
| | | }
|
| | |
|
| | | public static string GetMocDirectory(
|
| | |
| | | string configName,
|
| | | string platformName, VCFile vCFile)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | string filePath = null;
|
| | | if (vCFile != null)
|
| | | filePath = vCFile.FullPath;
|
| | |
| | | string platformName,
|
| | | string filePath = null)
|
| | | {
|
| | | var dir = GetDirectory(project, Resources.mocDirKeyword);
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var dir = QtVSIPSettingsShared.GetDirectory(project, Resources.mocDirKeyword);
|
| | | if (!string.IsNullOrEmpty(configName)
|
| | | && !string.IsNullOrEmpty(platformName))
|
| | | HelperFunctions.ExpandString(ref dir, project, configName, platformName, filePath);
|
| | |
| | |
|
| | | public static bool HasDifferentMocFilePerConfig(EnvDTE.Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var mocDir = GetMocDirectory(project);
|
| | | return mocDir.Contains("$(ConfigurationName)");
|
| | | }
|
| | |
|
| | | public static bool HasDifferentMocFilePerPlatform(EnvDTE.Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var mocDir = GetMocDirectory(project);
|
| | | return mocDir.Contains("$(PlatformName)");
|
| | | }
|
| | |
|
| | | public static string GetMocOptions()
|
| | | {
|
| | | return GetOption(Resources.mocOptionsKeyword);
|
| | | }
|
| | |
|
| | | public static string GetMocOptions(EnvDTE.Project project)
|
| | | {
|
| | | return GetOption(project, Resources.mocOptionsKeyword);
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return QtVSIPSettingsShared.GetOption(project, Resources.mocOptionsKeyword);
|
| | | }
|
| | |
|
| | | public static bool GetLUpdateOnBuild(EnvDTE.Project project)
|
| | | {
|
| | | if (GetProjectQtSetting(project, "QtRunLUpdateOnBuild") == "true")
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (QtVSIPSettingsShared.GetProjectQtSetting(project, "QtRunLUpdateOnBuild") == "true")
|
| | | return true;
|
| | | return GetBoolValue(project, Resources.lupdateKeyword);
|
| | | }
|
| | |
|
| | | public static string GetLUpdateOptions()
|
| | | {
|
| | | return GetOption(Resources.lupdateOptionsKeyword);
|
| | | }
|
| | |
|
| | | static string GetProjectQtSetting(EnvDTE.Project project, string propertyName)
|
| | | {
|
| | | var vcProject = project.Object as VCProject;
|
| | | if (vcProject == null)
|
| | | return null;
|
| | |
|
| | | var vcConfigs = vcProject.Configurations as IVCCollection;
|
| | | if (vcConfigs == null)
|
| | | return null;
|
| | |
|
| | | var activeConfig = project.ConfigurationManager.ActiveConfiguration;
|
| | | if (activeConfig == null)
|
| | | return null;
|
| | |
|
| | | var activeConfigId = string.Format("{0}|{1}",
|
| | | activeConfig.ConfigurationName, activeConfig.PlatformName);
|
| | |
|
| | | var props = vcProject as IVCBuildPropertyStorage;
|
| | | if (props == null)
|
| | | return null;
|
| | |
|
| | | try {
|
| | | return props.GetPropertyValue(propertyName, activeConfigId, "ProjectFile");
|
| | | } catch {
|
| | | return null;
|
| | | }
|
| | | }
|
| | |
|
| | | public static string GetLUpdateOptions(EnvDTE.Project project)
|
| | | {
|
| | | string qtLUpdateOptions = GetProjectQtSetting(project, "QtLUpdateOptions");
|
| | | if (!string.IsNullOrEmpty(qtLUpdateOptions))
|
| | | return qtLUpdateOptions;
|
| | | return GetOption(project, Resources.lupdateOptionsKeyword);
|
| | | }
|
| | |
|
| | | public static string GetLReleaseOptions()
|
| | | {
|
| | | return GetOption(Resources.lreleaseOptionsKeyword);
|
| | | }
|
| | |
|
| | | public static string GetLReleaseOptions(EnvDTE.Project project)
|
| | | {
|
| | | string qtLReleaseOptions = GetProjectQtSetting(project, "QtLReleaseOptions");
|
| | | if (!string.IsNullOrEmpty(qtLReleaseOptions))
|
| | | return qtLReleaseOptions;
|
| | | return GetOption(project, Resources.lreleaseOptionsKeyword);
|
| | | }
|
| | |
|
| | | public static bool GetAskBeforeCheckoutFile()
|
| | | {
|
| | | return GetBoolValue(Resources.askBeforeCheckoutFileKeyword, true);
|
| | | }
|
| | |
|
| | | public static void SaveAskBeforeCheckoutFile(bool value)
|
| | | {
|
| | | SetBoolValue(Resources.askBeforeCheckoutFileKeyword, value);
|
| | | }
|
| | |
|
| | | public static bool GetDisableCheckoutFiles()
|
| | | {
|
| | | return GetBoolValue(Resources.disableCheckoutFilesKeyword, false);
|
| | | }
|
| | |
|
| | | public static void SaveDisableCheckoutFiles(bool value)
|
| | | {
|
| | | SetBoolValue(Resources.disableCheckoutFilesKeyword, value);
|
| | | }
|
| | |
|
| | | public static void SaveMocDirectory(EnvDTE.Project project, string directory)
|
| | | {
|
| | | if (directory == null)
|
| | | SaveDirectory(project, Resources.mocDirKeyword, GetDirectory(project, Resources.mocDirKeyword));
|
| | | else
|
| | | SaveDirectory(project, Resources.mocDirKeyword, directory);
|
| | | }
|
| | |
|
| | | public static void SaveMocOptions(EnvDTE.Project project, string options)
|
| | | {
|
| | | if (options == null)
|
| | | options = GetMocOptions();
|
| | | SaveOption(project, Resources.mocOptionsKeyword, options);
|
| | | }
|
| | |
|
| | | public static void SaveMocOptions(string options)
|
| | | {
|
| | | SaveOption(Resources.mocOptionsKeyword, options);
|
| | | }
|
| | |
|
| | | public static void SaveLUpdateOnBuild(EnvDTE.Project project)
|
| | | {
|
| | | SetBoolValue(project, Resources.lupdateKeyword, GetLUpdateOnBuild());
|
| | | }
|
| | |
|
| | | public static void SaveLUpdateOnBuild(EnvDTE.Project project, bool value)
|
| | | {
|
| | | SetBoolValue(project, Resources.lupdateKeyword, value);
|
| | | }
|
| | |
|
| | | public static void SaveLUpdateOptions(EnvDTE.Project project, string options)
|
| | | {
|
| | | if (options == null)
|
| | | options = GetLUpdateOptions();
|
| | |
|
| | | SaveOption(project, Resources.lupdateOptionsKeyword, options);
|
| | | }
|
| | |
|
| | | public static void SaveLUpdateOptions(string options)
|
| | | {
|
| | | SaveOption(Resources.lupdateOptionsKeyword, options);
|
| | | }
|
| | |
|
| | | public static void SaveLReleaseOptions(EnvDTE.Project project, string options)
|
| | | {
|
| | | if (options == null)
|
| | | options = GetLReleaseOptions();
|
| | | SaveOption(project, Resources.lreleaseOptionsKeyword, options);
|
| | | }
|
| | |
|
| | | public static void SaveLReleaseOptions(string options)
|
| | | {
|
| | | SaveOption(Resources.lreleaseOptionsKeyword, options);
|
| | | return QtVSIPSettingsShared.GetBoolValue(project, Resources.lupdateKeyword);
|
| | | }
|
| | |
|
| | | public static string GetRccDirectory(EnvDTE.Project project)
|
| | | {
|
| | | return GetDirectory(project, Resources.rccDirKeyword);
|
| | | }
|
| | |
|
| | | public static void SaveRccDirectory(string dir)
|
| | | {
|
| | | SaveDirectory(Resources.rccDirKeyword, dir);
|
| | | }
|
| | |
|
| | | public static void SaveRccDirectory(EnvDTE.Project project, string directory)
|
| | | {
|
| | | if (directory == null)
|
| | | SaveDirectory(project, Resources.rccDirKeyword, GetDirectory(project, Resources.rccDirKeyword));
|
| | | else
|
| | | SaveDirectory(project, Resources.rccDirKeyword, directory);
|
| | | }
|
| | |
|
| | | private static string GetDirectory(string type)
|
| | | {
|
| | | try {
|
| | | var key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\" + Resources.registryPackagePath);
|
| | | if (key != null) {
|
| | | var path = (string)key.GetValue(type, null);
|
| | | if (path != null)
|
| | | return HelperFunctions.NormalizeRelativeFilePath(path);
|
| | | }
|
| | | } catch { }
|
| | | if (type == Resources.mocDirKeyword)
|
| | | return Resources.generatedFilesDir + "\\$(ConfigurationName)";
|
| | | return Resources.generatedFilesDir;
|
| | | }
|
| | |
|
| | | private static string GetOption(string type)
|
| | | {
|
| | | try {
|
| | | var key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\" + Resources.registryPackagePath);
|
| | | if (key != null) {
|
| | | var opt = (string)key.GetValue(type, null);
|
| | | if (opt != null)
|
| | | return opt;
|
| | | }
|
| | | } catch { }
|
| | | return null;
|
| | | }
|
| | |
|
| | | public static bool GetLUpdateOnBuild()
|
| | | {
|
| | | return GetBoolValue(Resources.lupdateKeyword, false);
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return QtVSIPSettingsShared.GetDirectory(project, Resources.rccDirKeyword);
|
| | | }
|
| | |
|
| | | public static string GetRccDirectory()
|
| | | {
|
| | | return GetDirectory(Resources.rccDirKeyword);
|
| | | return QtVSIPSettingsShared.GetDirectory(Resources.rccDirKeyword);
|
| | | }
|
| | |
|
| | | public static string GetUicDirectory()
|
| | | {
|
| | | return GetDirectory(Resources.uicDirKeyword);
|
| | | }
|
| | |
|
| | | private static string GetDirectory(EnvDTE.Project project, string type)
|
| | | {
|
| | | // check for directory in following order:
|
| | | // - stored in project
|
| | | // - stored in cache
|
| | | // - retrieve from moc/uic steps
|
| | | // - globally defined default directory
|
| | | // - fallback on hardcoded directory
|
| | | if (project != null) {
|
| | | if (project.Globals.get_VariablePersists(type))
|
| | | return HelperFunctions.NormalizeRelativeFilePath((string)project.Globals[type]);
|
| | |
|
| | | try {
|
| | | if (type == Resources.mocDirKeyword && mocDirCache.Contains(project.FullName))
|
| | | return (string)mocDirCache[project.FullName];
|
| | | if (type == Resources.uicDirKeyword && uicDirCache.Contains(project.FullName))
|
| | | return (string)uicDirCache[project.FullName];
|
| | | if (type == Resources.rccDirKeyword && rccDirCache.Contains(project.FullName))
|
| | | return (string)rccDirCache[project.FullName];
|
| | |
|
| | | QtCustomBuildTool tool = null;
|
| | | string configName = null;
|
| | | string platformName = null;
|
| | | var vcpro = (VCProject)project.Object;
|
| | | foreach (VCFile vcfile in (IVCCollection)vcpro.Files) {
|
| | | var name = vcfile.Name;
|
| | | if ((type == Resources.mocDirKeyword && HelperFunctions.IsHeaderFile(name))
|
| | | || (type == Resources.mocDirKeyword && HelperFunctions.IsMocFile(name))
|
| | | || (type == Resources.uicDirKeyword && HelperFunctions.IsUicFile(name))
|
| | | || (type == Resources.rccDirKeyword && HelperFunctions.IsQrcFile(name))) {
|
| | | foreach (VCFileConfiguration config in (IVCCollection)vcfile.FileConfigurations) {
|
| | | tool = new QtCustomBuildTool(config);
|
| | | configName = config.Name.Remove(config.Name.IndexOf('|'));
|
| | | var vcConfig = config.ProjectConfiguration as VCConfiguration;
|
| | | var platform = vcConfig.Platform as VCPlatform;
|
| | | platformName = platform.Name;
|
| | | if (tool != null && (tool.CommandLine.IndexOf("moc.exe", StringComparison.OrdinalIgnoreCase) != -1
|
| | | || (tool.CommandLine.IndexOf("uic.exe", StringComparison.OrdinalIgnoreCase) != -1)
|
| | | || (tool.CommandLine.IndexOf("rcc.exe", StringComparison.OrdinalIgnoreCase) != -1)))
|
| | | break;
|
| | | tool = null;
|
| | | }
|
| | |
|
| | | if (tool != null)
|
| | | break;
|
| | | }
|
| | | }
|
| | |
|
| | | if (tool != null) {
|
| | | string dir = null;
|
| | | var lastindex = tool.Outputs.LastIndexOf('\\');
|
| | | if (tool.Outputs.LastIndexOf('/') > lastindex)
|
| | | lastindex = tool.Outputs.LastIndexOf('/');
|
| | |
|
| | | if (lastindex == -1)
|
| | | dir = ".";
|
| | | else
|
| | | dir = tool.Outputs.Substring(0, lastindex);
|
| | | dir = dir.Replace("\"", "");
|
| | |
|
| | | if (type == Resources.mocDirKeyword) {
|
| | | int index;
|
| | | if ((index = dir.IndexOf(configName, StringComparison.OrdinalIgnoreCase)) != -1)
|
| | | dir = dir.Replace(dir.Substring(index, configName.Length), "$(ConfigurationName)");
|
| | | if ((index = dir.IndexOf(platformName, StringComparison.OrdinalIgnoreCase)) != -1)
|
| | | dir = dir.Replace(dir.Substring(index, platformName.Length), "$(PlatformName)");
|
| | |
|
| | | mocDirCache.Add(project.FullName, HelperFunctions.NormalizeRelativeFilePath(dir));
|
| | | } else if (type == Resources.uicDirKeyword)
|
| | | uicDirCache.Add(project.FullName, HelperFunctions.NormalizeRelativeFilePath(dir));
|
| | | else if (type == Resources.rccDirKeyword)
|
| | | rccDirCache.Add(project.FullName, HelperFunctions.NormalizeRelativeFilePath(dir));
|
| | |
|
| | | cleanUpCache(project);
|
| | |
|
| | | return HelperFunctions.NormalizeRelativeFilePath(dir);
|
| | | }
|
| | | } catch { }
|
| | | }
|
| | |
|
| | | return GetDirectory(type);
|
| | | }
|
| | |
|
| | | private static string GetOption(EnvDTE.Project project, string type)
|
| | | {
|
| | | // check for directory in following order:
|
| | | // - stored in project
|
| | | // - globally defined default option
|
| | | // - empty options
|
| | | if (project != null && project.Globals.get_VariablePersists(type))
|
| | | return (string)project.Globals[type];
|
| | | return GetOption(type);
|
| | | }
|
| | |
|
| | | private static bool GetBoolValue(EnvDTE.Project project, string type)
|
| | | {
|
| | | // check for directory in following order:
|
| | | // - stored in project
|
| | | // - globally defined default option
|
| | | // - empty options
|
| | | if (project != null && project.Globals.get_VariablePersists(type))
|
| | | return Convert.ToInt32(project.Globals[type] as string) > 0;
|
| | | return GetBoolValue(type, false);
|
| | | }
|
| | |
|
| | | private static void SaveDirectory(EnvDTE.Project project, string type, string dir)
|
| | | {
|
| | | dir = HelperFunctions.NormalizeRelativeFilePath(dir);
|
| | | project.Globals[type] = dir;
|
| | | if (!project.Globals.get_VariablePersists(type))
|
| | | project.Globals.set_VariablePersists(type, true);
|
| | |
|
| | | cleanUpCache(project);
|
| | | }
|
| | |
|
| | | private static void SaveOption(EnvDTE.Project project, string type, string option)
|
| | | {
|
| | | project.Globals[type] = option;
|
| | | if (!project.Globals.get_VariablePersists(type))
|
| | | project.Globals.set_VariablePersists(type, true);
|
| | | }
|
| | |
|
| | | private static void SetBoolValue(EnvDTE.Project project, string type, bool value)
|
| | | {
|
| | | project.Globals[type] = Convert.ToInt32(value).ToString();
|
| | | if (!project.Globals.get_VariablePersists(type))
|
| | | project.Globals.set_VariablePersists(type, true);
|
| | | }
|
| | |
|
| | | public static void SaveUicDirectory(string dir)
|
| | | {
|
| | | SaveDirectory(Resources.uicDirKeyword, dir);
|
| | | }
|
| | |
|
| | | public static void SaveMocDirectory(string dir)
|
| | | {
|
| | | SaveDirectory(Resources.mocDirKeyword, dir);
|
| | | }
|
| | |
|
| | | public static void SaveLUpdateOnBuild(bool val)
|
| | | {
|
| | | SetBoolValue(Resources.lupdateKeyword, val);
|
| | | }
|
| | |
|
| | | public static void cleanUpCache(EnvDTE.Project project)
|
| | | {
|
| | | try {
|
| | | var mocEnumerator = mocDirCache.GetEnumerator();
|
| | | while (mocEnumerator.MoveNext()) {
|
| | | if (!HelperFunctions.IsProjectInSolution(project.DTE, (string)mocEnumerator.Key)) {
|
| | | mocDirCache.Remove(mocEnumerator.Key);
|
| | | mocEnumerator = mocDirCache.GetEnumerator();
|
| | | }
|
| | | }
|
| | |
|
| | | var uicEnumerator = uicDirCache.GetEnumerator();
|
| | | while (uicEnumerator.MoveNext()) {
|
| | | if (!HelperFunctions.IsProjectInSolution(project.DTE, (string)uicEnumerator.Key)) {
|
| | | uicDirCache.Remove(uicEnumerator.Key);
|
| | | uicEnumerator = uicDirCache.GetEnumerator();
|
| | | }
|
| | | }
|
| | |
|
| | | var rccEnumerator = rccDirCache.GetEnumerator();
|
| | | while (rccEnumerator.MoveNext()) {
|
| | | if (!HelperFunctions.IsProjectInSolution(project.DTE, (string)rccEnumerator.Key)) {
|
| | | rccDirCache.Remove(rccEnumerator.Key);
|
| | | rccEnumerator = rccDirCache.GetEnumerator();
|
| | | }
|
| | | }
|
| | | } catch { }
|
| | | }
|
| | |
|
| | | private static void SaveDirectory(string type, string dir)
|
| | | {
|
| | | dir = HelperFunctions.NormalizeRelativeFilePath(dir);
|
| | | var key = Registry.CurrentUser.CreateSubKey("SOFTWARE\\" + Resources.registryPackagePath);
|
| | | if (key == null)
|
| | | return;
|
| | | key.SetValue(type, dir);
|
| | | }
|
| | |
|
| | | private static void SaveOption(string type, string option)
|
| | | {
|
| | | var key = Registry.CurrentUser.CreateSubKey("SOFTWARE\\" + Resources.registryPackagePath);
|
| | | if (key == null)
|
| | | return;
|
| | | if (option == null)
|
| | | option = "";
|
| | | key.SetValue(type, option);
|
| | | return QtVSIPSettingsShared.GetDirectory(Resources.uicDirKeyword);
|
| | | }
|
| | |
|
| | | public static bool AutoUpdateUicSteps()
|
| | | {
|
| | | if (ValueExists("AutoUpdateUicSteps"))
|
| | | return GetBoolValue("AutoUpdateUicSteps", true);
|
| | | return GetBoolValue("AutoUpdateBuildSteps", true);
|
| | | }
|
| | |
|
| | | private static bool GetBoolValue(string key, bool defaultValue)
|
| | | {
|
| | | var regKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\" + Resources.registryPackagePath);
|
| | | if (regKey == null)
|
| | | return defaultValue;
|
| | | return ((int)regKey.GetValue(key, defaultValue ? 1 : 0)) > 0;
|
| | | }
|
| | |
|
| | | private static bool ValueExists(string key)
|
| | | {
|
| | | var regKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\" + Resources.registryPackagePath);
|
| | | if (regKey != null) {
|
| | | foreach (var s in regKey.GetValueNames()) {
|
| | | if (s == key)
|
| | | return true;
|
| | | }
|
| | | }
|
| | | return false;
|
| | | }
|
| | |
|
| | | private static void SetBoolValue(string key, bool val)
|
| | | {
|
| | | var regKey = Registry.CurrentUser.CreateSubKey("SOFTWARE\\" + Resources.registryPackagePath);
|
| | | if (regKey == null)
|
| | | return;
|
| | | regKey.SetValue(key, val ? 1 : 0);
|
| | | }
|
| | |
|
| | | public static bool GetQmlDebug(EnvDTE.Project project)
|
| | | {
|
| | | return QtProject.Create(project).QmlDebug;
|
| | | }
|
| | |
|
| | | public static void SaveQmlDebug(EnvDTE.Project project, bool enabled)
|
| | | {
|
| | | QtProject.Create(project).QmlDebug = enabled;
|
| | | if (QtVSIPSettingsShared.ValueExists("AutoUpdateUicSteps"))
|
| | | return QtVSIPSettingsShared.GetBoolValue("AutoUpdateUicSteps", true);
|
| | | return QtVSIPSettingsShared.GetBoolValue("AutoUpdateBuildSteps", true);
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using Microsoft.Win32;
|
| | | using System;
|
| | | using System.Collections;
|
| | | using System.Collections.Generic;
|
| | | using System.IO;
|
| | | using System.Linq;
|
| | | using System.Threading;
|
| | | using QtVsTools.VisualStudio;
|
| | | using EnvDTE;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using Microsoft.Win32;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | |
| | | public class QtVersionManager
|
| | | {
|
| | | private static QtVersionManager instance;
|
| | | private string regVersionPath;
|
| | | private string strVersionKey;
|
| | | private readonly string regVersionPath;
|
| | | private readonly string strVersionKey;
|
| | | private Hashtable versionCache;
|
| | |
|
| | | protected QtVersionManager()
|
| | | {
|
| | | strVersionKey = "Versions";
|
| | | regVersionPath = Resources.registryVersionPath;
|
| | | RefreshVersionNames();
|
| | | }
|
| | |
|
| | | void RefreshVersionNames()
|
| | | {
|
| | | var rootKeyPath = "SOFTWARE\\" + Resources.registryRootPath;
|
| | | try {
|
| | | using (var rootKey = Registry.CurrentUser.OpenSubKey(rootKeyPath, true))
|
| | | using (var versionsKey = rootKey.OpenSubKey(strVersionKey, true)) {
|
| | | versionsKey.SetValue("VersionNames", string.Join(";", GetVersions()));
|
| | | }
|
| | | private static readonly EventWaitHandle packageInit = new EventWaitHandle(false, EventResetMode.ManualReset);
|
| | | private static EventWaitHandle packageInitDone = null;
|
| | |
|
| | | } catch (Exception e) {
|
| | | Messages.Print(
|
| | | e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
|
| | | }
|
| | | }
|
| | |
|
| | | static EventWaitHandle
|
| | | packageInit = new EventWaitHandle(false, EventResetMode.ManualReset),
|
| | | packageInitDone = null;
|
| | |
|
| | | static public QtVersionManager The(EventWaitHandle initDone = null)
|
| | | public static QtVersionManager The(EventWaitHandle initDone = null)
|
| | | {
|
| | | if (initDone == null) {
|
| | | packageInit.WaitOne();
|
| | |
| | |
|
| | | public VersionInformation GetVersionInfo(string name)
|
| | | {
|
| | | if (name == "$(DefaultQtVersion)")
|
| | | name = GetDefaultVersion();
|
| | | if (name == null)
|
| | | return null;
|
| | | if (name == "$(DefaultQtVersion)")
|
| | | name = GetDefaultVersion();
|
| | | if (versionCache == null)
|
| | | versionCache = new Hashtable();
|
| | |
|
| | |
| | |
|
| | | public VersionInformation GetVersionInfo(EnvDTE.Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return GetVersionInfo(GetProjectQtVersion(project));
|
| | | }
|
| | |
|
| | | public void ClearVersionCache()
|
| | | {
|
| | | if (versionCache != null)
|
| | | versionCache.Clear();
|
| | | }
|
| | |
|
| | | public string[] GetVersions()
|
| | |
| | | if (qtDir == null)
|
| | | return null;
|
| | |
|
| | | qtDir = qtDir.ToLower();
|
| | | var versions = GetVersions();
|
| | | foreach (var version in versions) {
|
| | | var installPath = GetInstallPath(version);
|
| | | if (installPath == null)
|
| | | continue;
|
| | | if (installPath.ToLower() == qtDir)
|
| | | if (installPath.Equals(qtDir, StringComparison.OrdinalIgnoreCase))
|
| | | return version;
|
| | | }
|
| | |
|
| | |
| | | /// <summary>
|
| | | /// Check if all Qt versions are valid and readable.
|
| | | /// </summary>
|
| | | /// Also sets the default Qt version to the newest version, if needed.
|
| | | /// <param name="errorMessage"></param>
|
| | | /// <returns>true, if we found an invalid version</returns>
|
| | | public bool HasInvalidVersions(out string errorMessage)
|
| | | /// <returns>true, if there are one or more invalid Qt version</returns>
|
| | | public bool HasInvalidVersions(out string errorMessage, out bool defaultVersionInvalid)
|
| | | {
|
| | | var validVersions = new Dictionary<string, QtConfig>();
|
| | | var invalidVersions = new List<string>();
|
| | | var defaultVersion = GetDefaultVersionString();
|
| | | defaultVersionInvalid = string.IsNullOrEmpty(defaultVersion);
|
| | |
|
| | | foreach (var v in GetVersions()) {
|
| | | if (v == "$(DefaultQtVersion)")
|
| | | continue;
|
| | |
|
| | | var vPath = GetInstallPath(v);
|
| | | if (string.IsNullOrEmpty(vPath)) {
|
| | | invalidVersions.Add(v);
|
| | | continue;
|
| | | }
|
| | |
|
| | | if (vPath.StartsWith("SSH:") || vPath.StartsWith("WSL:"))
|
| | | continue;
|
| | |
|
| | | var qmakePath = Path.Combine(vPath, "bin", "qmake.exe");
|
| | | if (!File.Exists(qmakePath))
|
| | | qmakePath = Path.Combine(vPath, "qmake.exe");
|
| | | if (!File.Exists(qmakePath)) {
|
| | | invalidVersions.Add(v);
|
| | | continue;
|
| | | }
|
| | |
|
| | | validVersions[v] = new QtConfig(vPath);
|
| | | }
|
| | |
|
| | | if (invalidVersions.Count > 0) {
|
| | | errorMessage = "These Qt version are inaccessible:\n";
|
| | | foreach (var invalidVersion in invalidVersions)
|
| | | errorMessage += invalidVersion + " in " + GetInstallPath(invalidVersion) + "\n";
|
| | | errorMessage += "Make sure that you have read access to all files in your Qt directories.";
|
| | |
|
| | | // Is the default Qt version invalid?
|
| | | var isDefaultQtVersionInvalid = false;
|
| | | var defaultQtVersionName = GetDefaultVersion();
|
| | | if (string.IsNullOrEmpty(defaultQtVersionName)) {
|
| | | isDefaultQtVersionInvalid = true;
|
| | | } else {
|
| | | foreach (var name in invalidVersions) {
|
| | | if (name == defaultQtVersionName) {
|
| | | isDefaultQtVersionInvalid = true;
|
| | | break;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | // find the newest valid Qt version that can be used as default version
|
| | | if (isDefaultQtVersionInvalid && validVersions.Count > 0) {
|
| | | QtConfig defaultQtVersionConfig = null;
|
| | | foreach (var vNameConfig in validVersions) {
|
| | | var vName = vNameConfig.Key;
|
| | | var v = vNameConfig.Value;
|
| | | if (defaultQtVersionConfig == null) {
|
| | | defaultQtVersionConfig = v;
|
| | | defaultQtVersionName = vName;
|
| | | continue;
|
| | | }
|
| | | if (defaultQtVersionConfig.VersionMajor < v.VersionMajor ||
|
| | | (defaultQtVersionConfig.VersionMajor == v.VersionMajor && (defaultQtVersionConfig.VersionMinor < v.VersionMinor ||
|
| | | (defaultQtVersionConfig.VersionMinor == v.VersionMinor && defaultQtVersionConfig.VersionPatch < v.VersionPatch)))) {
|
| | | defaultQtVersionConfig = v;
|
| | | defaultQtVersionName = vName;
|
| | | }
|
| | | }
|
| | | if (defaultQtVersionConfig != null)
|
| | | SaveDefaultVersion(defaultQtVersionName);
|
| | | }
|
| | |
|
| | | return true;
|
| | | }
|
| | | errorMessage = null;
|
| | | return false;
|
| | | foreach (var version in GetVersions()) {
|
| | | if (version == "$(DefaultQtVersion)")
|
| | | continue;
|
| | |
|
| | | var path = GetInstallPath(version);
|
| | | if (path != null && (path.StartsWith("SSH:") || path.StartsWith("WSL:")))
|
| | | continue;
|
| | |
|
| | | if (string.IsNullOrEmpty(path) || !QMake.Exists(path)) {
|
| | | errorMessage += version + " in " + path + "\n";
|
| | | defaultVersionInvalid |= version == defaultVersion;
|
| | | }
|
| | |
|
| | | if (!string.IsNullOrEmpty(errorMessage)) {
|
| | | errorMessage = "These Qt version are inaccessible:\n"
|
| | | + errorMessage
|
| | | + "Make sure that you have read access to all files in your Qt directories.";
|
| | | }
|
| | | }
|
| | | return errorMessage != null;
|
| | | }
|
| | |
|
| | | public void SetLatestQtVersionAsDefault()
|
| | | {
|
| | | var validVersions = new Dictionary<string, Version>();
|
| | | foreach (var version in GetVersions()) {
|
| | | if (version == "$(DefaultQtVersion)")
|
| | | continue;
|
| | |
|
| | | var path = GetInstallPath(version);
|
| | | if (!string.IsNullOrEmpty(path) && QMake.Exists(path))
|
| | | validVersions[version] = new Version(new QtConfig(path).VersionString);
|
| | | }
|
| | |
|
| | | if (validVersions.Count <= 0)
|
| | | return;
|
| | |
|
| | | var defaultName = "";
|
| | | Version defaultVersion = null;
|
| | | foreach (var tmp in validVersions) {
|
| | | var version = tmp.Value;
|
| | | if (defaultVersion == null || defaultVersion < version) {
|
| | | defaultName = tmp.Key;
|
| | | defaultVersion = version;
|
| | | }
|
| | | }
|
| | | SaveDefaultVersion(defaultName);
|
| | | }
|
| | |
|
| | | public string GetInstallPath(string version)
|
| | |
| | | return Environment.GetEnvironmentVariable("QTDIR");
|
| | |
|
| | | var key = root.OpenSubKey("SOFTWARE\\" + Resources.registryRootPath, false);
|
| | | if (key == null)
|
| | | return null;
|
| | | var versionKey = key.OpenSubKey(strVersionKey + "\\" + version, false);
|
| | | if (versionKey == null)
|
| | | return null;
|
| | | return (string)versionKey.GetValue("InstallDir");
|
| | | var versionKey = key?.OpenSubKey(strVersionKey + "\\" + version, false);
|
| | | return versionKey?.GetValue("InstallDir") as string;
|
| | | }
|
| | |
|
| | | public string GetInstallPath(EnvDTE.Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var version = GetProjectQtVersion(project);
|
| | | if (version == "$(DefaultQtVersion)")
|
| | | version = GetDefaultVersion();
|
| | |
| | | versionKey.SetValue("InstallDir", dir);
|
| | | }
|
| | | }
|
| | | RefreshVersionNames();
|
| | | return true;
|
| | | }
|
| | |
|
| | |
| | | return;
|
| | | key.DeleteSubKey(versionName);
|
| | | key.Close();
|
| | | RefreshVersionNames();
|
| | | }
|
| | |
|
| | | private bool IsVersionAvailable(string version)
|
| | | internal bool IsVersionAvailable(string version)
|
| | | {
|
| | | var versionAvailable = false;
|
| | | var versions = GetVersions();
|
| | |
| | |
|
| | | public bool SaveProjectQtVersion(EnvDTE.Project project, string version)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return SaveProjectQtVersion(project, version, project.ConfigurationManager.ActiveConfiguration.PlatformName);
|
| | | }
|
| | |
|
| | | public bool SaveProjectQtVersion(EnvDTE.Project project, string version, string platform)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (!IsVersionAvailable(version) && version != "$(DefaultQtVersion)")
|
| | | return false;
|
| | |
|
| | | if (QtProject.GetFormatVersion(project) >= Resources.qtMinFormatVersion_Settings) {
|
| | | var vcPro = project.Object as VCProject;
|
| | | if (vcPro == null)
|
| | |
| | |
|
| | | public string GetProjectQtVersion(EnvDTE.Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | EnvDTE.Configuration config = null;
|
| | | try {
|
| | | config = project.ConfigurationManager.ActiveConfiguration;
|
| | |
| | | }
|
| | |
|
| | | if (version == null)
|
| | | version = GetSolutionQtVersion(project.DTE.Solution);
|
| | | version = Legacy.QtVersionManager.GetSolutionQtVersion(project.DTE.Solution);
|
| | |
|
| | | return version;
|
| | | }
|
| | |
|
| | | public string GetProjectQtVersion(EnvDTE.Project project, EnvDTE.Configuration config)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (QtProject.GetFormatVersion(project) >= Resources.qtMinFormatVersion_Settings)
|
| | | return QtProject.GetPropertyValue(project, config, "QtInstall");
|
| | |
|
| | |
| | |
|
| | | public string GetProjectQtVersion(EnvDTE.Project project, string platform)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (QtProject.GetFormatVersion(project) >= Resources.qtMinFormatVersion_Settings)
|
| | | return GetProjectQtVersion(project);
|
| | |
|
| | |
| | | version = Environment.GetEnvironmentVariable(env);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | public bool SaveSolutionQtVersion(EnvDTE.Solution solution, string version)
|
| | | {
|
| | | if (!IsVersionAvailable(version) && version != "$(DefaultQtVersion)")
|
| | | return false;
|
| | | solution.Globals["Qt5Version"] = version;
|
| | | if (!solution.Globals.get_VariablePersists("Qt5Version"))
|
| | | solution.Globals.set_VariablePersists("Qt5Version", true);
|
| | | return true;
|
| | | }
|
| | |
|
| | | public string GetSolutionQtVersion(EnvDTE.Solution solution)
|
| | | {
|
| | | if (solution == null)
|
| | | return null;
|
| | |
|
| | | if (solution.Globals.get_VariableExists("Qt5Version")) {
|
| | | var version = (string)solution.Globals["Qt5Version"];
|
| | | return VerifyIfQtVersionExists(version) ? version : null;
|
| | | }
|
| | |
|
| | | return null;
|
| | | }
|
| | |
|
| | | public string GetDefaultVersion()
|
| | |
| | | }
|
| | | }
|
| | | return VerifyIfQtVersionExists(defaultVersion) ? defaultVersion : null;
|
| | | }
|
| | |
|
| | | public string GetDefaultVersionString()
|
| | | {
|
| | | string defaultVersion = null;
|
| | | try {
|
| | | var key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\" + regVersionPath, false);
|
| | | if (key != null)
|
| | | defaultVersion = key.GetValue("DefaultQtVersion") as string;
|
| | | } catch {
|
| | | Messages.Print("Cannot read the default Qt version from registry.");
|
| | | }
|
| | |
|
| | | if (defaultVersion == null) {
|
| | | var qtDir = Environment.GetEnvironmentVariable("QTDIR");
|
| | | if (string.IsNullOrEmpty(qtDir))
|
| | | return defaultVersion;
|
| | | }
|
| | | return defaultVersion;
|
| | | }
|
| | |
|
| | | public bool SaveDefaultVersion(string version)
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | private bool VerifyIfQtVersionExists(string version)
|
| | | internal bool VerifyIfQtVersionExists(string version)
|
| | | {
|
| | | if (version == "$(DefaultQtVersion)")
|
| | | version = GetDefaultVersion();
|
| | |
| | | // -->
|
| | | <ItemGroup>
|
| | | <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
|
| | | <Reference Include="PresentationFramework" />
|
| | | <Reference Include="System" />
|
| | | <Reference Include="System.Drawing" />
|
| | | <Reference Include="System.Xml" />
|
| | | <Reference Include="System.Xml.Linq" />
|
| | | <Reference Include="System.Windows.Forms" />
|
| | | <Reference Include="WindowsBase" />
|
| | | </ItemGroup>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Version specific references
|
| | | // General package references
|
| | | // -->
|
| | | <Import Project="$(SolutionDir)\references.props" />
|
| | | <ItemGroup>
|
| | | <PackageReference Include="Microsoft.VisualStudio.SDK"
|
| | | Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
|
| | | <PackageReference Include="Microsoft.VSSDK.BuildTools"
|
| | | Version="$(Version_Microsoft_VSSDK_BuildTools)" />
|
| | | <PackageReference Include="Microsoft.Build"
|
| | | Version="$(Version_Microsoft_Build)" />
|
| | | <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
|
| | | <PackageReference Include="$(Name_Microsoft_Build)" Version="$(Version_Microsoft_Build)" />
|
| | | </ItemGroup>
|
| | | <ItemGroup Condition="'$(VisualStudioVersion)'=='17.0'">
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)"
|
| | | Version="$(Version_Microsoft_VisualStudio_VCProjectEngine)" />
|
| | | </ItemGroup>
|
| | | <ItemGroup Condition="'$(VisualStudioVersion)'=='16.0'">
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)"
|
| | | Version="$(Version_Microsoft_VisualStudio_VCProjectEngine)" />
|
| | | </ItemGroup>
|
| | | <ItemGroup Condition="'$(VisualStudioVersion)'=='15.0'">
|
| | | <Reference Include="Microsoft.VisualStudio.VCProjectEngine" />
|
| | | </ItemGroup>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Version specific package references
|
| | | // -->
|
| | | <Choose>
|
| | | <When Condition="'$(VisualStudioVersion)'=='17.0'">
|
| | | <ItemGroup>
|
| | | </ItemGroup>
|
| | | </When>
|
| | | <When Condition="'$(VisualStudioVersion)'=='16.0'">
|
| | | <ItemGroup>
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_Validation)" Version="$(Version_Microsoft_VisualStudio_Validation)" />
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)" Version="$(Version_Microsoft_VisualStudio_VCProjectEngine)" />
|
| | | </ItemGroup>
|
| | | </When>
|
| | | <When Condition="'$(VisualStudioVersion)'=='15.0'">
|
| | | <ItemGroup>
|
| | | <Reference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)" />
|
| | | </ItemGroup>
|
| | | </When>
|
| | | </Choose>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Solution project references
|
| | |
| | | <Compile Include="BuildConfig.cs" />
|
| | | <Compile Include="CommandLineParser.cs" />
|
| | | <Compile Include="Common\EnumExt.cs" />
|
| | | <Compile Include="Common\LazyFactory.cs" />
|
| | | <Compile Include="Common\QtVSIPSettingsShared.cs" />
|
| | | <Compile Include="CompilerToolWrapper.cs" />
|
| | | <Compile Include="CxxStreamReader.cs" />
|
| | | <Compile Include="ExportProjectDialog.cs">
|
| | |
| | | <Compile Include="ImageButton.cs">
|
| | | <SubType>Component</SubType>
|
| | | </Compile>
|
| | | <Compile Include="Legacy\QtProject.cs" />
|
| | | <Compile Include="Legacy\QtVersionManager.cs" />
|
| | | <Compile Include="Legacy\QtVSIPSettings.cs" />
|
| | | <Compile Include="LinkerToolWrapper.cs" />
|
| | | <Compile Include="MainWinWrapper.cs" />
|
| | | <Compile Include="Messages.cs" />
|
| | | <Compile Include="MocCmdChecker.cs" />
|
| | | <Compile Include="MsBuildProject.cs" />
|
| | | <Compile Include="Observable.cs" />
|
| | | <Compile Include="OutputWindowPane.cs" />
|
| | | <Compile Include="ProFileContent.cs" />
|
| | | <Compile Include="ProFileOption.cs" />
|
| | | <Compile Include="ProjectExporter.cs" />
|
| | |
| | | <Compile Include="RccOptions.cs" />
|
| | | <Compile Include="Resources.cs" />
|
| | | <Compile Include="SR.cs" />
|
| | | <Compile Include="TemplateType.cs" />
|
| | | <Compile Include="VersionInformation.cs" />
|
| | | <Compile Include="VisualStudio\InfoBarMessage.cs" />
|
| | | <Compile Include="VisualStudio\IProjectTracker.cs" />
|
| | | <Compile Include="VisualStudio\VsSearch.cs" />
|
| | | <Compile Include="VisualStudio\VsServiceProvider.cs" />
|
| | | <Compile Include="VisualStudio\VsShell.cs" />
|
| | | <Compile Include="WaitDialog.cs" />
|
| | | <EmbeddedResource Include="ExportProjectDialog.resx">
|
| | | <DependentUpon>ExportProjectDialog.cs</DependentUpon>
|
| | |
| | | </ItemGroup>
|
| | | <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
| | | <Import Project="$(SolutionDir)\transform.targets" />
|
| | | </Project>
|
| | | </Project> |
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using System;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | |
| | | {
|
| | | get
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (project.Globals.get_VariablePersists("RccCompressFiles" + id)
|
| | | && (string)project.Globals["RccCompressFiles" + id] == "true")
|
| | | return true;
|
| | |
| | | }
|
| | | set
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (value)
|
| | | project.Globals["RccCompressFiles" + id] = "true";
|
| | | else
|
| | |
| | | {
|
| | | get
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (project.Globals.get_VariablePersists("RccCompressLevel" + id))
|
| | | return Convert.ToInt32((string)project.Globals["RccCompressLevel" + id], 10);
|
| | | return 0;
|
| | | }
|
| | | set
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | project.Globals["RccCompressLevel" + id] = value.ToString();
|
| | | if (!project.Globals.get_VariablePersists("RccCompressLevel" + id))
|
| | | project.Globals.set_VariablePersists("RccCompressLevel" + id, true);
|
| | |
| | | {
|
| | | get
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (project.Globals.get_VariablePersists("RccCompressThreshold" + id))
|
| | | return Convert.ToInt32((string)project.Globals["RccCompressThreshold" + id], 10);
|
| | | return 0;
|
| | | }
|
| | | set
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | project.Globals["RccCompressThreshold" + id] = value.ToString();
|
| | | if (!project.Globals.get_VariablePersists("RccCompressThreshold" + id))
|
| | | project.Globals.set_VariablePersists("RccCompressThreshold" + id, true);
|
| | |
| | | public const int qtMinFormatVersion_PropertyEval = 303;
|
| | |
|
| | | // Project properties labels
|
| | | public const string projLabelGlobals = "Globals";
|
| | | public const string projLabelQtSettings = "QtSettings";
|
| | |
|
| | | public const string uic4Command = "$(QTDIR)\\bin\\uic.exe";
|
| | | public const string moc4Command = "$(QTDIR)\\bin\\moc.exe";
|
| | | public const string rcc4Command = "$(QTDIR)\\bin\\rcc.exe";
|
| | | public const string lupdateCommand = "\\bin\\lupdate.exe";
|
| | | public const string lreleaseCommand = "\\bin\\lrelease.exe";
|
| | |
|
| | | // All defined paths have to be relative to the project directory!!!
|
| | |
|
| | | public const string resourceDir = "Resources";
|
| | |
|
| | | // If those directories do not equal to the project directory
|
| | | // they have to be added to the include directories for
|
| | |
| | | <data name="OpenSolution" xml:space="preserve">
|
| | | <value>Open Solution</value>
|
| | | </data>
|
| | | <data name="ProjectExists" xml:space="preserve">
|
| | | <value>Project file already exists.</value>
|
| | | </data>
|
| | | <data name="ExportProject_EditProjectFileManually" xml:space="preserve">
|
| | | <value>qmake has generated a .vcproj file, but it needs to be converted.
|
| | | To do this you must open the .vcproj file manually.
|
| | |
| | | <value>Export to .pri File</value>
|
| | | </data>
|
| | | <data name="ExportProject_NoProjectsToExport" xml:space="preserve">
|
| | | <value>Cannot find any Qt 4 projects to export.</value>
|
| | | <value>Cannot find any Qt projects to export.</value>
|
| | | </data>
|
| | | <data name="ExportProject_PriFileContainsSpaces" xml:space="preserve">
|
| | | <value>The generated .pri file contains paths with spaces. You will not be able to import from this file.
|
| | | 1. Manually edit the generated .pri file.
|
| | | 2. Move your project to a location without spaces in the path.
|
| | | 3. Place the .pri file in another directory.</value>
|
| | | </data>
|
| | | <data name="ExportProject_ProjectExistsRegenerateOrReuse" xml:space="preserve">
|
| | | <value>{0} already exists.
|
| | | Select 'Yes' to regenerate the file, and 'No' to use the existing one.</value>
|
| | | </data>
|
| | | <data name="ExportProject_ProjectOrSolutionCorrupt" xml:space="preserve">
|
| | | <value>{0}
|
| | |
| | | <data name="QtProject_CannotRemoveMocStep" xml:space="preserve">
|
| | | <value>Cannot remove a moc step from file {0}</value>
|
| | | </data>
|
| | | <data name="QtProject_CannotAddFilter" xml:space="preserve">
|
| | | <value>Project cannot add filter {0}</value>
|
| | | </data>
|
| | | <data name="QtProject_CannotAddFile" xml:space="preserve">
|
| | | <value>Cannot add file {0} to filter.</value>
|
| | | </data>
|
| | | <data name="QtProject_CannotRemoveFile" xml:space="preserve">
|
| | | <value>Cannot remove file {0} from filter.</value>
|
| | | </data>
|
| | |
| | | <data name="QtProject_ProjectCannotAddResourceFilter" xml:space="preserve">
|
| | | <value>Cannot add a resource filter.</value>
|
| | | </data>
|
| | | <data name="QtProject_CannotCreateResourceDir" xml:space="preserve">
|
| | | <value>Cannot create a resource directory.</value>
|
| | | </data>
|
| | | <data name="QtProject_CannotAdjustWhitespaces" xml:space="preserve">
|
| | | <value>Cannot adjust whitespace or tabs in file (write).
|
| | | ({0})</value>
|
| | | </data>
|
| | | <data name="QtProject_CannotReplaceTokenRead" xml:space="preserve">
|
| | | <value>Cannot replace token ({0} -> {1}) in file (read).
|
| | | ({3})</value>
|
| | | </data>
|
| | | <data name="QtProject_CannotReplaceTokenWrite" xml:space="preserve">
|
| | | <value>Cannot replace token ({0} -> {1}) in file (write).
|
| | | ({3})</value>
|
| | | </data>
|
| | | <data name="QtProject_FileExistsInProjectFolder" xml:space="preserve">
|
| | | <value>The file {0} exists in your project folder. Qt VS Tools will overwrite the existing file.
|
| | |
|
| | | Select 'Yes' to overwrite, select 'No' to keep the existing file and automatically add it to the project.</value>
|
| | | </data>
|
| | | <data name="QtVersionManager_CannotLoadQtVersion" xml:space="preserve">
|
| | | <value>Cannot load the default Qt version.</value>
|
| | |
| | | <data name="Resources_ResourceFiles" xml:space="preserve">
|
| | | <value>Resource Files</value>
|
| | | </data>
|
| | | <data name="Resources_TranslationFiles" xml:space="preserve">
|
| | | <value>Translation Files</value>
|
| | | </data>
|
| | | <data name="Resources_GeneratedFiles" xml:space="preserve">
|
| | | <value>Generated Files</value>
|
| | | </data>
|
| | |
| | | </data>
|
| | | <data name="QtProject_CannotAccessUserFile" xml:space="preserve">
|
| | | <value>Could not add QTDIR to {0}'s .user file.</value>
|
| | | </data>
|
| | | <data name="ImportProject_CannotConvertProject" xml:space="preserve">
|
| | | <value>Could not convert project file {0} to Qt/MSBuild.</value>
|
| | | </data>
|
| | | <data name="Resources_OtherFiles" xml:space="preserve">
|
| | | <value>Other Files</value>
|
| | | </data>
|
| | | <data name="WaitDialogRefreshMoc" xml:space="preserve">
|
| | | <value>Updating moc steps...</value>
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Globalization;
|
| | | using System.Resources;
|
| | | using System.Threading;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | |
| | | {
|
| | | static SR loader;
|
| | | readonly ResourceManager resources;
|
| | | static readonly Object obj = new Object();
|
| | | static readonly object obj = new object();
|
| | |
|
| | | internal SR()
|
| | | {
|
| | |
| | | loader = new SR();
|
| | | }
|
| | | }
|
| | |
|
| | | return loader;
|
| | | }
|
| | |
|
| | | private static CultureInfo Culture
|
| | | {
|
| | | get { return null/*use ResourceManager default, CultureInfo.CurrentUICulture*/; }
|
| | | //get { return new CultureInfo("de-DE"); }
|
| | | }
|
| | |
|
| | | public static string LanguageName
|
| | | {
|
| | | get { return Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName; }
|
| | | //get { return Culture.TwoLetterISOLanguageName; }
|
| | | }
|
| | |
|
| | | public static string GetString(string name, params object[] args)
|
| | |
| | | var sys = GetLoader();
|
| | | if (sys == null)
|
| | | return null;
|
| | | var res = sys.resources.GetString(name, Culture);
|
| | |
|
| | | if (args != null && args.Length > 0)
|
| | | var res = sys.resources.GetString(name, null);
|
| | | if (args != null && args.Length > 0 && !string.IsNullOrEmpty(res))
|
| | | return string.Format(res, args);
|
| | | return res;
|
| | | }
|
| | |
|
| | | public static string GetString(string name)
|
| | | {
|
| | | var sys = GetLoader();
|
| | | if (sys == null)
|
| | | return null;
|
| | | return sys.resources.GetString(name, Culture);
|
| | | return GetString(name, null);
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | using System.Linq;
|
| | | using System.Text;
|
| | | using System.Text.RegularExpressions;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | |
| | | {
|
| | | //fields
|
| | | public string name;
|
| | | public string qtDir;
|
| | | public readonly string qtDir;
|
| | | public uint qtMajor; // X in version x.y.z
|
| | | public uint qtMinor; // Y in version x.y.z
|
| | | public uint qtPatch; // Z in version x.y.z
|
| | | public bool qt5Version = true;
|
| | | private QtConfig qtConfig;
|
| | | private QMakeConf qmakeConf;
|
| | | private string vsPlatformName;
|
| | |
| | | _cache.Clear();
|
| | | }
|
| | |
|
| | | Dictionary<string, bool> _IsModuleAvailable;
|
| | | readonly Dictionary<string, bool> _IsModuleAvailable;
|
| | | public bool IsModuleAvailable(string module)
|
| | | {
|
| | | return _IsModuleAvailable?[module] ?? false;
|
| | | }
|
| | |
|
| | | public string VC_MinimumVisualStudioVersion { get; private set; }
|
| | | public string VC_ApplicationTypeRevision { get; private set; }
|
| | | public string VC_WindowsTargetPlatformMinVersion { get; private set; }
|
| | | public string VC_WindowsTargetPlatformVersion { get; private set; }
|
| | | public string VC_Link_TargetMachine { get; private set; }
|
| | | public string VC_PlatformToolset { get; private set; }
|
| | | public string VC_MinimumVisualStudioVersion { get; }
|
| | | public string VC_ApplicationTypeRevision { get; }
|
| | | public string VC_WindowsTargetPlatformMinVersion { get; }
|
| | | public string VC_WindowsTargetPlatformVersion { get; }
|
| | | public string VC_Link_TargetMachine { get; }
|
| | | private string VC_PlatformToolset { get; }
|
| | |
|
| | | private VersionInformation(string qtDirIn)
|
| | | {
|
| | |
| | | qtMinor = (version >> 8) & 0xFF;
|
| | | qtPatch = version & 0xFF;
|
| | | }
|
| | | qt5Version = (qtMajor == 5);
|
| | |
|
| | | try {
|
| | | QtInstallDocs = qmakeQuery["QT_INSTALL_DOCS"];
|
| | |
| | | var tempProData = new StringBuilder();
|
| | | tempProData.AppendLine("SOURCES = main.cpp");
|
| | |
|
| | | var modules = QtModules.Instance.GetAvailableModules()
|
| | | var modules = QtModules.Instance.GetAvailableModules(qtMajor)
|
| | | .Where((QtModule mi) => mi.Selectable);
|
| | |
|
| | | foreach (QtModule mi in modules) {
|
| | |
| | |
|
| | | public string QtInstallDocs
|
| | | {
|
| | | get; private set;
|
| | | get;
|
| | | }
|
| | |
|
| | | public string QMakeSpecDirectory
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2021 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Diagnostics;
|
| | | using System.Linq;
|
| | | using Microsoft.VisualStudio.Imaging.Interop;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | |
|
| | | namespace QtVsTools.VisualStudio
|
| | | {
|
| | | using Common;
|
| | |
|
| | | public abstract class InfoBarMessage
|
| | | {
|
| | | protected abstract ImageMoniker Icon { get; }
|
| | | protected abstract TextSpan[] Text { get; }
|
| | | protected abstract Hyperlink[] Hyperlinks { get; }
|
| | |
|
| | | protected class TextSpan
|
| | | {
|
| | | public string Text { get; set; }
|
| | | public bool Bold { get; set; }
|
| | | public bool Italic { get; set; }
|
| | | public bool Underline { get; set; }
|
| | | public static implicit operator TextSpan(string text) => new TextSpan { Text = text };
|
| | | }
|
| | |
|
| | | protected class TextSpacer : TextSpan
|
| | | {
|
| | | public TextSpacer(int spaces)
|
| | | {
|
| | | Text = new string(' ', spaces);
|
| | | }
|
| | | }
|
| | |
|
| | | protected class Hyperlink
|
| | | {
|
| | | public string Text { get; set; }
|
| | | public bool CloseInfoBar { get; set; }
|
| | | public Action OnClicked { get; set; }
|
| | | }
|
| | |
|
| | | private MessageUI UI { get; set; }
|
| | |
|
| | | public InfoBarMessage()
|
| | | {
|
| | | UI = new MessageUI { Message = this };
|
| | | }
|
| | |
|
| | | public virtual void Show()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | UI.Show();
|
| | | }
|
| | |
|
| | | public virtual void Close()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | UI.Close();
|
| | | }
|
| | |
|
| | | public bool IsOpen => UI.IsOpen;
|
| | |
|
| | | protected virtual void OnClosed()
|
| | | { }
|
| | |
|
| | | private class MessageUI : IVsInfoBarUIEvents
|
| | | {
|
| | | static LazyFactory StaticLazy { get; } = new LazyFactory();
|
| | | static IVsInfoBarUIFactory Factory => StaticLazy.Get(() =>
|
| | | Factory, () => VsServiceProvider
|
| | | .GetService<SVsInfoBarUIFactory, IVsInfoBarUIFactory>());
|
| | |
|
| | | private IVsInfoBarUIElement UIElement { get; set; }
|
| | | private uint eventNotificationCookie;
|
| | |
|
| | | public bool IsOpen => UIElement != null;
|
| | |
|
| | | public InfoBarMessage Message { get; set; }
|
| | |
|
| | | public void Show()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | if (Factory == null)
|
| | | return;
|
| | | if (UIElement != null) // Message already shown
|
| | | return;
|
| | | var textSpans = Enumerable.Empty<InfoBarTextSpan>();
|
| | | if (Message.Text != null) {
|
| | | textSpans = Message.Text
|
| | | .Select(x => new InfoBarTextSpan(x.Text, x.Bold, x.Italic, x.Underline));
|
| | | }
|
| | | var hyperlinks = Enumerable.Empty<InfoBarHyperlink>();
|
| | | if (Message.Hyperlinks != null) {
|
| | | hyperlinks = Message.Hyperlinks
|
| | | .Select(x => new InfoBarHyperlink(x.Text, x));
|
| | | }
|
| | | var model = new InfoBarModel(textSpans, hyperlinks, Message.Icon, true);
|
| | | UIElement = Factory.CreateInfoBar(model);
|
| | | if (UIElement != null) {
|
| | | UIElement.Advise(this, out eventNotificationCookie);
|
| | | VsShell.InfoBarHost?.AddInfoBar(UIElement);
|
| | | }
|
| | | }
|
| | |
|
| | | public void Close()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | UIElement?.Close();
|
| | | }
|
| | |
|
| | | void IVsInfoBarUIEvents.OnActionItemClicked(
|
| | | IVsInfoBarUIElement infoBarUIElement,
|
| | | IVsInfoBarActionItem actionItem)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | Debug.Assert(infoBarUIElement == UIElement);
|
| | | var hyperlink = actionItem.ActionContext as Hyperlink;
|
| | | if (hyperlink == null)
|
| | | return;
|
| | | if (hyperlink.CloseInfoBar)
|
| | | Close();
|
| | | hyperlink.OnClicked();
|
| | | }
|
| | |
|
| | | void IVsInfoBarUIEvents.OnClosed(IVsInfoBarUIElement infoBarUIElement)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | Debug.Assert(infoBarUIElement == UIElement);
|
| | | if (UIElement != null) {
|
| | | UIElement.Unadvise(eventNotificationCookie);
|
| | | UIElement = null;
|
| | | eventNotificationCookie = 0;
|
| | | Message.OnClosed();
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.Linq;
|
| | | using System.Windows.Controls;
|
| | | using System.Windows.Data;
|
| | | using Microsoft.Internal.VisualStudio.PlatformUI;
|
| | | using Microsoft.VisualStudio;
|
| | | using Microsoft.VisualStudio.PlatformUI;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | |
|
| | | namespace QtVsTools.VisualStudio
|
| | | {
|
| | | public class SearchTask : VsSearchTask
|
| | | {
|
| | | private readonly Action _clearCallback = null;
|
| | | private readonly Func<IEnumerable<string>, uint> _searchCallBack = null;
|
| | |
|
| | | public SearchTask(uint cookie, IVsSearchQuery query, IVsSearchCallback callback,
|
| | | Action clearCallback, Func<IEnumerable<string>, uint> searchCallBack)
|
| | | : base(cookie, query, callback)
|
| | | {
|
| | | _clearCallback = clearCallback;
|
| | | _searchCallBack = searchCallBack;
|
| | | }
|
| | |
|
| | | protected override void OnStartSearch()
|
| | | {
|
| | | ErrorCode = VSConstants.S_OK;
|
| | | try {
|
| | | _ = ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
|
| | | {
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | if (TaskStatus != VSConstants.VsSearchTaskStatus.Stopped) {
|
| | | SearchResults = _searchCallBack(
|
| | | SearchUtilities.ExtractSearchTokens(SearchQuery).Select(token =>
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return token.ParsedTokenText;
|
| | | })
|
| | | );
|
| | | } else if (TaskStatus == VSConstants.VsSearchTaskStatus.Stopped) {
|
| | | _clearCallback();
|
| | | }
|
| | | });
|
| | | } catch {
|
| | | ErrorCode = VSConstants.E_FAIL;
|
| | | }
|
| | | base.OnStartSearch();
|
| | | }
|
| | |
|
| | | protected override void OnStopSearch()
|
| | | {
|
| | | SearchResults = 0;
|
| | | }
|
| | | }
|
| | |
|
| | | public abstract class VsWindowSearch : IVsWindowSearch
|
| | | {
|
| | | public abstract IVsSearchTask CreateSearch(uint cookie, IVsSearchQuery query,
|
| | | IVsSearchCallback callback);
|
| | |
|
| | | public virtual void ClearSearch()
|
| | | {}
|
| | |
|
| | | public virtual void ProvideSearchSettings(IVsUIDataSource settings)
|
| | | {
|
| | | Utilities.SetValue(settings, SearchSettingsDataSource.PropertyNames.ControlMaxWidth,
|
| | | (uint)10000);
|
| | | Utilities.SetValue(settings, SearchSettingsDataSource.PropertyNames.SearchStartType,
|
| | | (uint)VSSEARCHSTARTTYPE.SST_INSTANT);
|
| | | }
|
| | |
|
| | | public virtual bool OnNavigationKeyDown(uint dwNavigationKey, uint dwModifiers) => false;
|
| | |
|
| | | public virtual bool SearchEnabled => true;
|
| | |
|
| | | public virtual Guid Category => Guid.Empty;
|
| | |
|
| | | public virtual IVsEnumWindowSearchFilters SearchFiltersEnum => null;
|
| | |
|
| | | public virtual IVsEnumWindowSearchOptions SearchOptionsEnum => null;
|
| | | }
|
| | |
|
| | | public class ListBoxSearch : VsWindowSearch
|
| | | {
|
| | | private readonly ListBox _listBox = null;
|
| | | private Action<string> _setSearchText = null;
|
| | |
|
| | | public ListBoxSearch(ListBox listBox, Action<string> action)
|
| | | {
|
| | | _listBox = listBox;
|
| | | _setSearchText = action;
|
| | | }
|
| | |
|
| | | public override IVsSearchTask CreateSearch(uint cookie, IVsSearchQuery query,
|
| | | IVsSearchCallback callback)
|
| | | {
|
| | | return new SearchTask(cookie, query, callback, ClearSearch,
|
| | | searchCallBack: (IEnumerable<string> tokens) =>
|
| | | {
|
| | | _setSearchText(string.Join(" ", tokens));
|
| | | var view = CollectionViewSource.GetDefaultView(_listBox.ItemsSource);
|
| | |
|
| | | view.Refresh();
|
| | | if (_listBox.Items.Count == 1 || _listBox.SelectedItem == null)
|
| | | _listBox.SelectedIndex = 0;
|
| | | return (uint)view.Cast<object>().Count();
|
| | | });
|
| | | }
|
| | |
|
| | | public override void ClearSearch()
|
| | | {
|
| | | _setSearchText(string.Empty);
|
| | | CollectionViewSource.GetDefaultView(_listBox.ItemsSource).Refresh();
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using System;
|
| | | using System.Collections.Concurrent;
|
| | | using System.Threading.Tasks;
|
| | |
| | | {
|
| | | public static IVsServiceProvider Instance { get; set; }
|
| | |
|
| | | static ConcurrentDictionary<ServiceType, object> services
|
| | | static readonly ConcurrentDictionary<ServiceType, object> services
|
| | | = new ConcurrentDictionary<ServiceType, object>();
|
| | |
|
| | | public static I GetService<I>()
|
| | |
| | | if (Instance == null)
|
| | | return null;
|
| | |
|
| | | object serviceObj;
|
| | | if (services.TryGetValue(new ServiceType(typeof(T), typeof(I)), out serviceObj))
|
| | | if (services.TryGetValue(new ServiceType(typeof(T), typeof(I)), out object serviceObj))
|
| | | return serviceObj as I;
|
| | |
|
| | | var serviceInterface = Instance.GetService<T, I>();
|
| | |
| | | if (Instance == null)
|
| | | return null;
|
| | |
|
| | | object serviceObj;
|
| | | if (services.TryGetValue(new ServiceType(typeof(T), typeof(I)), out serviceObj))
|
| | | if (services.TryGetValue(new ServiceType(typeof(T), typeof(I)), out object serviceObj))
|
| | | return serviceObj as I;
|
| | |
|
| | | var serviceInterface = await Instance.GetServiceAsync<T, I>();
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2018 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using Microsoft.VisualStudio;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | |
|
| | | namespace QtVsTools.VisualStudio
|
| | | {
|
| | | public static class VsShell
|
| | | {
|
| | | public static string InstallRootDir
|
| | | {
|
| | | get
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | Initialize();
|
| | | return _InstallRootDir;
|
| | | }
|
| | | }
|
| | |
|
| | | private static IVsShell vsShell;
|
| | | private static string _InstallRootDir;
|
| | |
|
| | | private static void Initialize()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (vsShell != null)
|
| | | return;
|
| | | vsShell = VsServiceProvider.GetService<IVsShell>();
|
| | |
|
| | | int res = vsShell.GetProperty((int)__VSSPROPID2.VSSPROPID_InstallRootDir, out object o);
|
| | | if (res == VSConstants.S_OK && o is string property)
|
| | | _InstallRootDir = property;
|
| | | }
|
| | |
|
| | | public static EnvDTE.Project GetProject(IVsHierarchy context)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | int res = context.GetProperty(
|
| | | (uint)VSConstants.VSITEMID.Root, (int)__VSHPROPID.VSHPROPID_ExtObject, out object value);
|
| | | if (res == VSConstants.S_OK && value is EnvDTE.Project project)
|
| | | return project;
|
| | | return null;
|
| | | }
|
| | |
|
| | | public static EnvDTE.ProjectItem GetProjectItem(IVsHierarchy context, uint itemid)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | int res = context.GetProperty(
|
| | | itemid, (int)__VSHPROPID.VSHPROPID_ExtObject, out object value);
|
| | | if (res == VSConstants.S_OK && value is EnvDTE.ProjectItem item)
|
| | | return item;
|
| | | return null;
|
| | | }
|
| | |
|
| | | public static EnvDTE.Document GetDocument(IVsHierarchy context, uint itemid)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return GetProjectItem(context, itemid)?.Document;
|
| | | }
|
| | |
|
| | | private static IVsInfoBarHost _InfoBarHost = null;
|
| | | public static IVsInfoBarHost InfoBarHost
|
| | | {
|
| | | get
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | if (_InfoBarHost != null)
|
| | | return _InfoBarHost;
|
| | | Initialize();
|
| | | object host = null;
|
| | | vsShell?.GetProperty((int)__VSSPROPID7.VSSPROPID_MainWindowInfoBarHost, out host);
|
| | | return _InfoBarHost = host as IVsInfoBarHost;
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.IO;
|
| | | using System.Linq;
|
| | | using System.Windows.Forms;
|
| | | using Microsoft.VisualStudio;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using QtVsTools.VisualStudio;
|
| | |
|
| | | namespace QtVsTools.Core
|
| | | {
|
| | | using VisualStudio;
|
| | |
|
| | | public class WaitDialog : IDisposable
|
| | | {
|
| | | static IVsThreadedWaitDialogFactory factory = null;
|
| | |
|
| | | public IVsThreadedWaitDialog2 VsWaitDialog { get; private set; }
|
| | | private IVsThreadedWaitDialog2 VsWaitDialog { get; set; }
|
| | |
|
| | | public bool Running { get; private set; }
|
| | | private bool Running { get; set; }
|
| | |
|
| | | bool? vsDialogCanceled = null;
|
| | |
|
| | |
| | | {
|
| | | get
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (vsDialogCanceled.HasValue)
|
| | | return vsDialogCanceled.Value;
|
| | |
|
| | | if (VsWaitDialog == null)
|
| | | return false;
|
| | |
|
| | | bool canceled = false;
|
| | | int res = VsWaitDialog.HasCanceled(out canceled);
|
| | | int res = VsWaitDialog.HasCanceled(out bool canceled);
|
| | | if (res != VSConstants.S_OK)
|
| | | return false;
|
| | |
|
| | |
| | |
|
| | | static WaitDialog Create(IVsThreadedWaitDialogFactory dialogFactory)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (factory == null) {
|
| | | factory = dialogFactory ?? VsServiceProvider
|
| | | .GetService<SVsThreadedWaitDialogFactory, IVsThreadedWaitDialogFactory>();
|
| | |
| | | return null;
|
| | | }
|
| | |
|
| | | IVsThreadedWaitDialog2 vsWaitDialog = null;
|
| | | factory.CreateInstance(out vsWaitDialog);
|
| | | factory.CreateInstance(out IVsThreadedWaitDialog2 vsWaitDialog);
|
| | | if (vsWaitDialog == null)
|
| | | return null;
|
| | |
|
| | |
| | | bool showMarqueeProgress = true,
|
| | | IVsThreadedWaitDialogFactory dialogFactory = null)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var dialog = Create(dialogFactory);
|
| | | if (dialog == null)
|
| | | return null;
|
| | |
| | | bool isCancelable = false,
|
| | | IVsThreadedWaitDialogFactory dialogFactory = null)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var dialog = Create(dialogFactory);
|
| | | if (dialog == null)
|
| | | return null;
|
| | |
| | | string statusBarText = null,
|
| | | bool disableCancel = false)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (!Running)
|
| | | return;
|
| | |
|
| | | bool canceled = false;
|
| | | int res = VsWaitDialog.UpdateProgress(message, progressText,
|
| | | statusBarText, currentStep, totalSteps, disableCancel, out canceled);
|
| | | statusBarText, currentStep, totalSteps, disableCancel, out bool canceled);
|
| | |
|
| | | if (res != VSConstants.S_OK)
|
| | | return;
|
| | |
| | |
|
| | | public void Stop()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (!Running)
|
| | | return;
|
| | |
|
| | | Running = false;
|
| | | int canceled = 0;
|
| | | VsWaitDialog.EndWaitDialog(out canceled);
|
| | | VsWaitDialog.EndWaitDialog(out int canceled);
|
| | | Canceled = (canceled != 0);
|
| | | }
|
| | |
|
| | | void IDisposable.Dispose()
|
| | | {
|
| | | Stop();
|
| | | ThreadHelper.JoinableTaskFactory.Run(async () => {
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | Stop();
|
| | | });
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | public abstract class Concurrent<TSubClass>
|
| | | where TSubClass : Concurrent<TSubClass>
|
| | | {
|
| | | private static readonly object _StaticCriticalSection = new object();
|
| | | protected static object StaticCriticalSection => _StaticCriticalSection;
|
| | | protected static object StaticCriticalSection { get; } = new object();
|
| | |
|
| | | private object _CriticalSection = null;
|
| | | protected object CriticalSection =>
|
| | | StaticThreadSafeInit(() => _CriticalSection, () => _CriticalSection = new object());
|
| | | protected object CriticalSection { get; } = new object();
|
| | |
|
| | | protected T ThreadSafeInit<T>(Func<T> getValue, Action init)
|
| | | where T : class
|
| | |
| | | {
|
| | | public class ConcurrentStopwatch : Concurrent<ConcurrentStopwatch>
|
| | | {
|
| | | Stopwatch Stopwatch { get; set; }
|
| | | Stopwatch Stopwatch { get; }
|
| | |
|
| | | public ConcurrentStopwatch()
|
| | | {
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.Runtime.Serialization;
|
| | |
|
| | | namespace QtVsTools.Json
|
| | |
| | | {
|
| | | #region //////////////////// Prototype ////////////////////////////////////////////////////
|
| | |
|
| | | protected Serializer Serializer { get; set; }
|
| | | private Serializer Serializer { get; set; }
|
| | |
|
| | | protected Serializable()
|
| | | { }
|
| | |
| | | var container = toDo.Dequeue();
|
| | | foreach (var defObj in container.PendingObjects) {
|
| | | defObj.Deserialize();
|
| | | var subContainer = defObj.Object as IDeferredObjectContainer;
|
| | | if (subContainer != null && subContainer.PendingObjects.Any())
|
| | | if (defObj.Object is IDeferredObjectContainer subContainer
|
| | | && subContainer.PendingObjects.Any()) {
|
| | | toDo.Enqueue(subContainer);
|
| | |
|
| | | }
|
| | | }
|
| | | }
|
| | | return obj;
|
| | |
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.ComponentModel;
|
| | | using System.Linq;
|
| | | using System.Reflection;
|
| | |
|
| | |
| | |
|
| | | class EnumStringAttribute : Attribute
|
| | | {
|
| | | public string ValueString { get; private set; }
|
| | | public string ValueString { get; }
|
| | |
|
| | | public EnumStringAttribute(string enumValueString)
|
| | | {
|
| | |
| | | using System.Runtime.Serialization.Json;
|
| | | using System.Text;
|
| | | using System.Xml;
|
| | | using QtVsTools.Core;
|
| | |
|
| | | /// <summary>
|
| | | /// The classes in this namespace provide support to the serialization and deserialization of
|
| | |
| | | serializer.WriteObject(writer, obj);
|
| | | writer.Close();
|
| | | return new JsonData() { Stream = stream };
|
| | | } catch (Exception e) {
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | if (stream != null && stream.CanRead && stream.Length > 0)
|
| | | stream.Dispose();
|
| | | System.Diagnostics.Debug.WriteLine(
|
| | | e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
|
| | | return null;
|
| | | }
|
| | | }
|
| | |
| | | using (reader = XmlReader.Create(data.XmlStream)) {
|
| | | var obj = serializer.ReadObject(reader, false);
|
| | |
|
| | | var container = obj as IDeferredObjectContainer;
|
| | | if (container != null)
|
| | | if (obj is IDeferredObjectContainer container)
|
| | | deferredObjects.ForEach(x => container.Add(x));
|
| | |
|
| | | return obj;
|
| | | }
|
| | |
|
| | | } catch (Exception e) {
|
| | | System.Diagnostics.Debug.WriteLine(
|
| | | e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | return null;
|
| | |
|
| | | } finally {
|
| | |
| | | data.XmlStream = new MemoryStream(xmlData);
|
| | | }
|
| | | return true;
|
| | | } catch (Exception e) {
|
| | | System.Diagnostics.Debug.WriteLine(
|
| | | e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
| | |
|
| | | #region //////////////////// Data Contract Surrogate //////////////////////////////////////
|
| | |
|
| | | static Exclusive<Serializer> sharedInstance = new Exclusive<Serializer>();
|
| | | static readonly Exclusive<Serializer> sharedInstance = new Exclusive<Serializer>();
|
| | | private XmlReader reader = null;
|
| | | private List<IDeferredObject> deferredObjects = new List<IDeferredObject>();
|
| | | private readonly List<IDeferredObject> deferredObjects = new List<IDeferredObject>();
|
| | |
|
| | | public static IJsonData GetCurrentJsonData()
|
| | | {
|
| | |
| | | root.Append("</root>");
|
| | | var xmlData = Encoding.UTF8.GetBytes(root.ToString());
|
| | | return new JsonData { XmlStream = new MemoryStream(xmlData) };
|
| | | } catch (Exception e) {
|
| | | System.Diagnostics.Debug.WriteLine(
|
| | | e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | return null;
|
| | | }
|
| | | }
|
| | |
| | | szTypeName = "";
|
| | | }
|
| | | public IntPtr hIcon;
|
| | | public int iIcon;
|
| | | public uint dwAttributes;
|
| | | private readonly int iIcon;
|
| | | private readonly uint dwAttributes;
|
| | | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
|
| | | public string szDisplayName;
|
| | | private readonly string szDisplayName;
|
| | | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_TYPE)]
|
| | | public string szTypeName;
|
| | | private readonly string szTypeName;
|
| | | };
|
| | |
|
| | | [Flags]
|
| | |
| | | public abstract class BasePriorityQueue<T, TPriority> : Concurrent, IEnumerable<T>
|
| | | where TPriority : IComparable<TPriority>
|
| | | {
|
| | | SortedDictionary<TPriority, T> ItemsByPriority { get; set; }
|
| | | Dictionary<object, TPriority> ItemPriority { get; set; }
|
| | | SortedDictionary<TPriority, T> ItemsByPriority { get; }
|
| | | Dictionary<object, TPriority> ItemPriority { get; }
|
| | | T Head { get; set; }
|
| | | public int Count { get; private set; }
|
| | | public bool IsEmpty => (Count == 0);
|
| | |
| | | IEnumerator<T> IEnumerable<T>.GetEnumerator() => Items.GetEnumerator();
|
| | | IEnumerator IEnumerable.GetEnumerator() => Items.GetEnumerator();
|
| | |
|
| | | Func<T, object> GetItemKey { get; set; }
|
| | | Func<T, object> GetItemKey { get; }
|
| | |
|
| | | public BasePriorityQueue() : this(x => x)
|
| | | { }
|
| | |
| | | if (item == null)
|
| | | throw new InvalidOperationException("Item cannot be null.");
|
| | | lock (CriticalSection) {
|
| | | T oldItem;
|
| | | if (ItemsByPriority.TryGetValue(priority, out oldItem) && !item.Equals(oldItem))
|
| | | if (ItemsByPriority.TryGetValue(priority, out T oldItem) && !item.Equals(oldItem))
|
| | | throw new InvalidOperationException("An item with the same priority exists.");
|
| | | TPriority oldPriority;
|
| | | if (ItemPriority.TryGetValue(GetItemKey(item), out oldPriority)) {
|
| | |
|
| | | if (ItemPriority.TryGetValue(GetItemKey(item), out TPriority oldPriority)) {
|
| | | ItemsByPriority.Remove(oldPriority);
|
| | | --Count;
|
| | | }
|
| | |
| | | public T Peek()
|
| | | {
|
| | | lock (CriticalSection) {
|
| | | T result;
|
| | | if (!TryPeek(out result))
|
| | | if (!TryPeek(out T result))
|
| | | throw new InvalidOperationException("Queue is empty.");
|
| | | return result;
|
| | | }
|
| | |
| | | public T Dequeue()
|
| | | {
|
| | | lock (CriticalSection) {
|
| | | T result;
|
| | | if (!TryDequeue(out result))
|
| | | if (!TryDequeue(out T result))
|
| | | throw new InvalidOperationException("Queue is empty.");
|
| | | return result;
|
| | | }
|
| | |
| | |
|
| | | static readonly object classCriticalSection = new object();
|
| | |
|
| | | static Dictionary<Type, List<Type>> types = GetTypeHierarchy(typeof(TBase));
|
| | | static readonly Dictionary<Type, List<Type>> types = GetTypeHierarchy(typeof(TBase));
|
| | |
|
| | | static Dictionary<Type, List<Type>> GetTypeHierarchy(Type baseType)
|
| | | {
|
| | |
| | | return subTypes;
|
| | | }
|
| | |
|
| | | static Dictionary<Type, SubClass> classes = types
|
| | | static readonly Dictionary<Type, SubClass> classes = types
|
| | | .ToDictionary(x => x.Key, x => Create(x.Key, x.Value));
|
| | |
|
| | | static SubClass Create(Type type, IEnumerable<Type> subTypes)
|
| | |
| | |
|
| | | lock (classCriticalSection) {
|
| | |
|
| | | SubClass subClass = null;
|
| | | if (!classes.TryGetValue(type, out subClass)) {
|
| | | if (!classes.TryGetValue(type, out SubClass subClass)) {
|
| | |
|
| | | var newTypes = GetTypeHierarchy(type)
|
| | | .Where(x => !classes.ContainsKey(x.Key));
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | public static SubClass baseClass = Get(typeof(TBase));
|
| | | public static readonly SubClass baseClass = Get(typeof(TBase));
|
| | | }
|
| | |
|
| | | #endregion //////////////////// SubClass //////////////////////////////////////////////////
|
| | |
| | |
|
| | | namespace QtVsTools
|
| | | {
|
| | | using Common;
|
| | |
|
| | | public class Timestamp : Concurrent<Timestamp>
|
| | | {
|
| | | static LazyFactory StaticLazy { get; } = new LazyFactory();
|
| | |
|
| | | long LastTimestamp { get; set; }
|
| | | long GetStrictMonotonicTimestamp()
|
| | | {
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | static Timestamp _Instance;
|
| | | static Timestamp Instance =>
|
| | | StaticThreadSafeInit(() => _Instance, () => _Instance = new Timestamp());
|
| | | static Timestamp Instance => StaticLazy.Get(() =>
|
| | | Instance, () => new Timestamp());
|
| | |
|
| | | public static long Next()
|
| | | {
|
| | |
| | | using System.IO;
|
| | | using System.Runtime.InteropServices;
|
| | | using System.Threading.Tasks;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | | using QtVsTools.QtMsBuild;
|
| | | using QtVsTools.VisualStudio;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | |
|
| | | using Task = System.Threading.Tasks.Task;
|
| | |
|
| | | namespace QtVsTools.Editors
|
| | | {
|
| | | using QtMsBuild;
|
| | | using VisualStudio;
|
| | |
|
| | | [Guid(GuidString)]
|
| | | public class QtDesigner : Editor
|
| | | {
|
| | |
| | |
|
| | | protected override void OnStart(Process process)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | base.OnStart(process);
|
| | | var document = VsShell.GetDocument(Context, ItemId);
|
| | | if (document == null)
|
| | | return;
|
| | |
|
| | | var project = document.ProjectItem?.ContainingProject;
|
| | | if (project == null || !QtProjectTracker.IsTracked(project))
|
| | | if (project == null || !QtProjectTracker.IsTracked(project.FullName))
|
| | | return;
|
| | | string projectPath = project.FullName;
|
| | | string filePath = document.FullName;
|
| | | string[] itemId = new[] { document.ProjectItem?.Name };
|
| | | var lastWriteTime = File.GetLastWriteTime(filePath);
|
| | | Task.Run(() =>
|
| | | _ = Task.Run(async () =>
|
| | | {
|
| | | while (!process.WaitForExit(1000)) {
|
| | | var latestWriteTime = File.GetLastWriteTime(filePath);
|
| | | if (lastWriteTime != latestWriteTime) {
|
| | | lastWriteTime = latestWriteTime;
|
| | | QtProjectIntellisense.Refresh(project, selectedFiles: itemId);
|
| | | await QtProjectIntellisense.RefreshAsync(project, projectPath);
|
| | | }
|
| | | }
|
| | | if (lastWriteTime != File.GetLastWriteTime(filePath)) {
|
| | | QtProjectIntellisense.Refresh(project, selectedFiles: itemId);
|
| | | await QtProjectIntellisense.RefreshAsync(project, projectPath);
|
| | | }
|
| | | });
|
| | | }
|
| | |
| | | using System;
|
| | | using System.Diagnostics;
|
| | | using System.Runtime.InteropServices;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | |
|
| | | namespace QtVsTools.Editors
|
| | | {
|
| | |
| | |
|
| | | public override string ExecutableName => "QrcEditor.exe";
|
| | |
|
| | | protected override string GetToolsPath()
|
| | | {
|
| | | return QtVsToolsPackage.Instance?.PkgInstallPath;
|
| | | }
|
| | | protected override string GetToolsPath() =>
|
| | | QtVsToolsPackage.Instance?.PkgInstallPath;
|
| | |
|
| | | public override Func<string, bool> WindowFilter =>
|
| | | caption => caption.StartsWith(Title);
|
| | |
|
| | | protected override string GetTitle(Process editorProcess)
|
| | | {
|
| | | return Title;
|
| | | }
|
| | | protected override string GetTitle(Process editorProcess) => Title;
|
| | |
|
| | | protected override bool Detached => QtVsToolsPackage.Instance.Options.ResourceEditorDetached;
|
| | | }
|
| | |
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using QtVsTools.Core;
|
| | | using QtVsTools.VisualStudio;
|
| | |
|
| | | namespace QtVsTools.Editors
|
| | | {
|
| | | using Core;
|
| | | using VisualStudio;
|
| | |
|
| | | using static Core.HelperFunctions;
|
| | |
|
| | | public abstract class Editor : IVsEditorFactory
|
| | |
| | |
|
| | | protected virtual string GetToolsPath()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return GetQtToolsPath() ?? GetDefaultQtToolsPath();
|
| | | }
|
| | |
|
| | |
| | |
|
| | | string GetQtToolsPath()
|
| | | {
|
| | | var project = VsShell.GetProject(Context);
|
| | | if (project == null)
|
| | | return null;
|
| | | return ThreadHelper.JoinableTaskFactory.Run(async () =>
|
| | | {
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | var project = VsShell.GetProject(Context);
|
| | | if (project == null)
|
| | | return null;
|
| | |
|
| | | var vcProject = project.Object as VCProject;
|
| | | if (vcProject == null)
|
| | | return null;
|
| | | var vcProject = project.Object as VCProject;
|
| | | if (vcProject == null)
|
| | | return null;
|
| | |
|
| | | var vcConfigs = vcProject.Configurations as IVCCollection;
|
| | | if (vcConfigs == null)
|
| | | return null;
|
| | | var vcConfigs = vcProject.Configurations as IVCCollection;
|
| | | if (vcConfigs == null)
|
| | | return null;
|
| | |
|
| | | var activeConfig = project.ConfigurationManager?.ActiveConfiguration;
|
| | | if (activeConfig == null)
|
| | | return null;
|
| | | var activeConfig = project.ConfigurationManager?.ActiveConfiguration;
|
| | | if (activeConfig == null)
|
| | | return null;
|
| | |
|
| | | var activeConfigId = string.Format("{0}|{1}",
|
| | | activeConfig.ConfigurationName, activeConfig.PlatformName);
|
| | | var vcConfig = vcConfigs.Item(activeConfigId) as VCConfiguration;
|
| | | if (vcConfig == null)
|
| | | return null;
|
| | | var activeConfigId = string.Format("{0}|{1}",
|
| | | activeConfig.ConfigurationName, activeConfig.PlatformName);
|
| | | var vcConfig = vcConfigs.Item(activeConfigId) as VCConfiguration;
|
| | | if (vcConfig == null)
|
| | | return null;
|
| | |
|
| | | var qtToolsPath = vcConfig.GetEvaluatedPropertyValue("QtToolsPath");
|
| | | if (string.IsNullOrEmpty(qtToolsPath))
|
| | | return null;
|
| | | var qtToolsPath = vcConfig.GetEvaluatedPropertyValue("QtToolsPath");
|
| | | if (string.IsNullOrEmpty(qtToolsPath))
|
| | | return null;
|
| | |
|
| | | return qtToolsPath;
|
| | | return qtToolsPath;
|
| | | });
|
| | | }
|
| | |
|
| | | string GetDefaultQtToolsPath()
|
| | |
| | | out Guid pguidCmdUI,
|
| | | out int pgrfCDW)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | // Initialize to null
|
| | | ppunkDocView = IntPtr.Zero;
|
| | | ppunkDocData = IntPtr.Zero;
|
| | |
| | | {
|
| | | if (string.IsNullOrEmpty(qtToolsPath))
|
| | | qtToolsPath = GetDefaultQtToolsPath();
|
| | | var st = GetStartInfo(filePath, qtToolsPath, hideWindow);
|
| | | try {
|
| | | return Process.Start(GetStartInfo(filePath, qtToolsPath, hideWindow));
|
| | | } catch (Exception e) {
|
| | | Messages.Print(
|
| | | e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
|
| | | return Process.Start(st);
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | if (!File.Exists(st.Arguments))
|
| | | Messages.Print("The system cannot find the file: " + st.Arguments);
|
| | | if (!File.Exists(st.FileName))
|
| | | Messages.Print("The system cannot find the file: " + st.FileName);
|
| | | return null;
|
| | | }
|
| | | }
|
| | |
| | |
|
| | | private class EditorPane : WindowPane, IVsPersistDocData
|
| | | {
|
| | | public Editor Editor { get; private set; }
|
| | | public string QtToolsPath { get; private set; }
|
| | | private Editor Editor { get; }
|
| | | private string QtToolsPath { get; }
|
| | |
|
| | | public TableLayoutPanel EditorContainer { get; private set; }
|
| | | public Label EditorTitle { get; private set; }
|
| | | public LinkLabel EditorDetachButton { get; private set; }
|
| | | public Panel EditorControl { get; private set; }
|
| | | private TableLayoutPanel EditorContainer { get; set; }
|
| | | private Label EditorTitle { get; }
|
| | | private LinkLabel EditorDetachButton { get; }
|
| | | private Panel EditorControl { get; }
|
| | | public override IWin32Window Window => EditorContainer;
|
| | |
|
| | | public Process EditorProcess { get; private set; }
|
| | | public IntPtr EditorWindow { get; private set; }
|
| | | public int EditorWindowStyle { get; private set; }
|
| | | public int EditorWindowStyleExt { get; private set; }
|
| | | public IntPtr EditorIcon { get; private set; }
|
| | | private Process EditorProcess { get; set; }
|
| | | private IntPtr EditorWindow { get; set; }
|
| | | private int EditorWindowStyle { get; set; }
|
| | | private int EditorWindowStyleExt { get; set; }
|
| | | private IntPtr EditorIcon { get; set; }
|
| | |
|
| | | public EditorPane(Editor editor, string qtToolsPath)
|
| | | {
|
| | |
| | |
|
| | | int IVsPersistDocData.LoadDocData(string pszMkDocument)
|
| | | {
|
| | | var solution = GetService(typeof(SVsSolution)) as IVsSolution;
|
| | | EditorProcess = Editor.Start(pszMkDocument, QtToolsPath,
|
| | | hideWindow: !Editor.Detached);
|
| | | if (EditorProcess == null)
|
| | | return VSConstants.E_FAIL;
|
| | |
|
| | | if (Editor.Detached) {
|
| | | Editor.OnStart(EditorProcess);
|
| | | CloseParentFrame();
|
| | |
| | | {
|
| | | EditorProcess = null;
|
| | | EditorWindow = IntPtr.Zero;
|
| | | var parentFrame = GetService(typeof(SVsWindowFrame)) as IVsWindowFrame;
|
| | | parentFrame?.CloseFrame((uint)__FRAMECLOSE.FRAMECLOSE_NoSave);
|
| | | ThreadHelper.JoinableTaskFactory.Run(async () =>
|
| | | {
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | var parentFrame = GetService(typeof(SVsWindowFrame)) as IVsWindowFrame;
|
| | | parentFrame?.CloseFrame((uint)__FRAMECLOSE.FRAMECLOSE_NoSave);
|
| | | });
|
| | | }
|
| | |
|
| | | private void EditorProcess_Exited(object sender, EventArgs e)
|
| | |
| | | EditorWindow = IntPtr.Zero;
|
| | |
|
| | | // Close editor window
|
| | | System.Threading.Tasks.Task.Run(() =>
|
| | | _ = System.Threading.Tasks.Task.Run(() =>
|
| | | {
|
| | | NativeAPI.SendMessage(editorWindow, NativeAPI.WM_CLOSE, 0, 0);
|
| | | if (!editorProcess.WaitForExit(500)) {
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <ImageManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
| | | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
| | | xmlns="http://schemas.microsoft.com/VisualStudio/ImageManifestSchema/2014">
|
| | | <Symbols>
|
| | | <String Name="Resources" Value="/QtVsTools;Component/Icons" />
|
| | | <Guid Name="QtMonikersGuid" Value="{0d2e443f-6dbb-4001-99dc-9cd7d5c924e7}" />
|
| | | <ID Name="prf" Value="0" />
|
| | | <ID Name="pri" Value="1" />
|
| | | <ID Name="pro" Value="2" />
|
| | | <ID Name="qml" Value="3" />
|
| | | <ID Name="qrc" Value="4" />
|
| | | <ID Name="ts" Value="5" />
|
| | | <ID Name="ui" Value="6" />
|
| | | </Symbols>
|
| | | <Images>
|
| | | <Image Guid="$(QtMonikersGuid)" ID="$(prf)">
|
| | | <Source Uri="$(Resources)/prf32.png">
|
| | | <Size Value="32" />
|
| | | </Source>
|
| | | </Image>
|
| | | <Image Guid="$(QtMonikersGuid)" ID="$(pri)">
|
| | | <Source Uri="$(Resources)/pri32.png">
|
| | | <Size Value="32" />
|
| | | </Source>
|
| | | </Image>
|
| | | <Image Guid="$(QtMonikersGuid)" ID="$(pro)">
|
| | | <Source Uri="$(Resources)/pro32.png">
|
| | | <Size Value="32" />
|
| | | </Source>
|
| | | </Image>
|
| | | <Image Guid="$(QtMonikersGuid)" ID="$(qml)">
|
| | | <Source Uri="$(Resources)/qml32.png">
|
| | | <Size Value="32" />
|
| | | </Source>
|
| | | </Image>
|
| | | <Image Guid="$(QtMonikersGuid)" ID="$(qrc)">
|
| | | <Source Uri="$(Resources)/qrc32.png">
|
| | | <Size Value="32" />
|
| | | </Source>
|
| | | </Image>
|
| | | <Image Guid="$(QtMonikersGuid)" ID="$(ts)">
|
| | | <Source Uri="$(Resources)/ts32.png">
|
| | | <Size Value="32" />
|
| | | </Source>
|
| | | </Image>
|
| | | <Image Guid="$(QtMonikersGuid)" ID="$(ui)">
|
| | | <Source Uri="$(Resources)/ui32.png">
|
| | | <Size Value="32" />
|
| | | </Source>
|
| | | </Image>
|
| | | </Images>
|
| | | <ImageLists />
|
| | | </ImageManifest>
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | namespace QtVsTools.Legacy
|
| | | {
|
| | | internal enum ChangeFor { Solution, Project }
|
| | | }
|
New file |
| | |
| | | namespace QtVsTools.Legacy
|
| | | {
|
| | | partial class FormChangeQtVersion
|
| | | {
|
| | |
|
| | | #region Windows Form Designer generated code
|
| | |
|
| | | /// <summary>
|
| | | /// Required method for Designer support - do not modify
|
| | | /// the contents of this method with the code editor.
|
| | | /// </summary>
|
| | | private void InitializeComponent()
|
| | | {
|
| | | btnOK = new System.Windows.Forms.Button();
|
| | | btnCancel = new System.Windows.Forms.Button();
|
| | | lbQtVersions = new System.Windows.Forms.ListBox();
|
| | | lQtVersions = new System.Windows.Forms.Label();
|
| | | SuspendLayout();
|
| | | //
|
| | | // btnOK
|
| | | //
|
| | | btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
|
| | | btnOK.Location = new System.Drawing.Point(124, 231);
|
| | | btnOK.Name = "btnOK";
|
| | | btnOK.Size = new System.Drawing.Size(75, 23);
|
| | | btnOK.TabIndex = 1;
|
| | | btnOK.Text = "&OK";
|
| | | btnOK.UseVisualStyleBackColor = true;
|
| | | //
|
| | | // btnCancel
|
| | | //
|
| | | btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
| | | btnCancel.Location = new System.Drawing.Point(205, 231);
|
| | | btnCancel.Name = "btnCancel";
|
| | | btnCancel.Size = new System.Drawing.Size(75, 23);
|
| | | btnCancel.TabIndex = 2;
|
| | | btnCancel.Text = "&Cancel";
|
| | | btnCancel.UseVisualStyleBackColor = true;
|
| | | //
|
| | | // lbQtVersions
|
| | | //
|
| | | lbQtVersions.FormattingEnabled = true;
|
| | | lbQtVersions.Location = new System.Drawing.Point(13, 39);
|
| | | lbQtVersions.Name = "lbQtVersions";
|
| | | lbQtVersions.Size = new System.Drawing.Size(267, 173);
|
| | | lbQtVersions.TabIndex = 0;
|
| | | //
|
| | | // lQtVersions
|
| | | //
|
| | | lQtVersions.AutoSize = true;
|
| | | lQtVersions.Location = new System.Drawing.Point(13, 20);
|
| | | lQtVersions.Name = "lQtVersions";
|
| | | lQtVersions.Size = new System.Drawing.Size(103, 13);
|
| | | lQtVersions.TabIndex = 3;
|
| | | lQtVersions.Text = "Installed Qt Versions";
|
| | | //
|
| | | // FormChangeQtVersion
|
| | | //
|
| | | AcceptButton = btnOK;
|
| | | AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
| | | AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
| | | CancelButton = btnCancel;
|
| | | ClientSize = new System.Drawing.Size(292, 266);
|
| | | Controls.Add(lQtVersions);
|
| | | Controls.Add(lbQtVersions);
|
| | | Controls.Add(btnCancel);
|
| | | Controls.Add(btnOK);
|
| | | FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
| | | KeyPreview = true;
|
| | | MaximizeBox = false;
|
| | | MinimizeBox = false;
|
| | | Name = "FormChangeQtVersion";
|
| | | ShowInTaskbar = false;
|
| | | Text = "FormChangeQtVersion";
|
| | | ResumeLayout(false);
|
| | | PerformLayout();
|
| | |
|
| | | }
|
| | |
|
| | | #endregion
|
| | |
|
| | | private System.Windows.Forms.Button btnOK;
|
| | | private System.Windows.Forms.Button btnCancel;
|
| | | private System.Windows.Forms.ListBox lbQtVersions;
|
| | | private System.Windows.Forms.Label lQtVersions;
|
| | | }
|
| | | }
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Windows.Forms;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | |
|
| | | namespace QtVsTools.Legacy
|
| | | {
|
| | | using Core;
|
| | | using Legacy = Core.Legacy;
|
| | |
|
| | | public partial class FormChangeQtVersion : Form
|
| | | {
|
| | | public FormChangeQtVersion()
|
| | | {
|
| | | InitializeComponent();
|
| | | btnOK.Text = "&OK";
|
| | | btnCancel.Text = "&Cancel";
|
| | | lQtVersions.Text = "Installed Qt Versions";
|
| | | lbQtVersions.DoubleClick += OnQtVersions_DoubleClick;
|
| | | KeyPress += FormChangeQtVersion_KeyPress;
|
| | | Shown += FormChangeQtVersion_Shown;
|
| | | }
|
| | |
|
| | | private void FormChangeQtVersion_Shown(object sender, EventArgs e)
|
| | | {
|
| | | Text = "Set Solution's Qt Version";
|
| | | }
|
| | |
|
| | | void OnQtVersions_DoubleClick(object sender, EventArgs e)
|
| | | {
|
| | | DialogResult = DialogResult.OK;
|
| | | Close();
|
| | | }
|
| | |
|
| | | void FormChangeQtVersion_KeyPress(object sender, KeyPressEventArgs e)
|
| | | {
|
| | | if (e.KeyChar == 27) {
|
| | | DialogResult = DialogResult.Cancel;
|
| | | Close();
|
| | | }
|
| | | }
|
| | |
|
| | | internal void UpdateContent(ChangeFor change)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | lbQtVersions.Items.Clear();
|
| | | var vm = QtVersionManager.The();
|
| | | foreach (var versionName in vm.GetVersions())
|
| | | lbQtVersions.Items.Add(versionName);
|
| | |
|
| | | lbQtVersions.Items.Add("$(DefaultQtVersion)");
|
| | | if (change == ChangeFor.Solution) {
|
| | | var qtVer = Legacy.QtVersionManager
|
| | | .GetSolutionQtVersion(QtVsToolsPackage.Instance.Dte.Solution);
|
| | | if (qtVer == null)
|
| | | qtVer = vm.GetDefaultVersion();
|
| | | if (qtVer != null)
|
| | | lbQtVersions.SelectedItem = qtVer;
|
| | | Text = "Set Solution's Qt Version";
|
| | | } else {
|
| | | var pro = Core.HelperFunctions.GetSelectedProject(QtVsToolsPackage.Instance.Dte);
|
| | | var qtVer = vm.GetProjectQtVersion(pro);
|
| | | if (qtVer == null)
|
| | | qtVer = vm.GetDefaultVersion();
|
| | | if (qtVer != null)
|
| | | lbQtVersions.SelectedItem = qtVer;
|
| | | Text = "Set Project's Qt Version";
|
| | | }
|
| | | }
|
| | |
|
| | | public string GetSelectedQtVersion()
|
| | | {
|
| | | var idx = lbQtVersions.SelectedIndex;
|
| | | if (idx < 0)
|
| | | return null;
|
| | | return lbQtVersions.Items[idx].ToString();
|
| | | }
|
| | | }
|
| | | }
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <root>
|
| | | <!--
|
| | | Microsoft ResX Schema
|
| | |
|
| | | Version 2.0
|
| | |
|
| | | The primary goals of this format is to allow a simple XML format
|
| | | that is mostly human readable. The generation and parsing of the
|
| | | various data types are done through the TypeConverter classes
|
| | | associated with the data types.
|
| | |
|
| | | Example:
|
| | |
|
| | | ... ado.net/XML headers & schema ...
|
| | | <resheader name="resmimetype">text/microsoft-resx</resheader>
|
| | | <resheader name="version">2.0</resheader>
|
| | | <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
| | | <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
| | | <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
| | | <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
| | | <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
| | | <value>[base64 mime encoded serialized .NET Framework object]</value>
|
| | | </data>
|
| | | <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
| | | <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
| | | <comment>This is a comment</comment>
|
| | | </data>
|
| | |
|
| | | There are any number of "resheader" rows that contain simple
|
| | | name/value pairs.
|
| | |
|
| | | Each data row contains a name, and value. The row also contains a
|
| | | type or mimetype. Type corresponds to a .NET class that support
|
| | | text/value conversion through the TypeConverter architecture.
|
| | | Classes that don't support this are serialized and stored with the
|
| | | mimetype set.
|
| | |
|
| | | The mimetype is used for serialized objects, and tells the
|
| | | ResXResourceReader how to depersist the object. This is currently not
|
| | | extensible. For a given mimetype the value must be set accordingly:
|
| | |
|
| | | Note - application/x-microsoft.net.object.binary.base64 is the format
|
| | | that the ResXResourceWriter will generate, however the reader can
|
| | | read any of the formats listed below.
|
| | |
|
| | | mimetype: application/x-microsoft.net.object.binary.base64
|
| | | value : The object must be serialized with
|
| | | : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
| | | : and then encoded with base64 encoding.
|
| | |
|
| | | mimetype: application/x-microsoft.net.object.soap.base64
|
| | | value : The object must be serialized with
|
| | | : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
| | | : and then encoded with base64 encoding.
|
| | |
|
| | | mimetype: application/x-microsoft.net.object.bytearray.base64
|
| | | value : The object must be serialized into a byte array
|
| | | : using a System.ComponentModel.TypeConverter
|
| | | : and then encoded with base64 encoding.
|
| | | -->
|
| | | <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
| | | <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
| | | <xsd:element name="root" msdata:IsDataSet="true">
|
| | | <xsd:complexType>
|
| | | <xsd:choice maxOccurs="unbounded">
|
| | | <xsd:element name="metadata">
|
| | | <xsd:complexType>
|
| | | <xsd:sequence>
|
| | | <xsd:element name="value" type="xsd:string" minOccurs="0" />
|
| | | </xsd:sequence>
|
| | | <xsd:attribute name="name" use="required" type="xsd:string" />
|
| | | <xsd:attribute name="type" type="xsd:string" />
|
| | | <xsd:attribute name="mimetype" type="xsd:string" />
|
| | | <xsd:attribute ref="xml:space" />
|
| | | </xsd:complexType>
|
| | | </xsd:element>
|
| | | <xsd:element name="assembly">
|
| | | <xsd:complexType>
|
| | | <xsd:attribute name="alias" type="xsd:string" />
|
| | | <xsd:attribute name="name" type="xsd:string" />
|
| | | </xsd:complexType>
|
| | | </xsd:element>
|
| | | <xsd:element name="data">
|
| | | <xsd:complexType>
|
| | | <xsd:sequence>
|
| | | <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
| | | <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
| | | </xsd:sequence>
|
| | | <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
| | | <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
| | | <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
| | | <xsd:attribute ref="xml:space" />
|
| | | </xsd:complexType>
|
| | | </xsd:element>
|
| | | <xsd:element name="resheader">
|
| | | <xsd:complexType>
|
| | | <xsd:sequence>
|
| | | <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
| | | </xsd:sequence>
|
| | | <xsd:attribute name="name" type="xsd:string" use="required" />
|
| | | </xsd:complexType>
|
| | | </xsd:element>
|
| | | </xsd:choice>
|
| | | </xsd:complexType>
|
| | | </xsd:element>
|
| | | </xsd:schema>
|
| | | <resheader name="resmimetype">
|
| | | <value>text/microsoft-resx</value>
|
| | | </resheader>
|
| | | <resheader name="version">
|
| | | <value>2.0</value>
|
| | | </resheader>
|
| | | <resheader name="reader">
|
| | | <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
| | | </resheader>
|
| | | <resheader name="writer">
|
| | | <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
| | | </resheader>
|
| | | </root> |
New file |
| | |
| | | using System.Windows.Forms;
|
| | |
|
| | | namespace QtVsTools.Legacy
|
| | | {
|
| | | partial class FormProjectQtSettings
|
| | | {
|
| | |
|
| | | #region Windows Form Designer generated code
|
| | |
|
| | | /// <summary>
|
| | | /// Required method for Designer support - do not modify
|
| | | /// the contents of this method with the code editor.
|
| | | /// </summary>
|
| | | private void InitializeComponent()
|
| | | {
|
| | | this.OptionsPropertyGrid = new System.Windows.Forms.PropertyGrid();
|
| | | this.panel1 = new System.Windows.Forms.Panel();
|
| | | this.okButton = new System.Windows.Forms.Button();
|
| | | this.cancelButton = new System.Windows.Forms.Button();
|
| | | this.tabControl1 = new System.Windows.Forms.TabControl();
|
| | | this.tabPage1 = new System.Windows.Forms.TabPage();
|
| | | this.tabPage2 = new System.Windows.Forms.TabPage();
|
| | | this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
|
| | | this.panel1.SuspendLayout();
|
| | | this.tabControl1.SuspendLayout();
|
| | | this.tabPage1.SuspendLayout();
|
| | | this.tabPage2.SuspendLayout();
|
| | | this.SuspendLayout();
|
| | | //
|
| | | // OptionsPropertyGrid
|
| | | //
|
| | | this.OptionsPropertyGrid.Dock = System.Windows.Forms.DockStyle.Fill;
|
| | | this.OptionsPropertyGrid.HelpVisible = false;
|
| | | this.OptionsPropertyGrid.Location = new System.Drawing.Point(6, 6);
|
| | | this.OptionsPropertyGrid.Margin = new System.Windows.Forms.Padding(6);
|
| | | this.OptionsPropertyGrid.Name = "OptionsPropertyGrid";
|
| | | this.OptionsPropertyGrid.PropertySort = System.Windows.Forms.PropertySort.Alphabetical;
|
| | | this.OptionsPropertyGrid.Size = new System.Drawing.Size(898, 603);
|
| | | this.OptionsPropertyGrid.TabIndex = 8;
|
| | | this.OptionsPropertyGrid.ToolbarVisible = false;
|
| | | //
|
| | | // panel1
|
| | | //
|
| | | this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
| | | this.panel1.Controls.Add(this.okButton);
|
| | | this.panel1.Controls.Add(this.cancelButton);
|
| | | this.panel1.Location = new System.Drawing.Point(620, 700);
|
| | | this.panel1.Margin = new System.Windows.Forms.Padding(6);
|
| | | this.panel1.Name = "panel1";
|
| | | this.panel1.Size = new System.Drawing.Size(336, 73);
|
| | | this.panel1.TabIndex = 9;
|
| | | //
|
| | | // okButton
|
| | | //
|
| | | this.okButton.Location = new System.Drawing.Point(16, 15);
|
| | | this.okButton.Margin = new System.Windows.Forms.Padding(6);
|
| | | this.okButton.Name = "okButton";
|
| | | this.okButton.Size = new System.Drawing.Size(150, 44);
|
| | | this.okButton.TabIndex = 0;
|
| | | this.okButton.Click += new System.EventHandler(this.OkButton_Click);
|
| | | this.okButton.Text = "&OK";
|
| | | //
|
| | | // cancelButton
|
| | | //
|
| | | this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
| | | this.cancelButton.Location = new System.Drawing.Point(176, 15);
|
| | | this.cancelButton.Margin = new System.Windows.Forms.Padding(6);
|
| | | this.cancelButton.Name = "cancelButton";
|
| | | this.cancelButton.Size = new System.Drawing.Size(150, 44);
|
| | | this.cancelButton.TabIndex = 1;
|
| | | this.cancelButton.Text = "Cancel";
|
| | | //
|
| | | // tabControl1
|
| | | //
|
| | | this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
| | | | System.Windows.Forms.AnchorStyles.Left)
|
| | | | System.Windows.Forms.AnchorStyles.Right)));
|
| | | this.tabControl1.Controls.Add(this.tabPage1);
|
| | | this.tabControl1.Controls.Add(this.tabPage2);
|
| | | this.tabControl1.Location = new System.Drawing.Point(24, 23);
|
| | | this.tabControl1.Margin = new System.Windows.Forms.Padding(6);
|
| | | this.tabControl1.Name = "tabControl1";
|
| | | this.tabControl1.SelectedIndex = 0;
|
| | | this.tabControl1.Size = new System.Drawing.Size(926, 662);
|
| | | this.tabControl1.TabIndex = 10;
|
| | | //
|
| | | // tabPage1
|
| | | //
|
| | | this.tabPage1.BackColor = System.Drawing.SystemColors.Control;
|
| | | this.tabPage1.Controls.Add(this.OptionsPropertyGrid);
|
| | | this.tabPage1.Location = new System.Drawing.Point(8, 39);
|
| | | this.tabPage1.Margin = new System.Windows.Forms.Padding(6);
|
| | | this.tabPage1.Name = "tabPage1";
|
| | | this.tabPage1.Padding = new System.Windows.Forms.Padding(6);
|
| | | this.tabPage1.Size = new System.Drawing.Size(910, 615);
|
| | | this.tabPage1.TabIndex = 0;
|
| | | this.tabPage1.Text = "Properties";
|
| | | //
|
| | | // tabPage2
|
| | | //
|
| | | this.tabPage2.BackColor = System.Drawing.SystemColors.Control;
|
| | | this.tabPage2.Controls.Add(this.flowLayoutPanel1);
|
| | | this.tabPage2.Location = new System.Drawing.Point(8, 39);
|
| | | this.tabPage2.Margin = new System.Windows.Forms.Padding(6);
|
| | | this.tabPage2.Name = "tabPage2";
|
| | | this.tabPage2.Padding = new System.Windows.Forms.Padding(6);
|
| | | this.tabPage2.Size = new System.Drawing.Size(910, 615);
|
| | | this.tabPage2.TabIndex = 1;
|
| | | this.tabPage2.Text = "Qt Modules";
|
| | | //
|
| | | // flowLayoutPanel1
|
| | | //
|
| | | this.flowLayoutPanel1.AutoScroll = true;
|
| | | this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
| | | this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
| | | this.flowLayoutPanel1.Location = new System.Drawing.Point(6, 6);
|
| | | this.flowLayoutPanel1.Name = "flowLayoutPanel1";
|
| | | this.flowLayoutPanel1.Size = new System.Drawing.Size(898, 603);
|
| | | this.flowLayoutPanel1.TabIndex = 66;
|
| | | //
|
| | | // FormProjectQtSettings
|
| | | //
|
| | | this.AcceptButton = this.okButton;
|
| | | this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F);
|
| | | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
| | | this.CancelButton = this.cancelButton;
|
| | | this.ClientSize = new System.Drawing.Size(962, 801);
|
| | | this.Controls.Add(this.tabControl1);
|
| | | this.Controls.Add(this.panel1);
|
| | | this.KeyPreview = true;
|
| | | this.Margin = new System.Windows.Forms.Padding(6);
|
| | | this.MaximizeBox = false;
|
| | | this.MinimizeBox = false;
|
| | | this.MinimumSize = new System.Drawing.Size(988, 750);
|
| | | this.Name = "FormProjectQtSettings";
|
| | | this.ShowIcon = false;
|
| | | this.ShowInTaskbar = false;
|
| | | this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show;
|
| | | this.Text = "Qt Project Settings";
|
| | | this.panel1.ResumeLayout(false);
|
| | | this.tabControl1.ResumeLayout(false);
|
| | | this.tabPage1.ResumeLayout(false);
|
| | | this.tabPage2.ResumeLayout(false);
|
| | | this.ResumeLayout(false);
|
| | |
|
| | | }
|
| | |
|
| | | #endregion
|
| | |
|
| | | private PropertyGrid OptionsPropertyGrid;
|
| | | private Panel panel1;
|
| | | private Button okButton;
|
| | | private Button cancelButton;
|
| | | private TabControl tabControl1;
|
| | | private TabPage tabPage1;
|
| | | private TabPage tabPage2;
|
| | | private FlowLayoutPanel flowLayoutPanel1;
|
| | | }
|
| | | }
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.ComponentModel;
|
| | | using System.Linq;
|
| | | using System.Windows.Forms;
|
| | | using System.IO;
|
| | | using EnvDTE;
|
| | |
|
| | | namespace QtVsTools.Legacy
|
| | | {
|
| | | using Core;
|
| | | using Legacy = Core.Legacy;
|
| | |
|
| | | public partial class FormProjectQtSettings : Form
|
| | | {
|
| | | private readonly Project project;
|
| | | private readonly ProjectQtSettings qtSettings;
|
| | | private readonly List<ModuleItem> moduleMap = new List<ModuleItem>();
|
| | |
|
| | | private struct ModuleItem
|
| | | {
|
| | | public readonly CheckBox checkbox;
|
| | | public readonly int moduleId;
|
| | | public bool initialValue;
|
| | |
|
| | | public ModuleItem(CheckBox cb, int mid, bool init)
|
| | | {
|
| | | checkbox = cb;
|
| | | moduleId = mid;
|
| | | initialValue = init;
|
| | | }
|
| | | }
|
| | |
|
| | | public FormProjectQtSettings(Project pro)
|
| | | {
|
| | | InitializeComponent();
|
| | |
|
| | | project = pro;
|
| | | qtSettings = new ProjectQtSettings(project);
|
| | | qtSettings.PropertyChanged += OnPropertyChanged;
|
| | | OptionsPropertyGrid.SelectedObject = qtSettings;
|
| | |
|
| | | InitModules(QtVersionManager.The().GetProjectQtVersion(project));
|
| | | }
|
| | |
|
| | | protected override bool ProcessDialogKey(Keys keyData)
|
| | | {
|
| | | if (ModifierKeys == Keys.None && keyData == Keys.Escape) {
|
| | | Close();
|
| | | return true;
|
| | | }
|
| | | return base.ProcessDialogKey(keyData);
|
| | | }
|
| | |
|
| | | private void OkButton_Click(object sender, EventArgs e)
|
| | | {
|
| | | // Disable the buttons since some operations are quite expensive (e.g. changing
|
| | | // the Qt version) and take some to finish. Keeping the buttons enabled allows to hit
|
| | | // the buttons several times resulting in successive executions of these operations.
|
| | | okButton.Enabled = false;
|
| | | cancelButton.Enabled = false;
|
| | |
|
| | | qtSettings.SaveSettings();
|
| | | SaveModules();
|
| | | okButton.DialogResult = DialogResult.OK;
|
| | | Close();
|
| | | }
|
| | |
|
| | | private void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
|
| | | {
|
| | | if (e.PropertyName != "Version")
|
| | | throw new ArgumentException();
|
| | | InitModules(qtSettings.Version);
|
| | | }
|
| | |
|
| | | private void InitModules(string qtVersion)
|
| | | {
|
| | | moduleMap.Clear();
|
| | | flowLayoutPanel1.Controls.Clear();
|
| | |
|
| | | var vm = QtVersionManager.The();
|
| | | var versionInfo = vm.GetVersionInfo(qtVersion);
|
| | | if (string.IsNullOrEmpty(qtVersion) || versionInfo == null) {
|
| | | flowLayoutPanel1.Controls.Add(new Label
|
| | | {
|
| | | Text = Environment.NewLine
|
| | | + "Please set a valid Qt version first.",
|
| | | AutoSize = true
|
| | | });
|
| | | return;
|
| | | }
|
| | |
|
| | | var installPath = vm.GetInstallPath(qtVersion) ?? string.Empty;
|
| | | var modules = QtModules.Instance.GetAvailableModules(versionInfo.qtMajor)
|
| | | .Where(x => x.Selectable)
|
| | | .OrderBy(x => x.Name);
|
| | | foreach (var module in modules) {
|
| | | var checkBox = new CheckBox
|
| | | {
|
| | | Margin = new Padding(6),
|
| | | Location = new System.Drawing.Point(150, 150),
|
| | | Name = module.LibraryPrefix,
|
| | | UseVisualStyleBackColor = true,
|
| | | AutoSize = true,
|
| | | Text = module.Name,
|
| | | Checked = Legacy.QtProject.HasModule(project, module.Id, qtVersion)
|
| | | };
|
| | | flowLayoutPanel1.Controls.Add(checkBox);
|
| | | moduleMap.Add(new ModuleItem(checkBox, module.Id, checkBox.Checked));
|
| | |
|
| | | var info = QtModules.Instance.Module(module.Id, versionInfo.qtMajor);
|
| | | var libraryPrefix = info?.LibraryPrefix;
|
| | | if (libraryPrefix.StartsWith("Qt", StringComparison.Ordinal))
|
| | | libraryPrefix = "Qt" + versionInfo.qtMajor + libraryPrefix.Substring(2);
|
| | | checkBox.Enabled = new FileInfo(
|
| | | Path.Combine(installPath, "lib", $"{libraryPrefix}{versionInfo.LibInfix()}.lib")
|
| | | ).Exists; // Disable the check-box if the module is not installed.
|
| | | if (!checkBox.Enabled)
|
| | | checkBox.Checked = false; // Uncheck if the module is not installed.
|
| | | }
|
| | | }
|
| | |
|
| | | private void SaveModules()
|
| | | {
|
| | | for (var i = 0; i < moduleMap.Count; ++i) {
|
| | | var item = moduleMap[i];
|
| | | var isModuleChecked = item.checkbox.Checked;
|
| | | if (isModuleChecked != item.initialValue) {
|
| | | if (isModuleChecked)
|
| | | Legacy.QtProject.AddModule(project, item.moduleId);
|
| | | else
|
| | | Legacy.QtProject.RemoveModule(project, item.moduleId);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | }
|
| | | }
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <root>
|
| | | <!-- |
| | | Microsoft ResX Schema |
| | | |
| | | Version 2.0
|
| | | |
| | | The primary goals of this format is to allow a simple XML format |
| | | that is mostly human readable. The generation and parsing of the |
| | | various data types are done through the TypeConverter classes |
| | | associated with the data types.
|
| | | |
| | | Example:
|
| | | |
| | | ... ado.net/XML headers & schema ...
|
| | | <resheader name="resmimetype">text/microsoft-resx</resheader>
|
| | | <resheader name="version">2.0</resheader>
|
| | | <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
| | | <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
| | | <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
| | | <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
| | | <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
| | | <value>[base64 mime encoded serialized .NET Framework object]</value>
|
| | | </data>
|
| | | <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
| | | <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
| | | <comment>This is a comment</comment>
|
| | | </data>
|
| | | |
| | | There are any number of "resheader" rows that contain simple |
| | | name/value pairs.
|
| | | |
| | | Each data row contains a name, and value. The row also contains a |
| | | type or mimetype. Type corresponds to a .NET class that support |
| | | text/value conversion through the TypeConverter architecture. |
| | | Classes that don't support this are serialized and stored with the |
| | | mimetype set.
|
| | | |
| | | The mimetype is used for serialized objects, and tells the |
| | | ResXResourceReader how to depersist the object. This is currently not |
| | | extensible. For a given mimetype the value must be set accordingly:
|
| | | |
| | | Note - application/x-microsoft.net.object.binary.base64 is the format |
| | | that the ResXResourceWriter will generate, however the reader can |
| | | read any of the formats listed below.
|
| | | |
| | | mimetype: application/x-microsoft.net.object.binary.base64
|
| | | value : The object must be serialized with |
| | | : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
| | | : and then encoded with base64 encoding.
|
| | | |
| | | mimetype: application/x-microsoft.net.object.soap.base64
|
| | | value : The object must be serialized with |
| | | : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
| | | : and then encoded with base64 encoding.
|
| | |
|
| | | mimetype: application/x-microsoft.net.object.bytearray.base64
|
| | | value : The object must be serialized into a byte array |
| | | : using a System.ComponentModel.TypeConverter
|
| | | : and then encoded with base64 encoding.
|
| | | -->
|
| | | <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
| | | <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
| | | <xsd:element name="root" msdata:IsDataSet="true">
|
| | | <xsd:complexType>
|
| | | <xsd:choice maxOccurs="unbounded">
|
| | | <xsd:element name="metadata">
|
| | | <xsd:complexType>
|
| | | <xsd:sequence>
|
| | | <xsd:element name="value" type="xsd:string" minOccurs="0" />
|
| | | </xsd:sequence>
|
| | | <xsd:attribute name="name" use="required" type="xsd:string" />
|
| | | <xsd:attribute name="type" type="xsd:string" />
|
| | | <xsd:attribute name="mimetype" type="xsd:string" />
|
| | | <xsd:attribute ref="xml:space" />
|
| | | </xsd:complexType>
|
| | | </xsd:element>
|
| | | <xsd:element name="assembly">
|
| | | <xsd:complexType>
|
| | | <xsd:attribute name="alias" type="xsd:string" />
|
| | | <xsd:attribute name="name" type="xsd:string" />
|
| | | </xsd:complexType>
|
| | | </xsd:element>
|
| | | <xsd:element name="data">
|
| | | <xsd:complexType>
|
| | | <xsd:sequence>
|
| | | <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
| | | <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
| | | </xsd:sequence>
|
| | | <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
| | | <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
| | | <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
| | | <xsd:attribute ref="xml:space" />
|
| | | </xsd:complexType>
|
| | | </xsd:element>
|
| | | <xsd:element name="resheader">
|
| | | <xsd:complexType>
|
| | | <xsd:sequence>
|
| | | <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
| | | </xsd:sequence>
|
| | | <xsd:attribute name="name" type="xsd:string" use="required" />
|
| | | </xsd:complexType>
|
| | | </xsd:element>
|
| | | </xsd:choice>
|
| | | </xsd:complexType>
|
| | | </xsd:element>
|
| | | </xsd:schema>
|
| | | <resheader name="resmimetype">
|
| | | <value>text/microsoft-resx</value>
|
| | | </resheader>
|
| | | <resheader name="version">
|
| | | <value>2.0</value>
|
| | | </resheader>
|
| | | <resheader name="reader">
|
| | | <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
| | | </resheader>
|
| | | <resheader name="writer">
|
| | | <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
| | | </resheader>
|
| | | </root> |
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.ComponentModel;
|
| | | using System.Globalization;
|
| | | using System.Text.RegularExpressions;
|
| | |
|
| | | namespace QtVsTools.Legacy
|
| | | {
|
| | | using Core;
|
| | | using Legacy = Core.Legacy;
|
| | |
|
| | | public class ProjectQtSettings : INotifyPropertyChanged
|
| | | {
|
| | | public event PropertyChangedEventHandler PropertyChanged;
|
| | | protected void OnPropertyChanged(string propertyName)
|
| | | {
|
| | | var eventHandler = PropertyChanged;
|
| | | if (eventHandler != null)
|
| | | eventHandler.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
| | | }
|
| | |
|
| | | public ProjectQtSettings(EnvDTE.Project proj)
|
| | | {
|
| | | versionManager = QtVersionManager.The();
|
| | | project = proj;
|
| | | newMocDir = oldMocDir = Legacy.QtVSIPSettings.GetMocDirectory(project);
|
| | | newMocOptions = oldMocOptions = Legacy.QtVSIPSettings.GetMocOptions(project);
|
| | | newRccDir = oldRccDir = Legacy.QtVSIPSettings.GetRccDirectory(project);
|
| | | newUicDir = oldUicDir = Legacy.QtVSIPSettings.GetUicDirectory(project);
|
| | | newLUpdateOnBuild = oldLUpdateOnBuild = Legacy.QtVSIPSettings.GetLUpdateOnBuild(project);
|
| | | newLUpdateOptions = oldLUpdateOptions = Legacy.QtVSIPSettings.GetLUpdateOptions(project);
|
| | | newLReleaseOptions = oldLReleaseOptions = Legacy.QtVSIPSettings.GetLReleaseOptions(project);
|
| | | newQtVersion = oldQtVersion = versionManager.GetProjectQtVersion(project);
|
| | | QmlDebug = oldQmlDebug = Legacy.QtVSIPSettings.GetQmlDebug(project);
|
| | | }
|
| | |
|
| | | private readonly QtVersionManager versionManager;
|
| | | private EnvDTE.Project project;
|
| | |
|
| | | private readonly string oldMocDir;
|
| | | private readonly string oldMocOptions;
|
| | | private readonly string oldRccDir;
|
| | | private readonly string oldUicDir;
|
| | | private readonly string oldQtVersion;
|
| | | private readonly bool oldLUpdateOnBuild;
|
| | | private readonly string oldLUpdateOptions;
|
| | | private readonly string oldLReleaseOptions;
|
| | | private readonly bool oldQmlDebug;
|
| | |
|
| | | private string newMocDir;
|
| | | private string newMocOptions;
|
| | | private string newRccDir;
|
| | | private string newUicDir;
|
| | | private string newQtVersion;
|
| | | private bool newLUpdateOnBuild;
|
| | | private string newLUpdateOptions;
|
| | | private string newLReleaseOptions;
|
| | |
|
| | | public void SaveSettings()
|
| | | {
|
| | | var updateMoc = false;
|
| | | var qtPro = QtProject.Create(project);
|
| | |
|
| | | if (oldMocDir != newMocDir) {
|
| | | Legacy.QtVSIPSettings.SaveMocDirectory(project, newMocDir);
|
| | | updateMoc = true;
|
| | | }
|
| | | if (oldMocOptions != newMocOptions) {
|
| | | Legacy.QtVSIPSettings.SaveMocOptions(project, newMocOptions);
|
| | | updateMoc = true;
|
| | | }
|
| | | if (updateMoc)
|
| | | qtPro.UpdateMocSteps(oldMocDir);
|
| | |
|
| | | if (oldUicDir != newUicDir) {
|
| | | Legacy.QtVSIPSettings.SaveUicDirectory(project, newUicDir);
|
| | | qtPro.UpdateUicSteps(oldUicDir, true);
|
| | | }
|
| | |
|
| | | if (oldRccDir != newRccDir) {
|
| | | Legacy.QtVSIPSettings.SaveRccDirectory(project, newRccDir);
|
| | | qtPro.RefreshRccSteps(oldRccDir);
|
| | | }
|
| | |
|
| | | if (oldLUpdateOnBuild != newLUpdateOnBuild)
|
| | | Legacy.QtVSIPSettings.SaveLUpdateOnBuild(project, newLUpdateOnBuild);
|
| | |
|
| | | if (oldLUpdateOptions != newLUpdateOptions)
|
| | | Legacy.QtVSIPSettings.SaveLUpdateOptions(project, newLUpdateOptions);
|
| | |
|
| | | if (oldLReleaseOptions != newLReleaseOptions)
|
| | | Legacy.QtVSIPSettings.SaveLReleaseOptions(project, newLReleaseOptions);
|
| | |
|
| | | if (oldQmlDebug != QmlDebug)
|
| | | Legacy.QtVSIPSettings.SaveQmlDebug(project, QmlDebug);
|
| | |
|
| | | if (oldQtVersion != newQtVersion) {
|
| | | if (Legacy.QtProject.PromptChangeQtVersion(project, oldQtVersion, newQtVersion)) {
|
| | | var newProjectCreated = false;
|
| | | var versionChanged = qtPro.ChangeQtVersion(
|
| | | oldQtVersion, newQtVersion, ref newProjectCreated);
|
| | | if (versionChanged && newProjectCreated)
|
| | | project = qtPro.Project;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | public string MocDirectory
|
| | | {
|
| | | get
|
| | | {
|
| | | return newMocDir;
|
| | | }
|
| | | set
|
| | | {
|
| | | var tmp = HelperFunctions.NormalizeRelativeFilePath(value);
|
| | | if (tmp.Equals(oldMocDir, StringComparison.OrdinalIgnoreCase))
|
| | | return;
|
| | |
|
| | | string badMacros = IncompatibleMacros(tmp);
|
| | | if (!string.IsNullOrEmpty(badMacros))
|
| | | Messages.DisplayErrorMessage(SR.GetString("IncompatibleMacros", badMacros));
|
| | | else
|
| | | newMocDir = tmp;
|
| | | }
|
| | | }
|
| | |
|
| | | public string MocOptions
|
| | | {
|
| | | get
|
| | | {
|
| | | return newMocOptions;
|
| | | }
|
| | |
|
| | | set
|
| | | {
|
| | | newMocOptions = value;
|
| | | }
|
| | | }
|
| | |
|
| | | public string UicDirectory
|
| | | {
|
| | | get
|
| | | {
|
| | | return newUicDir;
|
| | | }
|
| | | set
|
| | | {
|
| | | var tmp = HelperFunctions.NormalizeRelativeFilePath(value);
|
| | | if (tmp.Equals(oldUicDir, StringComparison.OrdinalIgnoreCase))
|
| | | return;
|
| | |
|
| | | string badMacros = IncompatibleMacros(tmp);
|
| | | if (!string.IsNullOrEmpty(badMacros))
|
| | | Messages.DisplayErrorMessage(SR.GetString("IncompatibleMacros", badMacros));
|
| | | else
|
| | | newUicDir = tmp;
|
| | | }
|
| | | }
|
| | |
|
| | | public string RccDirectory
|
| | | {
|
| | | get
|
| | | {
|
| | | return newRccDir;
|
| | | }
|
| | | set
|
| | | {
|
| | | var tmp = HelperFunctions.NormalizeRelativeFilePath(value);
|
| | | if (tmp.Equals(oldRccDir, StringComparison.OrdinalIgnoreCase))
|
| | | return;
|
| | |
|
| | | string badMacros = IncompatibleMacros(tmp);
|
| | | if (!string.IsNullOrEmpty(badMacros))
|
| | | Messages.DisplayErrorMessage(SR.GetString("IncompatibleMacros", badMacros));
|
| | | else
|
| | | newRccDir = tmp;
|
| | | }
|
| | | }
|
| | |
|
| | | public bool lupdateOnBuild
|
| | | {
|
| | | get
|
| | | {
|
| | | return newLUpdateOnBuild;
|
| | | }
|
| | |
|
| | | set
|
| | | {
|
| | | newLUpdateOnBuild = value;
|
| | | }
|
| | | }
|
| | |
|
| | | public string LUpdateOptions
|
| | | {
|
| | | get
|
| | | {
|
| | | return newLUpdateOptions;
|
| | | }
|
| | |
|
| | | set
|
| | | {
|
| | | newLUpdateOptions = value;
|
| | | }
|
| | | }
|
| | |
|
| | | public string LReleaseOptions
|
| | | {
|
| | | get
|
| | | {
|
| | | return newLReleaseOptions;
|
| | | }
|
| | |
|
| | | set
|
| | | {
|
| | | newLReleaseOptions = value;
|
| | | }
|
| | | }
|
| | |
|
| | | [DisplayName("QML Debug")]
|
| | | [TypeConverter(typeof(QmlDebugConverter))]
|
| | | private bool QmlDebug { get; }
|
| | |
|
| | | private static string IncompatibleMacros(string stringToExpand)
|
| | | {
|
| | | string incompatibleMacros = "";
|
| | | foreach (Match metaNameMatch in Regex.Matches(stringToExpand, @"\%\(([^\)]+)\)")) {
|
| | | string metaName = metaNameMatch.Groups[1].Value;
|
| | | if (!incompatibleMacros.Contains(string.Format("%({0})", metaName))) {
|
| | | switch (metaName) {
|
| | | case "RecursiveDir":
|
| | | case "ModifiedTime":
|
| | | case "CreatedTime":
|
| | | case "AccessedTime":
|
| | | if (!string.IsNullOrEmpty(incompatibleMacros))
|
| | | incompatibleMacros += ", ";
|
| | | incompatibleMacros += string.Format("%({0})", metaName);
|
| | | break;
|
| | | }
|
| | | }
|
| | | }
|
| | | return incompatibleMacros;
|
| | | }
|
| | |
|
| | | internal class QmlDebugConverter : BooleanConverter
|
| | | {
|
| | | public override object ConvertTo(
|
| | | ITypeDescriptorContext context,
|
| | | CultureInfo culture,
|
| | | object value,
|
| | | Type destinationType)
|
| | | {
|
| | | return (bool)value ? "Enabled" : "Disabled";
|
| | | }
|
| | |
|
| | | public override object ConvertFrom(
|
| | | ITypeDescriptorContext context,
|
| | | CultureInfo culture,
|
| | | object value)
|
| | | {
|
| | | return (string)value == "Enabled";
|
| | | }
|
| | | }
|
| | |
|
| | | [TypeConverter(typeof(VersionConverter))]
|
| | | public string Version
|
| | | {
|
| | | get
|
| | | {
|
| | | return newQtVersion;
|
| | | }
|
| | | set
|
| | | {
|
| | | if (newQtVersion != value) {
|
| | | newQtVersion = value;
|
| | | OnPropertyChanged("Version");
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | internal class VersionConverter : StringConverter
|
| | | {
|
| | | private readonly QtVersionManager versionManager;
|
| | |
|
| | | public VersionConverter()
|
| | | {
|
| | | versionManager = QtVersionManager.The();
|
| | | }
|
| | |
|
| | | public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
|
| | | {
|
| | | return true;
|
| | | }
|
| | |
|
| | | public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
|
| | | {
|
| | | var versions = versionManager.GetVersions();
|
| | | Array.Resize(ref versions, versions.Length + 1);
|
| | | versions[versions.Length - 1] = "$(DefaultQtVersion)";
|
| | | return new StandardValuesCollection(versions);
|
| | | }
|
| | |
|
| | | public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
|
| | | {
|
| | | return true;
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System.Windows.Forms;
|
| | | using EnvDTE;
|
| | | using EnvDTE80;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | |
|
| | | namespace QtVsTools.Legacy
|
| | | {
|
| | | using Core;
|
| | | using Legacy = Core.Legacy;
|
| | |
|
| | | internal static class QtMenu
|
| | | {
|
| | | internal static void ShowFormProjectQtSettings(Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | using (var form = new FormProjectQtSettings(project)) {
|
| | | form.StartPosition = FormStartPosition.CenterParent;
|
| | | form.ShowDialog(new MainWinWrapper(QtVsToolsPackage.Instance.Dte));
|
| | | }
|
| | | }
|
| | |
|
| | | internal static void ShowFormChangeProjectQtVersion()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var pro = HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte);
|
| | | if (!HelperFunctions.IsQtProject(pro))
|
| | | return;
|
| | |
|
| | | using (var formChangeQtVersion = new FormChangeQtVersion()) {
|
| | | formChangeQtVersion.UpdateContent(ChangeFor.Project);
|
| | | var ww = new MainWinWrapper(QtVsToolsPackage.Instance.Dte);
|
| | | if (formChangeQtVersion.ShowDialog(ww) == DialogResult.OK) {
|
| | | var qtVersion = formChangeQtVersion.GetSelectedQtVersion();
|
| | | HelperFunctions.SetDebuggingEnvironment(pro, "PATH=" + QtVersionManager
|
| | | .The().GetInstallPath(qtVersion) + @"\bin;$(PATH)", true);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | internal static void ShowFormChangeSolutionQtVersion()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | string newQtVersion = null;
|
| | | using (var formChangeQtVersion = new FormChangeQtVersion()) {
|
| | | formChangeQtVersion.UpdateContent(ChangeFor.Solution);
|
| | | if (formChangeQtVersion.ShowDialog() != DialogResult.OK)
|
| | | return;
|
| | | newQtVersion = formChangeQtVersion.GetSelectedQtVersion();
|
| | | }
|
| | | if (newQtVersion == null)
|
| | | return;
|
| | |
|
| | | string platform = null;
|
| | | var dte = QtVsToolsPackage.Instance.Dte;
|
| | | try {
|
| | | platform = (dte.Solution.SolutionBuild.ActiveConfiguration as SolutionConfiguration2)
|
| | | .PlatformName;
|
| | | } catch { }
|
| | | if (string.IsNullOrEmpty(platform))
|
| | | return;
|
| | |
|
| | | var vm = QtVersionManager.The();
|
| | | foreach (var project in HelperFunctions.ProjectsInSolution(dte)) {
|
| | | if (HelperFunctions.IsVsToolsProject(project)) {
|
| | | var OldQtVersion = vm.GetProjectQtVersion(project, platform);
|
| | | if (OldQtVersion == null)
|
| | | OldQtVersion = vm.GetDefaultVersion();
|
| | |
|
| | | var created = false;
|
| | | var qtProject = QtProject.Create(project);
|
| | | if (Legacy.QtProject.PromptChangeQtVersion(project, OldQtVersion, newQtVersion))
|
| | | qtProject.ChangeQtVersion(OldQtVersion, newQtVersion, ref created);
|
| | | }
|
| | | }
|
| | | Legacy.QtVersionManager.SaveSolutionQtVersion(dte.Solution, newQtVersion);
|
| | | }
|
| | | }
|
| | | }
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2021 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.ComponentModel;
|
| | | using Microsoft.Win32;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | |
|
| | | namespace QtVsTools.Legacy
|
| | | {
|
| | | using Core;
|
| | |
|
| | | public class QtOptionsPage : DialogPage
|
| | | {
|
| | | [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
|
| | | [DisplayName("Source control: Ask before checking out files")]
|
| | | public bool CheckoutPrompt { get; set; }
|
| | |
|
| | | [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
|
| | | [DisplayName("Source control: Enable file check-out")]
|
| | | public bool Checkout { get; set; }
|
| | |
|
| | | [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
|
| | | [DisplayName("Linguist: Default lrelease options")]
|
| | | public string DefaultLReleaseOptions { get; set; }
|
| | |
|
| | | [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
|
| | | [DisplayName("Linguist: Default lupdate options")]
|
| | | public string DefaultLUpdateOptions { get; set; }
|
| | |
|
| | | [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
|
| | | [DisplayName("Linguist: Run lupdate during build")]
|
| | | public bool EnableLUpdateOnBuild { get; set; }
|
| | |
|
| | | [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
|
| | | [DisplayName("Meta-Object Compiler: Default moc generated files directory")]
|
| | | public string DefaultMocDir { get; set; }
|
| | |
|
| | | [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
|
| | | [DisplayName("Meta-Object Compiler: Default additional moc options ")]
|
| | | public string AdditionalMocOptions { get; set; }
|
| | |
|
| | | [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
|
| | | [DisplayName("Meta-Object Compiler: Enable automatic moc")]
|
| | | public bool AutoMoc { get; set; }
|
| | |
|
| | | [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
|
| | | [DisplayName("Resource Compiler: Default rcc generated files directory")]
|
| | | public string DefaultRccDir { get; set; }
|
| | |
|
| | | [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
|
| | | [DisplayName("User Interface Compiler: Default uic generated files directory")]
|
| | | public string DefaultUicDir { get; set; }
|
| | |
|
| | | [Category(@"Qt VS Project Format v2 (Qt tools integrated via custom-build steps)")]
|
| | | [DisplayName("Build: Run pre-build setup")]
|
| | | public bool PreBuildSetup { get; set; }
|
| | |
|
| | | const string VALUENAME_LegacyPreBuild = "LegacyPreBuild";
|
| | |
|
| | | public override void ResetSettings()
|
| | | {
|
| | | CheckoutPrompt = true;
|
| | | Checkout = true;
|
| | | DefaultLReleaseOptions = "";
|
| | | DefaultLUpdateOptions = "";
|
| | | EnableLUpdateOnBuild = false;
|
| | | DefaultMocDir = "";
|
| | | AdditionalMocOptions = "";
|
| | | AutoMoc = true;
|
| | | DefaultRccDir = "";
|
| | | DefaultUicDir = "";
|
| | | PreBuildSetup = false;
|
| | | }
|
| | |
|
| | | public override void LoadSettingsFromStorage()
|
| | | {
|
| | | ResetSettings();
|
| | | try {
|
| | | using (var key = Registry.CurrentUser
|
| | | .OpenSubKey(@"SOFTWARE\" + Resources.registryPackagePath, writable: false)) {
|
| | | if (key == null)
|
| | | return;
|
| | | if (key.GetValue(Resources.askBeforeCheckoutFileKeyword) is int checkoutPrompt)
|
| | | CheckoutPrompt = (checkoutPrompt != 0);
|
| | | if (key.GetValue(Resources.disableCheckoutFilesKeyword) is int disableCheckout)
|
| | | Checkout = (disableCheckout == 0);
|
| | | if (key.GetValue(Resources.lreleaseOptionsKeyword) is string lreleaseOptions)
|
| | | DefaultLReleaseOptions = lreleaseOptions;
|
| | | if (key.GetValue(Resources.lupdateOptionsKeyword) is string lupdateOptions)
|
| | | DefaultLUpdateOptions = lupdateOptions;
|
| | | if (key.GetValue(Resources.lupdateKeyword) is int lupdateOnBuild)
|
| | | EnableLUpdateOnBuild = (lupdateOnBuild != 0);
|
| | | if (key.GetValue(Resources.mocDirKeyword) is string mocDir)
|
| | | DefaultMocDir = mocDir;
|
| | | if (key.GetValue(Resources.mocOptionsKeyword) is string mocOptions)
|
| | | AdditionalMocOptions = mocOptions;
|
| | | if (key.GetValue(Resources.disableAutoMocStepsUpdateKeyword) is int autoMocOff)
|
| | | AutoMoc = (autoMocOff == 0);
|
| | | if (key.GetValue(Resources.rccDirKeyword) is string rccDir)
|
| | | DefaultRccDir = rccDir;
|
| | | if (key.GetValue(Resources.uicDirKeyword) is string uicDir)
|
| | | DefaultUicDir = uicDir;
|
| | | if (key.GetValue(VALUENAME_LegacyPreBuild) is int preBuild)
|
| | | PreBuildSetup = (preBuild != 0);
|
| | | }
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | }
|
| | | }
|
| | |
|
| | | public override void SaveSettingsToStorage()
|
| | | {
|
| | | try {
|
| | | using (var key = Registry.CurrentUser
|
| | | .CreateSubKey(@"SOFTWARE\" + Resources.registryPackagePath)) {
|
| | | if (key == null)
|
| | | return;
|
| | | key.SetValue(Resources.askBeforeCheckoutFileKeyword, CheckoutPrompt ? 1 : 0);
|
| | | key.SetValue(Resources.disableCheckoutFilesKeyword, Checkout ? 0 : 1);
|
| | | key.SetValue(Resources.lreleaseOptionsKeyword, DefaultLReleaseOptions);
|
| | | key.SetValue(Resources.lupdateOptionsKeyword, DefaultLUpdateOptions);
|
| | | key.SetValue(Resources.lupdateKeyword, EnableLUpdateOnBuild ? 1 : 0);
|
| | | key.SetValue(Resources.mocDirKeyword, DefaultMocDir);
|
| | | key.SetValue(Resources.mocOptionsKeyword, AdditionalMocOptions);
|
| | | key.SetValue(Resources.disableAutoMocStepsUpdateKeyword, AutoMoc ? 0 : 1);
|
| | | key.SetValue(Resources.rccDirKeyword, DefaultRccDir);
|
| | | key.SetValue(Resources.uicDirKeyword, DefaultUicDir);
|
| | | key.SetValue(VALUENAME_LegacyPreBuild, PreBuildSetup ? 1 : 0);
|
| | | }
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System.Collections.Generic;
|
| | | using System.Diagnostics;
|
| | | using System.IO;
|
| | | using System.Linq;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | |
|
| | | namespace QtVsTools.Legacy
|
| | | {
|
| | | using Core;
|
| | | using Legacy = Core.Legacy;
|
| | |
|
| | | using static Core.HelperFunctions;
|
| | | using BuildAction = QtVsTools.Translation.BuildAction;
|
| | |
|
| | | internal static class Translation
|
| | | {
|
| | | internal static void Run(BuildAction buildAction, QtProject qtProject,
|
| | | IEnumerable<string> tsFiles)
|
| | | {
|
| | | var qtInstallPath = QtVersionManager.The().GetInstallPath(qtProject.GetQtVersion());
|
| | | if (string.IsNullOrEmpty(qtInstallPath)) {
|
| | | Messages.Print("translation: Error accessing Qt installation");
|
| | | return;
|
| | | }
|
| | |
|
| | | if (tsFiles == null) {
|
| | | tsFiles = (qtProject.VCProject
|
| | | .GetFilesEndingWith(".ts") as IVCCollection)
|
| | | .Cast<VCFile>()
|
| | | .Select(vcFile => vcFile.RelativePath);
|
| | | }
|
| | |
|
| | | if (tsFiles != null) {
|
| | | var project = qtProject.Project;
|
| | | var tempFile = Path.GetTempFileName();
|
| | |
|
| | | File.WriteAllLines(tempFile, GetProjectFiles(project, FilesToList.FL_HFiles)
|
| | | .Union(GetProjectFiles(project, FilesToList.FL_CppFiles))
|
| | | .Union(GetProjectFiles(project, FilesToList.FL_UiFiles))
|
| | | .Union(GetProjectFiles(project, FilesToList.FL_QmlFiles)));
|
| | |
|
| | | var procInfo = new ProcessStartInfo
|
| | | {
|
| | | WorkingDirectory = qtProject.ProjectDir,
|
| | | CreateNoWindow = true,
|
| | | UseShellExecute = false,
|
| | | RedirectStandardError = true,
|
| | | RedirectStandardOutput = true,
|
| | | Arguments = ""
|
| | | };
|
| | | procInfo.FileName = Path.Combine(qtInstallPath, "bin",
|
| | | buildAction == BuildAction.Update ? "lupdate.exe" : "lrelease.exe");
|
| | |
|
| | | foreach (var file in tsFiles.Where(file => file != null))
|
| | | Run(buildAction, file, tempFile, procInfo);
|
| | | } else {
|
| | | Messages.Print("translation: No translation files found");
|
| | | }
|
| | | }
|
| | |
|
| | | private static void Run(BuildAction buildAction, string tsFile, string tempFile,
|
| | | ProcessStartInfo procInfo)
|
| | | {
|
| | | switch (buildAction) {
|
| | | case BuildAction.Update:
|
| | | Messages.Print("\r\n--- (lupdate) file: " + tsFile);
|
| | | var options = Legacy.QtVSIPSettings.GetLUpdateOptions();
|
| | | if (!string.IsNullOrEmpty(options))
|
| | | procInfo.Arguments += options + " ";
|
| | | procInfo.Arguments += string.Format("\"@{0}\" -ts \"{1}\"", tempFile, tsFile);
|
| | | break;
|
| | | case BuildAction.Release:
|
| | | Messages.Print("\r\n--- (lrelease) file: " + tsFile);
|
| | | options = Legacy.QtVSIPSettings.GetLReleaseOptions();
|
| | | if (!string.IsNullOrEmpty(options))
|
| | | procInfo.Arguments += options + " ";
|
| | | procInfo.Arguments += string.Format("\"{0}\"", tsFile);
|
| | | break;
|
| | | }
|
| | |
|
| | | using (var proc = Process.Start(procInfo)) {
|
| | | proc.OutputDataReceived += (object sender, DataReceivedEventArgs e) =>
|
| | | {
|
| | | if (!string.IsNullOrEmpty(e.Data))
|
| | | Messages.Print(e.Data);
|
| | | };
|
| | | proc.ErrorDataReceived += (object sender, DataReceivedEventArgs e) =>
|
| | | {
|
| | | if (!string.IsNullOrEmpty(e.Data))
|
| | | Messages.Print(e.Data);
|
| | | };
|
| | | proc.BeginOutputReadLine();
|
| | | proc.BeginErrorReadLine();
|
| | | proc.WaitForExit();
|
| | | switch (proc.ExitCode) {
|
| | | case 0:
|
| | | Messages.Print("translation: ok");
|
| | | break;
|
| | | default:
|
| | | Messages.Print(string.Format("translation: ERROR {0}", proc.ExitCode));
|
| | | break;
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | <p><h3><span>The main features of Qt VS Tools are:</span></h3></p>
|
| | | <ul>
|
| | | <li>
|
| | | Wizards for creating new Qt projects and classes.
|
| | | Wizards for creating new Qt and Qt Quick projects and files.
|
| | | </li>
|
| | | <li>
|
| | | Automated build setup for the <a href="http://doc.qt.io/qt-5/moc.html">
|
| | |
| | | <li>
|
| | | Debugging extensions for Qt data types.
|
| | | </li>
|
| | | <li>
|
| | | QML debug engine for debugging Qt Quick applications.
|
| | | </li>
|
| | | </ul>
|
| | | <p><h3>How to set up F1 help</h3></p>
|
| | | <ol class="1" type="1">
|
| | |
| | | Select <strong>Assign</strong>, and then select <strong>OK</strong>.
|
| | | </li>
|
| | | </ol>
|
| | | <p><h3>How to report bugs and contribute code?</h3></p>
|
| | | <p><h3>How to contribute via GitHub?</h3></p>
|
| | | <ul>
|
| | | <li>
|
| | | <a title="Bug reports" href="https://bugreports.qt.io/browse/QTVSADDINBUG">Bug reports</a>
|
| | | <a title="Source code on GitHub"
|
| | | href="https://github.com/qt-labs/vstools">Source code on GitHub</a>
|
| | | </li>
|
| | | <li>
|
| | | <a title="Source code" href="https://code.qt.io/cgit/qt-labs/vstools.git">Source code</a>
|
| | | <a title="Pull requests on GitHub"
|
| | | href="https://github.com/qt-labs/vstools/pulls">Pull requests on GitHub</a>
|
| | | </li>
|
| | | </ul>
|
| | | <p><h3>How to contribute via Qt Labs?</h3></p>
|
| | | <ul>
|
| | | <li>
|
| | | <a title="Source code on Qt Labs"
|
| | | href="https://code.qt.io/cgit/qt-labs/vstools.git">Source code on Qt Labs</a>
|
| | | </li>
|
| | | <li>
|
| | | <a title="Qt VS Tools Code Review"
|
| | | href="https://codereview.qt-project.org/q/project:qt-labs/vstools">Qt VS Tools Code Review</a>
|
| | | </li>
|
| | | </ul>
|
| | | For more information on how to contribute to the Qt Visual Tools via Qt Labs, please look at the
|
| | | <a title="Qt contribution Guidelines"
|
| | | href="https://wiki.qt.io/Qt_Contribution_Guidelines">
|
| | | Qt contribution Guidelines</a> first.
|
| | | <p><h3>How to report bugs?</h3></p>
|
| | | <ul>
|
| | | <li>
|
| | | <a title="Qt Bug Tracker"
|
| | | href="https://bugreports.qt.io/browse/QTVSADDINBUG">Qt Bug Tracker</a>
|
| | | </li>
|
| | | <li>
|
| | | <a title="GitHub Issue Tracker"
|
| | | href="https://github.com/qt-labs/vstools/issues">GitHub Issue Tracker</a>
|
| | | </li>
|
| | | </ul>
|
| | | <p>
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2020 The Qt Company Ltd.
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | |
| | | using System.ComponentModel;
|
| | | using System.Globalization;
|
| | | using System.Linq;
|
| | | using Microsoft.Win32;
|
| | | using System.Linq.Expressions;
|
| | | using System.Reflection;
|
| | | using Microsoft.Build.Framework;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | | using Microsoft.Build.Framework;
|
| | | using Microsoft.Win32;
|
| | | using EnvDTE;
|
| | | using QtVsTools.Core;
|
| | | using QtVsTools.Common;
|
| | | using QtVsTools.VisualStudio;
|
| | | using System.Reflection;
|
| | | using System.Linq.Expressions;
|
| | |
|
| | | namespace QtVsTools.Options
|
| | | {
|
| | | using static EnumExt;
|
| | | using Core;
|
| | | using VisualStudio;
|
| | |
|
| | | using static Common.EnumExt;
|
| | |
|
| | | public class QtOptionsPage : DialogPage, IQtVsToolsOptions
|
| | | {
|
| | |
| | | [String("BkgBuild_RunQtTools")] RunQtTools,
|
| | | [String("BkgBuild_DebugInfo")] DebugInfo,
|
| | | [String("BkgBuild_LoggerVerbosity")] LoggerVerbosity,
|
| | | }
|
| | |
|
| | | public enum Notifications
|
| | | {
|
| | | [String("Notifications_Installed")] Installed,
|
| | | }
|
| | |
|
| | | public enum Natvis
|
| | | {
|
| | | [String("LinkNatvis")] Link,
|
| | | }
|
| | |
|
| | | public enum Timeout : uint { Disabled = 0 }
|
| | |
| | | object value,
|
| | | Type destinationType)
|
| | | {
|
| | | if (value.GetType() == typeof(bool) && destinationType == typeof(string))
|
| | | return ((bool)value) ? "Enable" : "Disable";
|
| | | if (value is bool b && destinationType == typeof(string))
|
| | | return b ? "Enable" : "Disable";
|
| | | return base.ConvertTo(context, culture, value, destinationType);
|
| | | }
|
| | | }
|
| | |
| | | [DisplayName("Keyboard shortcut")]
|
| | | [Description("To change keyboard mapping, go to: Tools > Options > Keyboard")]
|
| | | [ReadOnly(true)]
|
| | | public string QtHelpKeyBinding { get; set; }
|
| | | private string QtHelpKeyBinding { get; set; }
|
| | |
|
| | | [Category("Help")]
|
| | | [DisplayName("Preferred source")]
|
| | |
| | | [Description("Configure verbosity level of background build log.")]
|
| | | public LoggerVerbosity BuildLoggerVerbosity { get; set; }
|
| | |
|
| | | [Category("Notifications")]
|
| | | [DisplayName("New version installed")]
|
| | | [Description("Show notification when a new version was recently installed.")]
|
| | | [TypeConverter(typeof(EnableDisableConverter))]
|
| | | public bool NotifyInstalled { get; set; }
|
| | |
|
| | | [Category("Natvis")]
|
| | | [DisplayName("Embed .natvis file into PDB")]
|
| | | [Description("Embeds the debugger visualizations (.natvis file) into the PDB file"
|
| | | + "generated by LINK. While setting this option, the embedded Natvis file will"
|
| | | + "take precedence over user-specific Natvis files(for example the files"
|
| | | + "located in %USERPROFILE%\\Documents\\Visual Studio 2022\\Visualizers).")]
|
| | | [TypeConverter(typeof(EnableDisableConverter))]
|
| | | public bool LinkNatvis { get; set; }
|
| | |
|
| | | public override void ResetSettings()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | QtMsBuildPath = "";
|
| | | QmlDebuggerEnabled = true;
|
| | | QmlDebuggerTimeout = (Timeout)60000;
|
| | |
| | | BuildRunQtTools = ProjectTracking = true;
|
| | | BuildDebugInformation = false;
|
| | | BuildLoggerVerbosity = LoggerVerbosity.Quiet;
|
| | | NotifyInstalled = true;
|
| | | LinkNatvis = true;
|
| | |
|
| | | ////////
|
| | | // Get Qt Help keyboard shortcut
|
| | |
| | |
|
| | | public override void LoadSettingsFromStorage()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | ResetSettings();
|
| | | try {
|
| | | QtMsBuildPath = Environment.GetEnvironmentVariable("QTMSBUILD");
|
| | |
| | | Load(() => BuildRunQtTools, key, BkgBuild.RunQtTools);
|
| | | Load(() => BuildDebugInformation, key, BkgBuild.DebugInfo);
|
| | | Load(() => BuildLoggerVerbosity, key, BkgBuild.LoggerVerbosity);
|
| | | Load(() => NotifyInstalled, key, Notifications.Installed);
|
| | | Load(() => LinkNatvis, key, Natvis.Link);
|
| | | }
|
| | | } catch (Exception exception) {
|
| | | Messages.Print(
|
| | | exception.Message + "\r\n\r\nStacktrace:\r\n" + exception.StackTrace);
|
| | | exception.Log();
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | Save(QmlDebuggerEnabled, key, QmlDebug.Enable);
|
| | | Save(QmlDebuggerTimeout, key, QmlDebug.Timeout);
|
| | | Save(HelpPreference, key, Help.Preference);
|
| | | Save(TryQtHelpOnF1Pressed, key, Help.Preference);
|
| | | Save(TryQtHelpOnF1Pressed, key, Help.TryOnF1Pressed);
|
| | | Save(DesignerDetached, key, Designer.Detached);
|
| | | Save(LinguistDetached, key, Linguist.Detached);
|
| | | Save(ResourceEditorDetached, key, ResEditor.Detached);
|
| | |
| | | Save(BuildRunQtTools, key, BkgBuild.RunQtTools);
|
| | | Save(BuildDebugInformation, key, BkgBuild.DebugInfo);
|
| | | Save(BuildLoggerVerbosity, key, BkgBuild.LoggerVerbosity);
|
| | | Save(NotifyInstalled, key, Notifications.Installed);
|
| | | Save(LinkNatvis, key, Natvis.Link);
|
| | | }
|
| | | } catch (Exception exception) {
|
| | | Messages.Print(
|
| | | exception.Message + "\r\n\r\nStacktrace:\r\n" + exception.StackTrace);
|
| | | exception.Log();
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2020 The Qt Company Ltd.
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | |
| | |
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.IO;
|
| | | using System.Linq;
|
| | | using System.Windows;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | | using QtVsTools.Core;
|
| | |
|
| | | namespace QtVsTools.Options
|
| | | {
|
| | | using Common;
|
| | | using Core;
|
| | | using static QtVsTools.Options.QtVersionsTable;
|
| | |
|
| | | public class QtVersionsPage : UIElementDialogPage
|
| | | {
|
| | | static LazyFactory Lazy { get; } = new LazyFactory();
|
| | |
|
| | | QtVersionManager VersionManager => QtVersionManager.The();
|
| | |
|
| | | QtVersionsTable _VersionsTable;
|
| | | QtVersionsTable VersionsTable => _VersionsTable
|
| | | ?? (_VersionsTable = new QtVersionsTable());
|
| | | QtVersionsTable VersionsTable => Lazy.Get(() =>
|
| | | VersionsTable, () => new QtVersionsTable());
|
| | |
|
| | | protected override UIElement Child => VersionsTable;
|
| | |
|
| | | public override void LoadSettingsFromStorage()
|
| | | {
|
| | | var versions = new List<QtVersionsTable.Row>();
|
| | | var versions = new List<Row>();
|
| | | foreach (var versionName in VersionManager.GetVersions()) {
|
| | | var versionPath = VersionManager.GetInstallPath(versionName);
|
| | | if (string.IsNullOrEmpty(versionPath))
|
| | | continue;
|
| | |
|
| | | BuildHost host = BuildHost.Windows;
|
| | | string compiler = "msvc";
|
| | | if (versionPath.StartsWith("SSH:") || versionPath.StartsWith("WSL:")) {
|
| | |
| | | compiler = linuxPaths[2];
|
| | | }
|
| | | var defaultVersion = VersionManager.GetDefaultVersion();
|
| | | versions.Add(new QtVersionsTable.Row()
|
| | | versions.Add(new Row()
|
| | | {
|
| | | IsDefault = (versionName == defaultVersion),
|
| | | VersionName = versionName,
|
| | | InitialVersionName = versionName,
|
| | | Path = versionPath,
|
| | | Host = host,
|
| | | Compiler = compiler,
|
| | | State = State.Unknown
|
| | | });
|
| | | }
|
| | | VersionsTable.UpdateVersions(versions);
|
| | |
| | |
|
| | | public override void SaveSettingsToStorage()
|
| | | {
|
| | | foreach (var versionName in VersionManager.GetVersions()) {
|
| | | void RemoveVersion(string versionName)
|
| | | {
|
| | | try {
|
| | | VersionManager.RemoveVersion(versionName);
|
| | | } catch (Exception exception) {
|
| | | Messages.Print(
|
| | | exception.Message + "\r\n\r\nStacktrace:\r\n" + exception.StackTrace);
|
| | | exception.Log();
|
| | | }
|
| | | }
|
| | | foreach (var version in VersionsTable.Versions) {
|
| | |
|
| | | var versions = VersionsTable.Versions;
|
| | | foreach (var version in versions) {
|
| | | if (version.State.HasFlag(State.Removed))
|
| | | RemoveVersion(version.VersionName);
|
| | |
|
| | | if (!version.State.HasFlag(State.Modified))
|
| | | continue;
|
| | |
|
| | | try {
|
| | | if (version.Host == BuildHost.Windows) {
|
| | | var versionInfo = VersionInformation.Get(version.Path);
|
| | | var generator = versionInfo.GetQMakeConfEntry("MAKEFILE_GENERATOR");
|
| | | if (generator != "MSVC.NET" && generator != "MSBUILD")
|
| | | throw new Exception(SR.GetString(
|
| | | "AddQtVersionDialog_IncorrectMakefileGenerator", generator));
|
| | | VersionManager.SaveVersion(version.VersionName, version.Path);
|
| | | if (version.State.HasFlag((State)Column.Path)) {
|
| | | var versionPath = version.Path;
|
| | | var ignoreCase = StringComparison.CurrentCultureIgnoreCase;
|
| | | if (Path.GetFileName(versionPath).Equals("qmake.exe", ignoreCase))
|
| | | versionPath = Path.GetDirectoryName(versionPath);
|
| | | if (Path.GetFileName(versionPath).Equals("bin", ignoreCase))
|
| | | versionPath = Path.GetDirectoryName(versionPath);
|
| | | var versionInfo = VersionInformation.Get(versionPath);
|
| | | var generator = versionInfo.GetQMakeConfEntry("MAKEFILE_GENERATOR");
|
| | | if (generator != "MSVC.NET" && generator != "MSBUILD")
|
| | | throw new Exception(string.Format(
|
| | | "This Qt version uses an unsupported makefile generator (used: "
|
| | | + "{0}, supported: MSVC.NET, MSBUILD)", generator));
|
| | | VersionManager.SaveVersion(version.VersionName, versionPath);
|
| | | }
|
| | | } else {
|
| | | string name = version.VersionName;
|
| | | string access =
|
| | |
| | | path = string.Format("{0}:{1}:{2}", access, path, compiler);
|
| | | VersionManager.SaveVersion(name, path, checkPath: false);
|
| | | }
|
| | |
|
| | | if (version.State.HasFlag((State)Column.VersionName)) {
|
| | | try {
|
| | | VersionManager.SaveVersion(version.VersionName, version.Path);
|
| | | if (!string.IsNullOrEmpty(version.InitialVersionName))
|
| | | VersionManager.RemoveVersion(version.InitialVersionName);
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | }
|
| | | }
|
| | | } catch (Exception exception) {
|
| | | Messages.Print(
|
| | | exception.Message + "\r\n\r\nStacktrace:\r\n" + exception.StackTrace);
|
| | | exception.Log();
|
| | | version.State = State.Removed;
|
| | | RemoveVersion(version.VersionName);
|
| | | }
|
| | | }
|
| | |
|
| | | try {
|
| | | var defaultVersion = VersionsTable.Versions
|
| | | .Where(version => version.IsDefault)
|
| | | .FirstOrDefault();
|
| | | if (defaultVersion != null)
|
| | | VersionManager.SaveDefaultVersion(defaultVersion.VersionName);
|
| | | var defaultVersion =
|
| | | versions.FirstOrDefault(v => v.IsDefault && v.State != State.Removed)
|
| | | ?? versions.FirstOrDefault(v => v.State != State.Removed);
|
| | | VersionManager.SaveDefaultVersion(defaultVersion?.VersionName ?? "");
|
| | | } catch (Exception exception) {
|
| | | Messages.Print(
|
| | | exception.Message + "\r\n\r\nStacktrace:\r\n" + exception.StackTrace);
|
| | | exception.Log();
|
| | | }
|
| | |
|
| | | if (Notifications.NoQtVersion.IsOpen && VersionManager.GetVersions()?.Any() == true)
|
| | | Notifications.NoQtVersion.Close();
|
| | | }
|
| | |
|
| | | protected override void OnApply(PageApplyEventArgs e)
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2020 The Qt Company Ltd.
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | |
| | | using System.Windows.Media;
|
| | | using System.Windows.Media.Imaging;
|
| | | using Microsoft.Win32;
|
| | | using QtVsTools.Common;
|
| | |
|
| | | namespace QtVsTools.Options
|
| | | {
|
| | | using static EnumExt;
|
| | | using Common;
|
| | | using QtVsTools.Core;
|
| | | using static Common.EnumExt;
|
| | |
|
| | | public enum BuildHost
|
| | | {
|
| | |
| | |
|
| | | public partial class QtVersionsTable : UserControl
|
| | | {
|
| | | LazyFactory Lazy { get; } = new LazyFactory();
|
| | |
|
| | | public QtVersionsTable()
|
| | | {
|
| | | InitializeComponent();
|
| | | }
|
| | |
|
| | | [Flags] public enum Column
|
| | | {
|
| | | IsDefault = 0x10,
|
| | | VersionName = 0x20,
|
| | | Host = 0x40,
|
| | | Path = 0x80,
|
| | | Compiler = 0x100
|
| | | }
|
| | |
|
| | | [Flags] public enum State
|
| | | {
|
| | | Unknown = 0x00,
|
| | | Existing = 0x01,
|
| | | Removed = 0x02,
|
| | | Modified = 0x04
|
| | | }
|
| | |
|
| | | public class Field
|
| | |
| | | public string Value { get; set; }
|
| | | public Control Control { get; set; }
|
| | | public DataGridCell Cell { get; set; }
|
| | | public string ValidationError { get; set; }
|
| | | private string error;
|
| | | public string ValidationError {
|
| | | set {
|
| | | UpdateUi = value != error;
|
| | | error = value;
|
| | | }
|
| | | get { return error; }
|
| | | }
|
| | | public bool IsValid => string.IsNullOrEmpty(ValidationError);
|
| | | public ToolTip ToolTip
|
| | | => IsValid ? null : new ToolTip() { Content = ValidationError };
|
| | | public int SelectionStart { get; set; }
|
| | | public bool UpdateUi { get; private set; } = false;
|
| | | }
|
| | |
|
| | | public class Row
|
| | | {
|
| | | public enum FieldNames { IsDefault, VersionName, Host, Path, Compiler }
|
| | | static LazyFactory StaticLazy { get; } = new LazyFactory();
|
| | | LazyFactory Lazy { get; } = new LazyFactory();
|
| | |
|
| | | public Dictionary<FieldNames, Field> _Fields;
|
| | | public Dictionary<FieldNames, Field> Fields => _Fields
|
| | | ?? (_Fields = GetValues<FieldNames>()
|
| | | .Select(field => new KeyValuePair<FieldNames, Field>(field, null))
|
| | | public Dictionary<Column, Field> Fields => Lazy.Get(() =>
|
| | | Fields, () => GetValues<Column>()
|
| | | .Select(field => new KeyValuePair<Column, Field>(field, null))
|
| | | .ToDictionary(keyValue => keyValue.Key, keyValue => keyValue.Value));
|
| | |
|
| | | public Field FieldDefault => Fields[FieldNames.IsDefault]
|
| | | ?? (Fields[FieldNames.IsDefault] = new Field());
|
| | | public Field FieldDefault => Fields[Column.IsDefault]
|
| | | ?? (Fields[Column.IsDefault] = new Field());
|
| | | public bool IsDefault
|
| | | {
|
| | | get => (FieldDefault.Value == true.ToString());
|
| | | set => FieldDefault.Value = value.ToString();
|
| | | }
|
| | |
|
| | | public Field FieldVersionName => Fields[FieldNames.VersionName]
|
| | | ?? (Fields[FieldNames.VersionName] = new Field());
|
| | | public Field FieldVersionName => Fields[Column.VersionName]
|
| | | ?? (Fields[Column.VersionName] = new Field());
|
| | | public string VersionName
|
| | | {
|
| | | get => FieldVersionName.Value;
|
| | | set => FieldVersionName.Value = value;
|
| | | }
|
| | | public string InitialVersionName { get; set; }
|
| | |
|
| | | public Field FieldHost => Fields[FieldNames.Host]
|
| | | ?? (Fields[FieldNames.Host] = new Field());
|
| | | public Field FieldHost => Fields[Column.Host]
|
| | | ?? (Fields[Column.Host] = new Field());
|
| | | public BuildHost Host
|
| | | {
|
| | | get => FieldHost.Value.Cast(defaultValue: BuildHost.Windows);
|
| | | set => FieldHost.Value = value.Cast<string>();
|
| | | }
|
| | |
|
| | | public Field FieldPath => Fields[FieldNames.Path]
|
| | | ?? (Fields[FieldNames.Path] = new Field());
|
| | | public Field FieldPath => Fields[Column.Path]
|
| | | ?? (Fields[Column.Path] = new Field());
|
| | | public string Path
|
| | | {
|
| | | get => FieldPath.Value;
|
| | | set => FieldPath.Value = value;
|
| | | }
|
| | |
|
| | | public Field FieldCompiler => Fields[FieldNames.Compiler]
|
| | | ?? (Fields[FieldNames.Compiler] = new Field());
|
| | | public Field FieldCompiler => Fields[Column.Compiler]
|
| | | ?? (Fields[Column.Compiler] = new Field());
|
| | | public string Compiler
|
| | | {
|
| | | get => FieldCompiler.Value;
|
| | |
| | | public bool DefaultEnabled => !IsDefault && !LastRow;
|
| | | public bool NameEnabled => !LastRow;
|
| | | public bool CompilerEnabled => (Host != BuildHost.Windows);
|
| | | public Visibility RowVisibility
|
| | | public Visibility RowContentVisibility
|
| | | => LastRow ? Visibility.Hidden : Visibility.Visible;
|
| | | public Visibility ButtonAddVisibility
|
| | | => LastRow ? Visibility.Visible : Visibility.Hidden;
|
| | |
| | | public FontWeight FontWeight
|
| | | => IsDefault ? FontWeights.Bold : FontWeights.Normal;
|
| | |
|
| | | public static ImageSource _ExplorerIcon;
|
| | | public static ImageSource ExplorerIcon => _ExplorerIcon
|
| | | ?? (_ExplorerIcon = GetExplorerIcon());
|
| | | }
|
| | | public static ImageSource ExplorerIcon => StaticLazy.Get(() =>
|
| | | ExplorerIcon, () => GetExplorerIcon());
|
| | |
|
| | | public bool IsValid { get; private set; }
|
| | | public State State { get; set; } = State.Unknown;
|
| | | public bool RowVisible => State != State.Removed;
|
| | | }
|
| | |
|
| | | Field FocusedField { get; set; }
|
| | |
|
| | | List<Row> _Rows;
|
| | | List<Row> Rows => _Rows ?? (_Rows = new List<Row>());
|
| | | List<Row> Rows => Lazy.Get(() => Rows, () => new List<Row>());
|
| | | public IEnumerable<Row> Versions => Rows.TakeWhile(item => !item.LastRow);
|
| | |
|
| | | public void UpdateVersions(IEnumerable<Row> versions)
|
| | |
| | | Rows.AddRange(versions);
|
| | | Rows.Add(new Row { LastRow = true });
|
| | | DataGrid.ItemsSource = Rows;
|
| | | IsValid = true;
|
| | | FocusedField = null;
|
| | | Validate(true);
|
| | | Rows.ForEach(item => item.State = State.Existing);
|
| | | }
|
| | |
|
| | | public IEnumerable<string> GetErrorMessages()
|
| | | {
|
| | | Validate(true);
|
| | | return Versions
|
| | | .Where(v => v.State != State.Removed)
|
| | | .SelectMany(v => v.Fields.Values.Select(f => f.ValidationError))
|
| | | .Where(s => !string.IsNullOrEmpty(s))
|
| | | .Distinct();
|
| | |
| | |
|
| | | void Validate(bool mustRefresh)
|
| | | {
|
| | | /////////////////////////
|
| | | // Automatic cell values
|
| | | foreach (var version in Versions) {
|
| | | if (version.Host != BuildHost.Windows && version.Compiler == "msvc") {
|
| | | version.Compiler = "g++";
|
| | | version.FieldCompiler.SelectionStart = version.Compiler.Length;
|
| | | mustRefresh = true;
|
| | | } else if (version.Host == BuildHost.Windows && version.Compiler != "msvc") {
|
| | | version.Compiler = "msvc";
|
| | | version.FieldCompiler.SelectionStart = version.Compiler.Length;
|
| | | mustRefresh = true;
|
| | | }
|
| | | }
|
| | |
|
| | | ////////////////////////
|
| | | // Validate cell values
|
| | | string previousValidation;
|
| | | bool wasValid = IsValid;
|
| | | IsValid = true;
|
| | | foreach (var version in Versions) {
|
| | | if (!version.State.HasFlag(State.Modified))
|
| | | continue;
|
| | |
|
| | | //////////////////////
|
| | | // Default validation
|
| | | previousValidation = version.FieldDefault.ValidationError;
|
| | | version.FieldDefault.ValidationError = null;
|
| | | if (version.IsDefault && version.Host != BuildHost.Windows) {
|
| | | version.FieldDefault.ValidationError = "Default version: host must be Windows";
|
| | | IsValid = false;
|
| | | if (version.State.HasFlag((State)Column.IsDefault)) {
|
| | | version.FieldDefault.ValidationError = null;
|
| | | if (version.IsDefault && version.Host != BuildHost.Windows)
|
| | | version.FieldDefault.ValidationError = "Default version: Host must be Windows";
|
| | | mustRefresh |= version.FieldDefault.UpdateUi;
|
| | | }
|
| | | if (previousValidation != version.FieldDefault.ValidationError)
|
| | | mustRefresh = true;
|
| | |
|
| | | ///////////////////
|
| | | // Name validation
|
| | | previousValidation = version.FieldVersionName.ValidationError;
|
| | | version.FieldVersionName.ValidationError = null;
|
| | | if (string.IsNullOrEmpty(version.VersionName)) {
|
| | | version.FieldVersionName.ValidationError = "Name cannot be empty";
|
| | | IsValid = false;
|
| | | } else if (Versions
|
| | | .Where(otherVersion => otherVersion != version
|
| | | && otherVersion.VersionName == version.VersionName)
|
| | | .Any()) {
|
| | | version.FieldVersionName.ValidationError = "Duplicate version names";
|
| | | IsValid = false;
|
| | | if (version.State.HasFlag((State)Column.VersionName)) {
|
| | | version.FieldVersionName.ValidationError = null;
|
| | | if (string.IsNullOrEmpty(version.VersionName)) {
|
| | | version.FieldVersionName.ValidationError = "Name cannot be empty";
|
| | | } else if (Versions.Where(otherVersion => otherVersion != version
|
| | | && otherVersion.VersionName == version.VersionName).Any()) {
|
| | | version.FieldVersionName.ValidationError = "Duplicate version names";
|
| | | }
|
| | | mustRefresh |= version.FieldVersionName.UpdateUi;
|
| | | }
|
| | | if (previousValidation != version.FieldVersionName.ValidationError)
|
| | | mustRefresh = true;
|
| | |
|
| | | ///////////////////
|
| | | // Host validation
|
| | | previousValidation = version.FieldHost.ValidationError;
|
| | | version.FieldHost.ValidationError = null;
|
| | | if (version.IsDefault && version.Host != BuildHost.Windows) {
|
| | | version.FieldHost.ValidationError = "Default version: host must be Windows";
|
| | | IsValid = false;
|
| | | if (version.State.HasFlag((State)Column.Host)) {
|
| | | version.FieldHost.ValidationError = null;
|
| | | if (version.IsDefault && version.Host != BuildHost.Windows)
|
| | | version.FieldHost.ValidationError = "Default version: Host must be Windows";
|
| | | mustRefresh |= version.FieldHost.UpdateUi;
|
| | | }
|
| | | if (previousValidation != version.FieldHost.ValidationError)
|
| | | mustRefresh = true;
|
| | |
|
| | | ///////////////////
|
| | | // Path validation
|
| | | previousValidation = version.FieldPath.ValidationError;
|
| | | version.FieldPath.ValidationError = null;
|
| | | if (string.IsNullOrEmpty(version.Path)) {
|
| | | version.FieldPath.ValidationError = "Path cannot be empty";
|
| | | IsValid = false;
|
| | | } else if (version.Host == BuildHost.Windows && !Directory.Exists(version.Path)) {
|
| | | version.FieldPath.ValidationError = "Path does not exist";
|
| | | IsValid = false;
|
| | | if (version.State.HasFlag((State)Column.Path)) {
|
| | | version.FieldPath.ValidationError = null;
|
| | | if (string.IsNullOrEmpty(version.Path)) {
|
| | | version.FieldPath.ValidationError = "Path cannot be empty";
|
| | | } else if (version.Host == BuildHost.Windows) {
|
| | | string path = NormalizePath(version.Path);
|
| | | if (path == null) {
|
| | | version.FieldPath.ValidationError = "Invalid path format";
|
| | | } else {
|
| | | if (!QMake.Exists(path))
|
| | | version.FieldPath.ValidationError = "Cannot find qmake.exe";
|
| | | }
|
| | | }
|
| | | mustRefresh |= version.FieldPath.UpdateUi;
|
| | | }
|
| | | if (previousValidation != version.FieldPath.ValidationError)
|
| | | mustRefresh = true;
|
| | |
|
| | | ///////////////////////
|
| | | // Compiler validation
|
| | | previousValidation = version.FieldCompiler.ValidationError;
|
| | | version.FieldCompiler.ValidationError = null;
|
| | | if (string.IsNullOrEmpty(version.Compiler)) {
|
| | | version.FieldCompiler.ValidationError = "Compiler cannot be empty";
|
| | | IsValid = false;
|
| | | if (version.State.HasFlag((State)Column.Compiler)) {
|
| | | version.FieldCompiler.ValidationError = null;
|
| | | if (string.IsNullOrEmpty(version.Compiler))
|
| | | version.FieldCompiler.ValidationError = "Compiler cannot be empty";
|
| | | mustRefresh |= version.FieldCompiler.UpdateUi;
|
| | | }
|
| | | if (previousValidation != version.FieldCompiler.ValidationError)
|
| | | mustRefresh = true;
|
| | | }
|
| | |
|
| | | //////////////////////////////////////
|
| | | // Refresh versions table if required
|
| | | mustRefresh |= (wasValid != IsValid);
|
| | | if (mustRefresh) {
|
| | | // Reset bindings
|
| | | foreach (var version in Versions) {
|
| | |
| | | if (sender is Control control && GetBinding(control) is Row version) {
|
| | | if (version.LastRow)
|
| | | return;
|
| | |
|
| | | Row.FieldNames field;
|
| | | if (string.IsNullOrEmpty(control.Name) || !control.Name.TryCast(out field))
|
| | | if (string.IsNullOrEmpty(control.Name) || !control.Name.TryCast(out Column column))
|
| | | return;
|
| | |
|
| | | var fieldBinding = version.Fields[field];
|
| | | fieldBinding.Control = control;
|
| | | fieldBinding.Cell = FindContainingCell(control);
|
| | | if (fieldBinding.Cell != null) {
|
| | | fieldBinding.Cell.Background =
|
| | | fieldBinding.IsValid ? Brushes.Transparent : InvalidCellBackground;
|
| | | var field = version.Fields[column];
|
| | | field.Control = control;
|
| | | field.Cell = FindContainingCell(control);
|
| | | if (field.Cell != null) {
|
| | | field.Cell.Background =
|
| | | field.IsValid ? Brushes.Transparent : InvalidCellBackground;
|
| | | }
|
| | | if (fieldBinding == FocusedField)
|
| | | if (field == FocusedField)
|
| | | control.Focus();
|
| | | if (control is TextBox textBox && fieldBinding.SelectionStart >= 0)
|
| | | textBox.Select(fieldBinding.SelectionStart, 0);
|
| | | if (control is TextBox textBox && field.SelectionStart >= 0)
|
| | | textBox.Select(field.SelectionStart, 0);
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | void Control_GotFocus(object sender, RoutedEventArgs e)
|
| | | {
|
| | | if (sender is Control control && GetBinding(control) is Row version) {
|
| | | Row.FieldNames field;
|
| | | if (string.IsNullOrEmpty(control.Name) || !control.Name.TryCast(out field))
|
| | | if (string.IsNullOrEmpty(control.Name) || !control.Name.TryCast(out Column column))
|
| | | return;
|
| | | var fieldBinding = version.Fields[field];
|
| | | if (fieldBinding.Control != control)
|
| | |
|
| | | var field = version.Fields[column];
|
| | | if (field.Control != control)
|
| | | return;
|
| | | FocusedField = fieldBinding;
|
| | | FocusedField = field;
|
| | | }
|
| | | }
|
| | |
|
| | | void Control_LostFocus(object sender, RoutedEventArgs e)
|
| | | {
|
| | | if (sender is Control control && GetBinding(control) is Row version) {
|
| | | Row.FieldNames field;
|
| | | if (string.IsNullOrEmpty(control.Name) || !control.Name.TryCast(out field))
|
| | | if (string.IsNullOrEmpty(control.Name) || !control.Name.TryCast(out Column column))
|
| | | return;
|
| | | var fieldBinding = version.Fields[field];
|
| | | if (fieldBinding != FocusedField || fieldBinding.Control != control)
|
| | |
|
| | | var field = version.Fields[column];
|
| | | if (field != FocusedField || field.Control != control)
|
| | | return;
|
| | | FocusedField = null;
|
| | | }
|
| | |
| | | void TextBox_SelectionChanged(object sender, RoutedEventArgs e)
|
| | | {
|
| | | if (sender is TextBox textBox && GetBinding(textBox) is Row version) {
|
| | | Row.FieldNames field;
|
| | | if (string.IsNullOrEmpty(textBox.Name) || !textBox.Name.TryCast(out field))
|
| | | if (string.IsNullOrEmpty(textBox.Name) || !textBox.Name.TryCast(out Column column))
|
| | | return;
|
| | | var fieldBinding = version.Fields[field];
|
| | | if (fieldBinding.Control != textBox)
|
| | |
|
| | | var field = version.Fields[column];
|
| | | if (field.Control != textBox)
|
| | | return;
|
| | | fieldBinding.SelectionStart = textBox.SelectionStart;
|
| | | field.SelectionStart = textBox.SelectionStart;
|
| | | }
|
| | | }
|
| | |
|
| | | void TextBox_TextChanged(object sender, TextChangedEventArgs e)
|
| | | {
|
| | | if (sender is TextBox textBox && GetBinding(textBox) is Row version) {
|
| | | Row.FieldNames field;
|
| | | if (string.IsNullOrEmpty(textBox.Name) || !textBox.Name.TryCast(out field))
|
| | | if (string.IsNullOrEmpty(textBox.Name) || !textBox.Name.TryCast(out Column column))
|
| | | return;
|
| | | var fieldBinding = version.Fields[field];
|
| | | if (fieldBinding == null
|
| | | || fieldBinding.Control != textBox
|
| | | || fieldBinding.Value == textBox.Text)
|
| | |
|
| | | var field = version.Fields[column];
|
| | | if (field == null
|
| | | || field.Control != textBox
|
| | | || field.Value == textBox.Text)
|
| | | return;
|
| | | fieldBinding.SelectionStart = textBox.SelectionStart;
|
| | | fieldBinding.Value = textBox.Text;
|
| | |
|
| | | field.SelectionStart = textBox.SelectionStart;
|
| | | field.Value = textBox.Text;
|
| | | version.State |= State.Modified | (State)column;
|
| | |
|
| | | Validate(false);
|
| | | }
|
| | | }
|
| | |
| | | if (sender is ComboBox comboBox && GetBinding(comboBox) is Row version) {
|
| | | if (!comboBox.IsEnabled || comboBox.SelectedIndex < 0)
|
| | | return;
|
| | | if (string.IsNullOrEmpty(comboBox.Name) || !comboBox.Name.TryCast(out Column column))
|
| | | return;
|
| | |
|
| | | string comboBoxValue = comboBox.Items[comboBox.SelectedIndex] as string;
|
| | | string controlName = comboBox.Name;
|
| | | Row.FieldNames field;
|
| | | if (string.IsNullOrEmpty(controlName) || !controlName.TryCast(out field))
|
| | | var field = version.Fields[column];
|
| | | if (field == null
|
| | | || field.Control != comboBox
|
| | | || field.Value == comboBoxValue)
|
| | | return;
|
| | | var fieldBinding = version.Fields[field];
|
| | | if (fieldBinding == null
|
| | | || fieldBinding.Control != comboBox
|
| | | || fieldBinding.Value == comboBoxValue)
|
| | | return;
|
| | | fieldBinding.Value = comboBoxValue;
|
| | | Validate(false);
|
| | |
|
| | | field.Value = comboBoxValue;
|
| | | version.State |= State.Modified | (State)Column.Host;
|
| | |
|
| | | bool mustRefresh = false;
|
| | | if (version.Host != BuildHost.Windows && version.Compiler == "msvc") {
|
| | | version.Compiler = "g++";
|
| | | version.FieldCompiler.SelectionStart = version.Compiler.Length;
|
| | | version.State |= (State)Column.Compiler;
|
| | | mustRefresh = true;
|
| | | } else if (version.Host == BuildHost.Windows && version.Compiler != "msvc") {
|
| | | version.Compiler = "msvc";
|
| | | version.FieldCompiler.SelectionStart = version.Compiler.Length;
|
| | | version.State |= (State)Column.Compiler;
|
| | | mustRefresh = true;
|
| | | }
|
| | |
|
| | | Validate(mustRefresh);
|
| | | }
|
| | | }
|
| | |
|
| | | static void SetDefaultState(ref Row version, bool value)
|
| | | {
|
| | | version.IsDefault = value;
|
| | | version.State |= State.Modified | (State)Column.IsDefault;
|
| | | }
|
| | |
|
| | | void Default_Click(object sender, RoutedEventArgs e)
|
| | | {
|
| | | if (sender is CheckBox checkBox && GetBinding(checkBox) is Row version) {
|
| | | var defaultVersion = Rows.Where(row => row.IsDefault).FirstOrDefault();
|
| | | var defaultVersion = Rows.FirstOrDefault(row => row.IsDefault);
|
| | | if (defaultVersion != null)
|
| | | defaultVersion.IsDefault = false;
|
| | | version.IsDefault = true;
|
| | | SetDefaultState(ref defaultVersion, false);
|
| | | SetDefaultState(ref version, true);
|
| | | Validate(true);
|
| | | }
|
| | | }
|
| | |
| | | {
|
| | | var version = new Row()
|
| | | {
|
| | | IsDefault = !Versions.Any(),
|
| | | IsDefault = !Versions.Any(x => x.State != State.Removed),
|
| | | Host = BuildHost.Windows,
|
| | | Path = "",
|
| | | Compiler = "msvc",
|
| | | LastRow = false
|
| | | LastRow = false,
|
| | | State = State.Modified | (State)Column.VersionName | (State)Column.Host
|
| | | | (State)Column.Path | (State)Column.Compiler
|
| | | };
|
| | | if (version.IsDefault)
|
| | | version.State |= (State)Column.IsDefault;
|
| | | Rows.Insert(Rows.Count - 1, version);
|
| | | FocusedField = version.FieldVersionName;
|
| | | Validate(true);
|
| | |
| | | void Remove_Click(object sender, RoutedEventArgs e)
|
| | | {
|
| | | if (sender is Button button && GetBinding(button) is Row version) {
|
| | | Rows.Remove(version);
|
| | | if (version.IsDefault && Versions.Any())
|
| | | Versions.First().IsDefault = true;
|
| | | version.State = State.Removed;
|
| | | if (version.IsDefault) {
|
| | | var first = Versions.FirstOrDefault(x => x.State != State.Removed);
|
| | | if (first != null)
|
| | | SetDefaultState(ref first, true);
|
| | | }
|
| | | Validate(true);
|
| | | }
|
| | | }
|
| | |
|
| | | static string NormalizePath(string path)
|
| | | {
|
| | | if (string.IsNullOrEmpty(path))
|
| | | return path;
|
| | | try {
|
| | | return Path.GetFullPath(new Uri(path).LocalPath)
|
| | | .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
|
| | | .ToUpperInvariant();
|
| | | } catch (UriFormatException) {
|
| | | return null;
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | if (openFileDialog.ShowDialog() == true) {
|
| | | var qmakePath = openFileDialog.FileName;
|
| | | var qmakeDir = Path.GetDirectoryName(qmakePath);
|
| | | var previousPath = NormalizePath(version.Path);
|
| | | if (Path.GetFileName(qmakeDir)
|
| | | .Equals("bin", StringComparison.InvariantCultureIgnoreCase)) {
|
| | | qmakeDir = Path.GetDirectoryName(qmakeDir);
|
| | |
| | | } else {
|
| | | version.Path = qmakePath;
|
| | | }
|
| | |
|
| | | if (previousPath != NormalizePath(version.Path))
|
| | | version.State |= State.Modified | (State)Column.Path;
|
| | |
|
| | | if (string.IsNullOrEmpty(version.VersionName)) {
|
| | | version.VersionName = string.Format("{0}_{1}",
|
| | | Path.GetFileName(Path.GetDirectoryName(qmakeDir)),
|
| | | Path.GetFileName(qmakeDir))
|
| | | .Replace(" ", "_");
|
| | | version.State |= State.Modified | (State)Column.VersionName;
|
| | | }
|
| | |
|
| | | Validate(true);
|
| | | }
|
| | | }
|
| | |
| | | static object GetBinding(FrameworkElement control)
|
| | | {
|
| | | if (control == null
|
| | | || control.BindingGroup == null
|
| | | || control.BindingGroup.Items == null
|
| | | || control.BindingGroup.Items.Count == 0) {
|
| | | || control.BindingGroup == null
|
| | | || control.BindingGroup.Items == null
|
| | | || control.BindingGroup.Items.Count == 0) {
|
| | | return null;
|
| | | }
|
| | | return control.BindingGroup.Items[0];
|
| | |
| | | {
|
| | | while (control != null) {
|
| | | if (control is ContentPresenter contentPresenter
|
| | | && contentPresenter.Parent is DataGridCell cell) {
|
| | | && contentPresenter.Parent is DataGridCell cell) {
|
| | | return cell;
|
| | | }
|
| | | control = VisualTreeHelper.GetParent(control);
|
| | |
| | | <!--
|
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2020 The Qt Company Ltd.
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | |
| | | xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
| | | xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
| | | xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
| | | xmlns:local="clr-namespace:QtVsTools.Options"
|
| | | mc:Ignorable="d"
|
| | | d:DesignHeight="450"
|
| | | d:DesignWidth="800">
|
| | |
| | | Color="Transparent" />
|
| | | <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}"
|
| | | Color="Transparent" />
|
| | | <BooleanToVisibilityConverter x:Key="b2v" />
|
| | | </DataGrid.Resources>
|
| | | <DataGrid.RowStyle>
|
| | | <Style TargetType="{x:Type DataGridRow}">
|
| | | <Setter Property="Visibility" Value="{Binding RowVisible, Converter={StaticResource b2v}}"/>
|
| | | </Style>
|
| | | </DataGrid.RowStyle>
|
| | | <DataGrid.CellStyle>
|
| | | <Style TargetType="DataGridCell">
|
| | | <Setter Property="BorderThickness"
|
| | |
| | | <CheckBox x:Name="IsDefault"
|
| | | IsChecked="{Binding IsDefault}"
|
| | | Focusable="{Binding DefaultEnabled}"
|
| | | IsHitTestVisible="{Binding DefaultEnabled}"
|
| | | Visibility="{Binding RowVisibility}"
|
| | | Visibility="{Binding RowContentVisibility}"
|
| | | BorderThickness="1"
|
| | | Background="Transparent"
|
| | | VerticalAlignment="Center"
|
| | |
| | | <!--//// Name ////-->
|
| | | <Grid>
|
| | | <Button Cursor="Hand"
|
| | | Visibility="{Binding RowVisibility}"
|
| | | Visibility="{Binding RowContentVisibility}"
|
| | | HorizontalAlignment="Left"
|
| | | VerticalAlignment="Center"
|
| | | Click="Remove_Click">
|
| | |
| | | </Button>
|
| | | <TextBox x:Name="VersionName"
|
| | | Text="{Binding VersionName}"
|
| | | Visibility="{Binding RowVisibility}"
|
| | | Visibility="{Binding RowContentVisibility}"
|
| | | IsEnabled="{Binding NameEnabled}"
|
| | | FontWeight="{Binding FontWeight}"
|
| | | Margin="20,4,2,4"
|
| | |
| | | LostFocus="Control_LostFocus"
|
| | | TextChanged="TextBox_TextChanged"
|
| | | SelectionChanged="TextBox_SelectionChanged"
|
| | | ToolTip="{Binding FieldName.ToolTip}">
|
| | | ToolTip="{Binding FieldVersionName.ToolTip}">
|
| | | <TextBox.Resources>
|
| | | <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
|
| | | Color="LimeGreen" />
|
| | |
| | | <DataTemplate>
|
| | | <!--//// Host ////-->
|
| | | <ComboBox x:Name="Host"
|
| | | Visibility="{Binding RowVisibility}"
|
| | | Visibility="{Binding RowContentVisibility}"
|
| | | IsEditable="True"
|
| | | IsReadOnly="True"
|
| | | BorderThickness="0"
|
| | |
| | | </Button>
|
| | | <TextBox x:Name="Path"
|
| | | Text="{Binding Path}"
|
| | | Visibility="{Binding RowVisibility}"
|
| | | Visibility="{Binding RowContentVisibility}"
|
| | | BorderThickness="0"
|
| | | Background="Transparent"
|
| | | Margin="{Binding PathMargin}"
|
| | |
| | | <!--//// Compiler ////-->
|
| | | <TextBox x:Name="Compiler"
|
| | | Text="{Binding Compiler}"
|
| | | Visibility="{Binding RowVisibility}"
|
| | | Visibility="{Binding RowContentVisibility}"
|
| | | IsEnabled="{Binding CompilerEnabled}"
|
| | | BorderThickness="0"
|
| | | Background="Transparent"
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | 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;
|
| | | }
|
| | | }
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using QtVsTools.Core;
|
| | | using System.Collections.Generic;
|
| | | using System.IO;
|
| | | using System.Text.RegularExpressions;
|
| | | using System.Windows.Forms;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | |
|
| | | namespace QtVsTools
|
| | | {
|
| | | using Core;
|
| | |
|
| | | public static class ExtLoader
|
| | | {
|
| | | public static void ImportProFile()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var vm = QtVersionManager.The();
|
| | | var qtVersion = vm.GetDefaultVersion();
|
| | | var qtDir = vm.GetInstallPath(qtVersion);
|
| | |
|
| | | if (qtDir == null) {
|
| | | Messages.DisplayErrorMessage(SR.GetString("CannotFindQMake"));
|
| | | return;
|
| | |
| | |
|
| | | public static void ImportPriFile(EnvDTE.Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (project == null)
|
| | | return;
|
| | |
|
| | | VCProject vcproj;
|
| | | if (!HelperFunctions.IsQtProject(project))
|
| | | if (!HelperFunctions.IsVsToolsProject(project))
|
| | | return;
|
| | |
|
| | | vcproj = project.Object as VCProject;
|
| | |
| | |
|
| | | public static void ImportPriFile(EnvDTE.Project project, string fileName)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (project == null)
|
| | | return;
|
| | |
|
| | | if (!HelperFunctions.IsQtProject(project))
|
| | | if (!HelperFunctions.IsVsToolsProject(project))
|
| | | return;
|
| | |
|
| | | var vcproj = project.Object as VCProject;
|
| | |
| | |
|
| | | private static List<string> ResolveFilesFromQMake(string[] files, EnvDTE.Project project, string path)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var lst = new List<string>();
|
| | | foreach (var file in files) {
|
| | | var s = ResolveEnvironmentVariables(file, project);
|
New file |
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | | **
|
| | | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
| | | ** Commercial License Usage
|
| | | ** Licensees holding valid commercial Qt licenses may use this file in
|
| | | ** accordance with the commercial license agreement provided with the
|
| | | ** Software or, alternatively, in accordance with the terms contained in
|
| | | ** a written agreement between you and The Qt Company. For licensing terms
|
| | | ** and conditions see https://www.qt.io/terms-conditions. For further
|
| | | ** information use the contact form at https://www.qt.io/contact-us.
|
| | | **
|
| | | ** GNU General Public License Usage
|
| | | ** Alternatively, this file may be used under the terms of the GNU
|
| | | ** General Public License version 3 as published by the Free Software
|
| | | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
| | | ** included in the packaging of this file. Please review the following
|
| | | ** information to ensure the GNU General Public License requirements will
|
| | | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
| | | **
|
| | | ** $QT_END_LICENSE$
|
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using Microsoft.VisualStudio.Imaging;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | |
|
| | | namespace QtVsTools
|
| | | {
|
| | | using Common;
|
| | | using Microsoft.VisualStudio.Imaging.Interop;
|
| | | using VisualStudio;
|
| | |
|
| | | public static class Notifications
|
| | | {
|
| | | static LazyFactory StaticLazy { get; } = new LazyFactory();
|
| | |
|
| | | public static NoQtVersion NoQtVersion
|
| | | => StaticLazy.Get(() => NoQtVersion, () => new NoQtVersion());
|
| | |
|
| | | public static NotifyInstall NotifyInstall
|
| | | => StaticLazy.Get(() => NotifyInstall, () => new NotifyInstall());
|
| | | }
|
| | |
|
| | | public class NoQtVersion : InfoBarMessage
|
| | | {
|
| | | protected override ImageMoniker Icon => KnownMonikers.StatusWarning;
|
| | |
|
| | | protected override TextSpan[] Text => new TextSpan[]
|
| | | {
|
| | | new TextSpan { Bold = true, Text = "Qt Visual Studio Tools" },
|
| | | new TextSpacer(2),
|
| | | "\u2014", // Em dash
|
| | | new TextSpacer(2),
|
| | | "You must select a Qt version to use for development."
|
| | | };
|
| | |
|
| | | protected override Hyperlink[] Hyperlinks => new Hyperlink[]
|
| | | {
|
| | | new Hyperlink
|
| | | {
|
| | | Text = "Select Qt version...",
|
| | | CloseInfoBar = false,
|
| | | OnClicked = () =>
|
| | | QtVsToolsPackage.Instance.ShowOptionPage(typeof(Options.QtVersionsPage))
|
| | | }
|
| | | };
|
| | | }
|
| | |
|
| | | public class NotifyInstall : InfoBarMessage
|
| | | {
|
| | | protected override ImageMoniker Icon => KnownMonikers.StatusInformation;
|
| | |
|
| | | protected override TextSpan[] Text => new TextSpan[]
|
| | | {
|
| | | new TextSpan { Bold = true, Text = "Qt Visual Studio Tools" },
|
| | | new TextSpacer(2),
|
| | | "\u2014", // Em dash
|
| | | new TextSpacer(2),
|
| | | $"Version {Version.USER_VERSION} was recently installed."
|
| | | };
|
| | |
|
| | | protected override Hyperlink[] Hyperlinks => new Hyperlink[]
|
| | | {
|
| | | new Hyperlink
|
| | | {
|
| | | Text = "Release Notes",
|
| | | CloseInfoBar = false,
|
| | | OnClicked= () =>
|
| | | {
|
| | | VsShellUtilities.OpenSystemBrowser(
|
| | | "https://code.qt.io/cgit/qt-labs/vstools.git/tree/Changelog");
|
| | | }
|
| | | },
|
| | | new Hyperlink
|
| | | {
|
| | | Text = "Don't show again",
|
| | | CloseInfoBar = true,
|
| | | OnClicked = () =>
|
| | | {
|
| | | QtVsToolsPackage.Instance.Options.NotifyInstalled = false;
|
| | | QtVsToolsPackage.Instance.Options.SaveSettingsToStorage();
|
| | | }
|
| | | }
|
| | | };
|
| | | }
|
| | | }
|
| | |
| | | public string QtDir { get; set; }
|
| | |
|
| | | public bool IsFlat { get; private set; }
|
| | | public bool IsValid { get; private set; }
|
| | | private bool IsValid { get; set; }
|
| | |
|
| | | public string[] SourceFiles { get; private set; }
|
| | | public string[] HeaderFiles { get; private set; }
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using EnvDTE;
|
| | | using Microsoft.VisualStudio.Settings;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | | using Microsoft.VisualStudio.Shell.Settings;
|
| | | using QtVsTools.Core;
|
| | | using QtVsTools.VisualStudio;
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.ComponentModel.Design;
|
| | |
| | | using System.Data.SQLite;
|
| | | using System.IO;
|
| | | using System.Linq;
|
| | | using System.Threading.Tasks;
|
| | | using Task = System.Threading.Tasks.Task;
|
| | | using EnvDTE;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | |
|
| | | namespace QtVsTools
|
| | | {
|
| | | using Core;
|
| | | using VisualStudio;
|
| | |
|
| | | public class QtHelp
|
| | | {
|
| | | public enum SourcePreference { Online, Offline }
|
| | |
|
| | | public static QtHelp Instance
|
| | | private static QtHelp Instance
|
| | | {
|
| | | get;
|
| | | private set;
|
| | | set;
|
| | | }
|
| | |
|
| | | public static void Initialize(Package package)
|
| | | public static void Initialize()
|
| | | {
|
| | | Instance = new QtHelp(package);
|
| | | Instance = new QtHelp();
|
| | | }
|
| | |
|
| | | const int F1QtHelpId = 0x0502;
|
| | |
|
| | | readonly Package package;
|
| | | public static readonly Guid MainMenuGuid = new Guid("58f83fff-d39d-4c66-810b-2702e1f04e73");
|
| | | private static readonly Guid MainMenuGuid = new Guid("58f83fff-d39d-4c66-810b-2702e1f04e73");
|
| | |
|
| | | QtHelp(Package pkg)
|
| | | private QtHelp()
|
| | | {
|
| | | if (pkg == null)
|
| | | throw new ArgumentNullException("package");
|
| | | package = pkg;
|
| | |
|
| | | var commandService = VsServiceProvider
|
| | | .GetService<IMenuCommandService, OleMenuCommandService>();
|
| | | if (commandService == null)
|
| | |
| | | var menuCommandID = new CommandID(MainMenuGuid, F1QtHelpId);
|
| | | commandService.AddCommand(new MenuCommand(F1QtHelpEventHandler, menuCommandID));
|
| | | }
|
| | |
|
| | | IServiceProvider ServiceProvider
|
| | | {
|
| | | get { return package; }
|
| | | }
|
| | |
|
| | | static bool IsSuperfluousCharacter(string text)
|
| | | {
|
| | | switch (text) {
|
| | |
| | |
|
| | | void F1QtHelpEventHandler(object sender, EventArgs args)
|
| | | {
|
| | | QueryEditorContextHelp(true);
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | if (!ShowEditorContextHelp()) {
|
| | | Messages.Print("No help match was found. You can still try to search online at "
|
| | | + "https://doc.qt.io" + ".", false, true);
|
| | | }
|
| | | }
|
| | |
|
| | | public static bool QueryEditorContextHelp(bool defaultTryOnline = false)
|
| | | public static bool ShowEditorContextHelp()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | try {
|
| | | var dte = VsServiceProvider.GetService<SDTE, DTE>();
|
| | | var objTextDocument = dte?.ActiveDocument?.Object() as TextDocument;
|
| | |
| | | var project = HelperFunctions.GetSelectedQtProject(dte);
|
| | | if (project == null) {
|
| | | project = HelperFunctions.GetSelectedProject(dte);
|
| | | if (project != null && HelperFunctions.IsQMakeProject(project)) {
|
| | | if (project != null && HelperFunctions.IsQtProject(project)) {
|
| | | var qmakeQtDir = HelperFunctions.GetQtDirFromQMakeProject(project);
|
| | | qtVersion = QtVersionManager.The().GetQtVersionFromInstallDir(qmakeQtDir);
|
| | | }
|
| | |
| | |
|
| | | var qchFiles = Directory.GetFiles(docPath, "*?.qch");
|
| | | if (qchFiles.Length == 0)
|
| | | return false;
|
| | | return TryShowGenericSearchResultsOnline(keyword, info.qtMajor);
|
| | |
|
| | | var offline = QtVsToolsPackage.Instance.Options.HelpPreference == SourcePreference.Offline;
|
| | |
|
| | |
| | | using (var connection = new SQLiteConnection(builder.ToString())) {
|
| | | connection.Open();
|
| | | using (var command = new SQLiteCommand(linksForKeyword, connection)) {
|
| | | using (var reader =
|
| | | Task.Run(async () => await command.ExecuteReaderAsync()).Result) {
|
| | | var reader = QtVsToolsPackage.Instance.JoinableTaskFactory
|
| | | .Run(async () => await command.ExecuteReaderAsync());
|
| | | using (reader) {
|
| | | while (reader.Read()) {
|
| | | var title = GetString(reader, 0);
|
| | | if (string.IsNullOrWhiteSpace(title))
|
| | |
| | | var uri = string.Empty;
|
| | | switch (links.Values.Count) {
|
| | | case 0:
|
| | | if (!offline && defaultTryOnline) {
|
| | | uri = new UriBuilder($"https://doc.qt.io/qt-{info.qtMajor}/search-results.html")
|
| | | {
|
| | | Query = "q=" + keyword
|
| | | }.ToString();
|
| | | } else {
|
| | | return false;
|
| | | }
|
| | | break;
|
| | | return TryShowGenericSearchResultsOnline(keyword, info.qtMajor);
|
| | | case 1:
|
| | | uri = links.First().Value;
|
| | | break;
|
| | |
| | | };
|
| | | if (!dialog.ShowModal().GetValueOrDefault())
|
| | | return false;
|
| | | uri = dialog.Link
|
| | | .Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
| | | uri = dialog.Link;
|
| | | break;
|
| | | }
|
| | |
|
| | | if (string.IsNullOrEmpty(uri)) { // offline mode without a single search hit
|
| | | VsShellUtilities.ShowMessageBox(Instance.ServiceProvider,
|
| | | "Your search - " + keyword + " - did not match any documents.",
|
| | | uri = HelperFunctions.FromNativeSeparators(uri);
|
| | | var helpUri = new Uri(uri);
|
| | | if (helpUri.IsFile && !File.Exists(helpUri.LocalPath)) {
|
| | | VsShellUtilities.ShowMessageBox(QtVsToolsPackage.Instance,
|
| | | "Your search - " + keyword + " - did match a document, but it could "
|
| | | + "not be found on disk. To use the online help, select: "
|
| | | + "Tools | Options | Qt | Preferred source | Online",
|
| | | string.Empty, OLEMSGICON.OLEMSGICON_INFO, OLEMSGBUTTON.OLEMSGBUTTON_OK,
|
| | | OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
|
| | | } else {
|
| | | var helpUri = new Uri(uri.Replace('\\', '/'));
|
| | | if (helpUri.IsFile && !File.Exists(helpUri.LocalPath)) {
|
| | | VsShellUtilities.ShowMessageBox(Instance.ServiceProvider,
|
| | | "Your search - " + keyword + " - did match a document, but it could "
|
| | | + "not be found on disk. To use the online help, select: "
|
| | | + "Help | Set Qt Help Preference | Use Online Documentation",
|
| | | string.Empty, OLEMSGICON.OLEMSGICON_INFO, OLEMSGBUTTON.OLEMSGBUTTON_OK,
|
| | | OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
|
| | | } else {
|
| | | VsShellUtilities.OpenSystemBrowser(HelperFunctions.ChangePathFormat(uri));
|
| | | }
|
| | | VsShellUtilities.OpenSystemBrowser(uri);
|
| | | }
|
| | | } catch (Exception e) {
|
| | | Messages.Print(
|
| | | e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | }
|
| | | return true;
|
| | | }
|
| | |
|
| | | private static bool TryShowGenericSearchResultsOnline(string keyword, uint version)
|
| | | {
|
| | | if (QtVsToolsPackage.Instance.Options.HelpPreference != SourcePreference.Online)
|
| | | return false;
|
| | |
|
| | | VsShellUtilities.OpenSystemBrowser(HelperFunctions.FromNativeSeparators(
|
| | | new UriBuilder($"https://doc.qt.io/qt-{version}/search-results.html")
|
| | | {
|
| | | Query = "q=" + keyword
|
| | | }.ToString())
|
| | | );
|
| | | return true;
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | <!--
|
| | | *****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | *****************************************************************************
|
| | | -->
|
| | |
|
| | | <local:VsToolsDialogWindow x:Class="QtVsTools.QtHelpLinkChooser"
|
| | | xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
| | | xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
| | | xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
| | | xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
| | | xmlns:local="clr-namespace:QtVsTools"
|
| | | Width="400"
|
| | | Height="250"
|
| | | MinWidth="400"
|
| | | MinHeight="250"
|
| | | mc:Ignorable="d"
|
| | | Title="Choose Topic"
|
| | | ShowInTaskbar="False"
|
| | | HasHelpButton="False"
|
| | | HasMinimizeButton="False"
|
| | | ResizeMode="CanResizeWithGrip"
|
| | | WindowStartupLocation="CenterOwner">
|
| | | <local:VsToolsDialogWindow.Resources>
|
| | | <BooleanToVisibilityConverter x:Key="b2v" />
|
| | | <vsui:DialogWindow x:Class="QtVsTools.QtHelpLinkChooser"
|
| | | xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
| | | xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
| | | xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
| | | xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
| | | xmlns:vsui="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.15.0"
|
| | | Width="400"
|
| | | Height="250"
|
| | | MinWidth="400"
|
| | | MinHeight="250"
|
| | | mc:Ignorable="d"
|
| | | Title="Choose Topic"
|
| | | ShowInTaskbar="False"
|
| | | HasHelpButton="False"
|
| | | HasMinimizeButton="False"
|
| | | ResizeMode="CanResizeWithGrip"
|
| | | WindowStartupLocation="CenterOwner">
|
| | | <vsui:DialogWindow.Resources>
|
| | | <Style x:Key="ListBoxDoubleClickStyle"
|
| | | TargetType="ListBoxItem">
|
| | | <EventSetter Event="MouseDoubleClick"
|
| | | Handler="OnListBoxItem_DoubleClick" />
|
| | | </Style>
|
| | | </local:VsToolsDialogWindow.Resources>
|
| | | <Grid Margin="10"
|
| | | FocusManager.FocusedElement="{Binding ElementName=searchBox}">
|
| | | </vsui:DialogWindow.Resources>
|
| | | <Grid Margin="10">
|
| | | <Grid.RowDefinitions>
|
| | | <RowDefinition Height="Auto" />
|
| | | <RowDefinition Height="Auto" />
|
| | |
| | | Text="{Binding Path=Keyword}" />
|
| | | <Run Text=":" />
|
| | | </TextBlock>
|
| | | <Grid Grid.Row="1"
|
| | | MinHeight="22"
|
| | | Background="White">
|
| | | <TextBlock Text=" Filter..."
|
| | | Foreground="LightSteelBlue"
|
| | | VerticalAlignment="Center"
|
| | | Visibility="{Binding ElementName=searchBox,
|
| | | Path=Text.IsEmpty, Converter={StaticResource b2v}}" />
|
| | | <TextBox Name="searchBox"
|
| | | Background="Transparent"
|
| | | TextChanged="OnSearchBox_TextChanged"
|
| | | VerticalContentAlignment="Center" />
|
| | | <Grid Grid.Row="1">
|
| | | <Grid Name="searchControlHost" />
|
| | | </Grid>
|
| | | <ListBox Grid.Row="2"
|
| | | Margin="0,10,0,0"
|
| | |
| | | Margin="0,10,0,0" />
|
| | | </StackPanel>
|
| | | </Grid>
|
| | | </local:VsToolsDialogWindow>
|
| | | </vsui:DialogWindow>
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | using System.Windows.Controls;
|
| | | using System.Windows.Data;
|
| | | using System.Windows.Input;
|
| | | using Microsoft.VisualStudio.PlatformUI;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | | using QtVsTools.VisualStudio;
|
| | |
|
| | | namespace QtVsTools
|
| | | {
|
| | | partial class QtHelpLinkChooser : VsToolsDialogWindow
|
| | | partial class QtHelpLinkChooser : DialogWindow
|
| | | {
|
| | | public QtHelpLinkChooser()
|
| | | {
|
| | |
| | | }
|
| | |
|
| | | public string Link { get; set; }
|
| | | public string SearchText { get; set; }
|
| | |
|
| | | public string Keyword { private get; set; }
|
| | | public Dictionary<string, string> Links { private get; set; }
|
| | |
|
| | | private void OnLoaded(object sender, RoutedEventArgs e)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var view = CollectionViewSource.GetDefaultView(linkListBox.ItemsSource);
|
| | | view.Filter = obj =>
|
| | | {
|
| | | if (string.IsNullOrEmpty(searchBox.Text))
|
| | | if (string.IsNullOrEmpty(SearchText))
|
| | | return true;
|
| | |
|
| | | var item = (KeyValuePair<string, string>)obj;
|
| | | return item.Key.IndexOf(searchBox.Text, StringComparison.OrdinalIgnoreCase) >= 0;
|
| | | return item.Key.IndexOf(SearchText, StringComparison.OrdinalIgnoreCase) >= 0;
|
| | | };
|
| | | linkListBox.SelectedIndex = 0;
|
| | | }
|
| | |
|
| | | private void OnSearchBox_TextChanged(object sender, TextChangedEventArgs e)
|
| | | {
|
| | | CollectionViewSource.GetDefaultView(linkListBox.ItemsSource).Refresh();
|
| | | if (linkListBox.Items.Count == 1 || linkListBox.SelectedItem == null)
|
| | | linkListBox.SelectedIndex = 0;
|
| | | var factory = VsServiceProvider
|
| | | .GetService<SVsWindowSearchHostFactory, IVsWindowSearchHostFactory>();
|
| | | var host = factory.CreateWindowSearchHost(searchControlHost);
|
| | |
|
| | | host.SetupSearch(new ListBoxSearch(linkListBox, value => SearchText = value));
|
| | | host.Activate(); // set focus
|
| | | }
|
| | |
|
| | | private void OnListBoxItem_DoubleClick(object sender, MouseButtonEventArgs e)
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using EnvDTE;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using QtVsTools.Core;
|
| | | using QtVsTools.VisualStudio;
|
| | | using System;
|
| | | using System.ComponentModel.Design;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using EnvDTE;
|
| | |
|
| | | namespace QtVsTools
|
| | | {
|
| | | using Core;
|
| | | using VisualStudio;
|
| | |
|
| | | /// <summary>
|
| | | /// Command handler
|
| | | /// </summary>
|
| | |
| | | /// <summary>
|
| | | /// Command menu group (command set GUID).
|
| | | /// </summary>
|
| | | public static readonly Guid ItemContextMenuGuid = new Guid("9f67a0bd-ee0a-47e3-b656-5efb12e3c770");
|
| | | private static readonly Guid ItemContextMenuGuid = new Guid("9f67a0bd-ee0a-47e3-b656-5efb12e3c770");
|
| | |
|
| | | /// <summary>
|
| | | /// Gets the instance of the command.
|
| | | /// </summary>
|
| | | public static QtItemContextMenu Instance
|
| | | private static QtItemContextMenu Instance
|
| | | {
|
| | | get;
|
| | | private set;
|
| | | set;
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// Initializes the singleton instance of the command.
|
| | | /// </summary>
|
| | | /// <param name="package">Owner package, not null.</param>
|
| | | public static void Initialize(Package package)
|
| | | public static void Initialize()
|
| | | {
|
| | | Instance = new QtItemContextMenu(package);
|
| | | Instance = new QtItemContextMenu();
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// VS Package that provides this command, not null.
|
| | | /// </summary>
|
| | | private readonly Package m_package;
|
| | |
|
| | | /// <summary>
|
| | | /// Command ID.
|
| | |
| | | /// Initializes a new instance of the <see cref="QtMainMenu"/> class.
|
| | | /// Adds our command handlers for menu (commands must exist in the command table file)
|
| | | /// </summary>
|
| | | /// <param name="package">Owner package, not null.</param>
|
| | | private QtItemContextMenu(Package package)
|
| | | private QtItemContextMenu()
|
| | | {
|
| | | if (package == null)
|
| | | throw new ArgumentNullException("package");
|
| | |
|
| | | m_package = package;
|
| | |
|
| | | var commandService = VsServiceProvider
|
| | | .GetService<IMenuCommandService, OleMenuCommandService>();
|
| | | if (commandService == null)
|
| | |
| | |
|
| | | private void execHandler(object sender, EventArgs e)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var command = sender as OleMenuCommand;
|
| | | if (command == null)
|
| | | return;
|
| | |
| | |
|
| | | private void beforeQueryStatus(object sender, EventArgs e)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var command = sender as OleMenuCommand;
|
| | | if (command == null)
|
| | | return;
|
| | |
| | | command.Visible = false;
|
| | |
|
| | | var prj = HelperFunctions.GetSelectedProject(QtVsToolsPackage.Instance.Dte);
|
| | | if (!HelperFunctions.IsQtProject(prj) || QtVsToolsPackage.Instance.Dte.SelectedItems.Count <= 0)
|
| | | if (!HelperFunctions.IsVsToolsProject(prj) || QtVsToolsPackage.Instance.Dte.SelectedItems.Count <= 0)
|
| | | return;
|
| | |
|
| | | foreach (SelectedItem si in QtVsToolsPackage.Instance.Dte.SelectedItems) {
|
| | |
| | | return; // Don't display commands if one of the selected files is not a .ts file.
|
| | | }
|
| | |
|
| | | command.Enabled = true;
|
| | | command.Enabled = Translation.ToolsAvailable(prj);
|
| | | command.Visible = true;
|
| | | }
|
| | | }
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using EnvDTE;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using QtVsTools.Core;
|
| | | using QtVsTools.VisualStudio;
|
| | | using System;
|
| | | using System.ComponentModel.Design;
|
| | | using System.Windows.Forms;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using EnvDTE;
|
| | |
|
| | | namespace QtVsTools
|
| | | {
|
| | | using Core;
|
| | | using VisualStudio;
|
| | |
|
| | | /// <summary>
|
| | | /// Command handler
|
| | | /// </summary>
|
| | |
| | | /// <summary>
|
| | | /// Command menu group (command set GUID).
|
| | | /// </summary>
|
| | | public static readonly Guid MainMenuGuid = new Guid("58f83fff-d39d-4c66-810b-2702e1f04e73");
|
| | | private static readonly Guid MainMenuGuid = new Guid("58f83fff-d39d-4c66-810b-2702e1f04e73");
|
| | |
|
| | | /// <summary>
|
| | | /// Gets the instance of the command.
|
| | | /// </summary>
|
| | | public static QtMainMenu Instance
|
| | | private static QtMainMenu Instance
|
| | | {
|
| | | get;
|
| | | private set;
|
| | | set;
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// Initializes the singleton instance of the command.
|
| | | /// </summary>
|
| | | /// <param name="package">Owner package, not null.</param>
|
| | | public static void Initialize(Package package)
|
| | | public static void Initialize()
|
| | | {
|
| | | Instance = new QtMainMenu(package);
|
| | | Instance = new QtMainMenu();
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | |
| | | {
|
| | | QtVersionId = 0x0500,
|
| | | ViewQtHelpId = 0x0501,
|
| | | ViewGettingStartedId = 0x0503,
|
| | | LaunchDesignerId = 0x0100,
|
| | | LaunchLinguistId = 0x0101,
|
| | | OpenProFileId = 0x0102,
|
| | | ImportPriFileId = 0x0103,
|
| | | ExportPriFileId = 0x0104,
|
| | | ExportProFileId = 0x0105,
|
| | | CreateNewTsFileId = 0x0107,
|
| | | ConvertToQtMsBuild = 0x0130,
|
| | | ConvertToQtId = 0x0124,
|
| | | ConvertToQmakeId = 0x0108,
|
| | | QtProjectSettingsId = 0x0109,
|
| | | ChangeProjectQtVersionId = 0x0126,
|
| | | QtOptionsId = 0x0110,
|
| | |
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// VS Package that provides this command, not null.
|
| | | /// </summary>
|
| | | private readonly Package m_package;
|
| | |
|
| | | /// <summary>
|
| | | /// Initializes a new instance of the <see cref="QtMainMenu"/> class.
|
| | | /// Adds our command handlers for menu (commands must exist in the command table file)
|
| | | /// </summary>
|
| | | /// <param name="package">Owner package, not null.</param>
|
| | | private QtMainMenu(Package package)
|
| | | private QtMainMenu()
|
| | | {
|
| | | if (package == null)
|
| | | throw new ArgumentNullException("package");
|
| | |
|
| | | m_package = package;
|
| | |
|
| | | var commandService = VsServiceProvider
|
| | | .GetService<IMenuCommandService, OleMenuCommandService>();
|
| | | if (commandService == null)
|
| | |
| | |
|
| | | private void execHandler(object sender, EventArgs e)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var command = sender as OleMenuCommand;
|
| | | if (command == null)
|
| | | return;
|
| | |
| | | switch ((CommandId)command.CommandID.ID) {
|
| | | case CommandId.ViewQtHelpId:
|
| | | VsShellUtilities.OpenSystemBrowser("https://www.qt.io/developers");
|
| | | break;
|
| | | case CommandId.ViewGettingStartedId:
|
| | | VsShellUtilities.OpenSystemBrowser("https://doc.qt.io/qtvstools/qtvstools-getting-started.html");
|
| | | break;
|
| | | case CommandId.LaunchDesignerId:
|
| | | QtVsToolsPackage.Instance.QtDesigner.Start(hideWindow: false);
|
| | |
| | | case CommandId.ExportProFileId:
|
| | | ExtLoader.ExportProFile();
|
| | | break;
|
| | | case CommandId.CreateNewTsFileId:
|
| | | Translation.CreateNewTranslationFile(HelperFunctions.GetSelectedQtProject(QtVsToolsPackage
|
| | | .Instance.Dte));
|
| | | break;
|
| | | case CommandId.ConvertToQtId:
|
| | | case CommandId.ConvertToQmakeId: {
|
| | | var caption = SR.GetString("ConvertTitle");
|
| | | var text = SR.GetString("ConvertConfirmation");
|
| | | if (MessageBox.Show(text, caption, MessageBoxButtons.YesNo) == DialogResult.Yes) {
|
| | | HelperFunctions.ToggleProjectKind(HelperFunctions.GetSelectedProject(QtVsToolsPackage
|
| | | .Instance.Dte));
|
| | | }
|
| | | }
|
| | | break;
|
| | | case CommandId.ConvertToQtMsBuild: {
|
| | | QtMsBuildConverter.SolutionToQtMsBuild();
|
| | | }
|
| | | case CommandId.ConvertToQtMsBuild:
|
| | | QtMsBuildConverter.SolutionToQtMsBuild();
|
| | | break;
|
| | | case CommandId.QtProjectSettingsId: {
|
| | | var pro = HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte);
|
| | |
| | | if (projectVersion >= Resources.qtMinFormatVersion_Settings) {
|
| | | QtVsToolsPackage.Instance.Dte.ExecuteCommand("Project.Properties");
|
| | | } else if (pro != null) {
|
| | | using (var formProjectQtSettings = new FormProjectQtSettings()) {
|
| | | formProjectQtSettings.SetProject(pro);
|
| | | formProjectQtSettings.StartPosition = FormStartPosition.CenterParent;
|
| | | var ww = new MainWinWrapper(QtVsToolsPackage.Instance.Dte);
|
| | | formProjectQtSettings.ShowDialog(ww);
|
| | | }
|
| | | Legacy.QtMenu.ShowFormProjectQtSettings(pro);
|
| | | } else {
|
| | | MessageBox.Show(SR.GetString("NoProjectOpened"));
|
| | | }
|
| | | }
|
| | | break;
|
| | | case CommandId.ChangeProjectQtVersionId: {
|
| | | var pro = HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte);
|
| | | if (HelperFunctions.IsQMakeProject(pro)) {
|
| | | using (var formChangeQtVersion = new FormChangeQtVersion()) {
|
| | | formChangeQtVersion.UpdateContent(ChangeFor.Project);
|
| | | var ww = new MainWinWrapper(QtVsToolsPackage.Instance.Dte);
|
| | | if (formChangeQtVersion.ShowDialog(ww) == DialogResult.OK) {
|
| | | var qtVersion = formChangeQtVersion.GetSelectedQtVersion();
|
| | | HelperFunctions.SetDebuggingEnvironment(pro, "PATH=" + QtVersionManager
|
| | | .The().GetInstallPath(qtVersion) + @"\bin;$(PATH)", true);
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | case CommandId.ChangeProjectQtVersionId:
|
| | | Legacy.QtMenu.ShowFormChangeProjectQtVersion();
|
| | | break;
|
| | | case CommandId.QtOptionsId:
|
| | | QtVsToolsPackage.Instance.ShowOptionPage(typeof(Options.QtOptionsPage));
|
| | |
| | |
|
| | | private void beforeQueryStatus(object sender, EventArgs e)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var command = sender as OleMenuCommand;
|
| | | if (command == null)
|
| | | return;
|
| | |
|
| | | var project = HelperFunctions.GetSelectedProject(QtVsToolsPackage.Instance.Dte);
|
| | |
|
| | | switch ((CommandId)command.CommandID.ID) {
|
| | | case CommandId.ViewQtHelpId:
|
| | | case CommandId.ViewGettingStartedId:
|
| | | command.Visible = command.Enabled = true;
|
| | | break;
|
| | | case CommandId.QtVersionId:
|
| | |
| | | case CommandId.ImportPriFileId:
|
| | | case CommandId.ExportPriFileId:
|
| | | case CommandId.ExportProFileId:
|
| | | case CommandId.CreateNewTsFileId: {
|
| | | command.Visible = true;
|
| | | command.Enabled = HelperFunctions.IsQtProject(HelperFunctions
|
| | | .GetSelectedProject(QtVsToolsPackage.Instance.Dte));
|
| | | }
|
| | | command.Visible = true;
|
| | | command.Enabled = HelperFunctions.IsVsToolsProject(project);
|
| | | break;
|
| | | // TODO: Fix these functionality and re-enable the menu items
|
| | | case CommandId.ConvertToQtId:
|
| | | case CommandId.ConvertToQmakeId: {
|
| | | command.Visible = false;
|
| | | }
|
| | | break;
|
| | | //case CommandId.ConvertToQmakeId:
|
| | | case CommandId.QtProjectSettingsId: {
|
| | | var status = vsCommandStatus.vsCommandStatusSupported;
|
| | | var project = HelperFunctions.GetSelectedProject(QtVsToolsPackage.Instance.Dte);
|
| | | if (project != null) {
|
| | | if (HelperFunctions.IsQtProject(project))
|
| | | if (HelperFunctions.IsVsToolsProject(project))
|
| | | status |= vsCommandStatus.vsCommandStatusEnabled;
|
| | | else if (HelperFunctions.IsQMakeProject(project))
|
| | | else if (HelperFunctions.IsQtProject(project))
|
| | | status |= vsCommandStatus.vsCommandStatusInvisible;
|
| | | }
|
| | | command.Enabled = ((status & vsCommandStatus.vsCommandStatusEnabled) != 0);
|
| | | command.Visible = ((status & vsCommandStatus.vsCommandStatusInvisible) == 0);
|
| | | }
|
| | | break;
|
| | | //case CommandId.ConvertToQtId:
|
| | | case CommandId.ChangeProjectQtVersionId: {
|
| | | var status = vsCommandStatus.vsCommandStatusSupported;
|
| | | var project = HelperFunctions.GetSelectedProject(QtVsToolsPackage.Instance.Dte);
|
| | | if ((project == null) || HelperFunctions.IsQtProject(project))
|
| | | if ((project == null) || HelperFunctions.IsVsToolsProject(project))
|
| | | status |= vsCommandStatus.vsCommandStatusInvisible;
|
| | | else if (HelperFunctions.IsQMakeProject(project))
|
| | | else if (HelperFunctions.IsQtProject(project))
|
| | | status |= vsCommandStatus.vsCommandStatusEnabled;
|
| | | else
|
| | | status |= vsCommandStatus.vsCommandStatusInvisible;
|
| | |
| | | using System.Linq;
|
| | | using System.Windows.Forms;
|
| | | using Microsoft.VisualStudio;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using QtVsTools.Core;
|
| | | using QtVsTools.VisualStudio;
|
| | |
|
| | | namespace QtVsTools
|
| | | {
|
| | | using Core;
|
| | | using VisualStudio;
|
| | |
|
| | | static class QtMsBuildConverter
|
| | | {
|
| | | public static bool SolutionToQtMsBuild()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var solution = QtVsToolsPackage.Instance.Dte.Solution;
|
| | | if (solution == null)
|
| | | return ErrorMessage(string.Format(SR.GetString("ErrorConvertingProject"), ""));
|
| | |
| | | return WarningMessage(SR.GetString("NoProjectsToConvert"));
|
| | |
|
| | | foreach (EnvDTE.Project project in allProjects) {
|
| | | if ((HelperFunctions.IsQtProject(project)
|
| | | || HelperFunctions.IsQMakeProject(project))
|
| | | if ((HelperFunctions.IsVsToolsProject(project)
|
| | | || HelperFunctions.IsQtProject(project))
|
| | | && !QtProject.IsQtMsBuildEnabled(project)) {
|
| | | projects.Add(project);
|
| | | }
|
| | |
| | | MessageBoxButtons.YesNo) != DialogResult.Yes)
|
| | | return WarningMessage(SR.GetString("CancelConvertingProject"));
|
| | |
|
| | | if (projects.Where(project => project.IsDirty).Any()) {
|
| | | bool hasDirtyProjects = projects
|
| | | .Where(project =>
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return project.IsDirty;
|
| | | })
|
| | | .Any();
|
| | | if (hasDirtyProjects) {
|
| | | if (MessageBox.Show(
|
| | | SR.GetString("ConvertSaveConfirmation"),
|
| | | SR.GetString("ConvertTitle"),
|
| | |
| | | return WarningMessage(SR.GetString("CancelConvertingProject"));
|
| | | }
|
| | |
|
| | | var projectPaths = projects.Select(x => x.FullName).ToList();
|
| | | var projectPaths = projects
|
| | | .Select(x =>
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return x.FullName;
|
| | | })
|
| | | .ToList();
|
| | |
|
| | | string solutionPath = solution.FileName;
|
| | | solution.Close(true);
|
| | |
| | |
|
| | | public static bool ProjectToQtMsBuild(EnvDTE.Project project, bool askConfirmation = true)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (project == null)
|
| | | return ErrorMessage(string.Format(SR.GetString("ErrorConvertingProject"), ""));
|
| | | var pathToProject = project.FullName;
|
| | |
| | | try {
|
| | | if (solution.UnloadProject(
|
| | | ref projectGuid,
|
| | | (uint)_VSProjectUnloadStatus.UNLOADSTATUS_LoadPendingIfNeeded)
|
| | | (uint)_VSProjectUnloadStatus.UNLOADSTATUS_UnloadedByUser)
|
| | | != VSConstants.S_OK)
|
| | | return ErrorMessage(
|
| | | string.Format(SR.GetString("ErrorConvertingProject"), projectName));
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using EnvDTE;
|
| | | using Microsoft.VisualStudio;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using QtVsTools.Core;
|
| | | using QtVsTools.VisualStudio;
|
| | | using System;
|
| | | using System.ComponentModel.Design;
|
| | | using System.Windows.Forms;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using EnvDTE;
|
| | |
|
| | | namespace QtVsTools
|
| | | {
|
| | | using Core;
|
| | | using QtMsBuild;
|
| | | using VisualStudio;
|
| | |
|
| | | /// <summary>
|
| | | /// Command handler
|
| | |
| | | /// <summary>
|
| | | /// Command menu group (command set GUID).
|
| | | /// </summary>
|
| | | public static readonly Guid ProjectContextMenuGuid = new Guid("5732faa9-6074-4e07-b035-2816e809f50e");
|
| | | private static readonly Guid ProjectContextMenuGuid = new Guid("5732faa9-6074-4e07-b035-2816e809f50e");
|
| | |
|
| | | /// <summary>
|
| | | /// Gets the instance of the command.
|
| | | /// </summary>
|
| | | public static QtProjectContextMenu Instance
|
| | | private static QtProjectContextMenu Instance
|
| | | {
|
| | | get;
|
| | | private set;
|
| | | set;
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// Initializes the singleton instance of the command.
|
| | | /// </summary>
|
| | | /// <param name="package">Owner package, not null.</param>
|
| | | public static void Initialize(Package package)
|
| | | public static void Initialize()
|
| | | {
|
| | | Instance = new QtProjectContextMenu(package);
|
| | | Instance = new QtProjectContextMenu();
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | |
| | | ImportPriFileProjectId = 0x0114,
|
| | | ExportPriFileProjectId = 0x0115,
|
| | | ExportProFileProjectId = 0x0116,
|
| | | CreateNewTsFileProjectId = 0x0117,
|
| | | lUpdateOnProjectId = 0x0118,
|
| | | lReleaseOnProjectId = 0x0119,
|
| | | ProjectConvertToQtMsBuild = 0x0130,
|
| | | ProjectRefreshIntelliSense = 0x0131,
|
| | | ConvertToQtProjectId = 0x0120,
|
| | | ConvertToQmakeProjectId = 0x0121,
|
| | | QtProjectSettingsProjectId = 0x0122,
|
| | | ChangeProjectQtVersionProjectId = 0x0123,
|
| | | ProjectAddNewQtClassProjectId = 0x200
|
| | | ChangeProjectQtVersionProjectId = 0x0123
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// VS Package that provides this command, not null.
|
| | | /// </summary>
|
| | | private readonly Package m_package;
|
| | |
|
| | | /// <summary>
|
| | | /// Initializes a new instance of the <see cref="QtMainMenu"/> class.
|
| | | /// Adds our command handlers for menu (commands must exist in the command table file)
|
| | | /// </summary>
|
| | | /// <param name="package">Owner package, not null.</param>
|
| | | private QtProjectContextMenu(Package package)
|
| | | private QtProjectContextMenu()
|
| | | {
|
| | | if (package == null)
|
| | | throw new ArgumentNullException("package");
|
| | |
|
| | | m_package = package;
|
| | |
|
| | | var commandService = VsServiceProvider
|
| | | .GetService<IMenuCommandService, OleMenuCommandService>();
|
| | | if (commandService == null)
|
| | |
| | |
|
| | | private void execHandler(object sender, EventArgs e)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var command = sender as OleMenuCommand;
|
| | | if (command == null)
|
| | | return;
|
| | |
| | | case CommandId.ExportProFileProjectId:
|
| | | ExtLoader.ExportProFile();
|
| | | break;
|
| | | case CommandId.CreateNewTsFileProjectId:
|
| | | Translation.CreateNewTranslationFile(HelperFunctions.GetSelectedQtProject(QtVsToolsPackage
|
| | | .Instance.Dte));
|
| | | break;
|
| | | case CommandId.lUpdateOnProjectId:
|
| | | Translation.RunlUpdate(HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte));
|
| | | break;
|
| | | case CommandId.lReleaseOnProjectId:
|
| | | Translation.RunlRelease(HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte));
|
| | | break;
|
| | | case CommandId.ConvertToQtProjectId:
|
| | | case CommandId.ConvertToQmakeProjectId: {
|
| | | var caption = SR.GetString("ConvertTitle");
|
| | | var text = SR.GetString("ConvertConfirmation");
|
| | | if (MessageBox.Show(text, caption, MessageBoxButtons.YesNo) == DialogResult.Yes) {
|
| | | HelperFunctions.ToggleProjectKind(HelperFunctions.GetSelectedProject(QtVsToolsPackage
|
| | | .Instance.Dte));
|
| | | }
|
| | | }
|
| | | break;
|
| | | case CommandId.QtProjectSettingsProjectId: {
|
| | | var pro = HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte);
|
| | |
| | | if (projectVersion >= Resources.qtMinFormatVersion_Settings) {
|
| | | QtVsToolsPackage.Instance.Dte.ExecuteCommand("Project.Properties");
|
| | | } else if (pro != null) {
|
| | | using (var formProjectQtSettings = new FormProjectQtSettings()) {
|
| | | formProjectQtSettings.SetProject(pro);
|
| | | formProjectQtSettings.StartPosition = FormStartPosition.CenterParent;
|
| | | var ww = new MainWinWrapper(QtVsToolsPackage.Instance.Dte);
|
| | | formProjectQtSettings.ShowDialog(ww);
|
| | | }
|
| | | Legacy.QtMenu.ShowFormProjectQtSettings(pro);
|
| | | } else {
|
| | | MessageBox.Show(SR.GetString("NoProjectOpened"));
|
| | | }
|
| | | }
|
| | | break;
|
| | | case CommandId.ChangeProjectQtVersionProjectId: {
|
| | | var pro = HelperFunctions.GetSelectedQtProject(QtVsToolsPackage.Instance.Dte);
|
| | | if (HelperFunctions.IsQMakeProject(pro)) {
|
| | | using (var formChangeQtVersion = new FormChangeQtVersion()) {
|
| | | formChangeQtVersion.UpdateContent(ChangeFor.Project);
|
| | | var ww = new MainWinWrapper(QtVsToolsPackage.Instance.Dte);
|
| | | if (formChangeQtVersion.ShowDialog(ww) == DialogResult.OK) {
|
| | | var qtVersion = formChangeQtVersion.GetSelectedQtVersion();
|
| | | HelperFunctions.SetDebuggingEnvironment(pro, "PATH=" + QtVersionManager
|
| | | .The().GetInstallPath(qtVersion) + @"\bin;$(PATH)", true);
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | case CommandId.ChangeProjectQtVersionProjectId:
|
| | | Legacy.QtMenu.ShowFormChangeProjectQtVersion();
|
| | | break;
|
| | | case CommandId.ProjectConvertToQtMsBuild: {
|
| | | QtMsBuildConverter.ProjectToQtMsBuild(
|
| | |
| | | break;
|
| | | case CommandId.ProjectRefreshIntelliSense: {
|
| | | var selectedProject = HelperFunctions.GetSelectedProject(QtVsToolsPackage.Instance.Dte);
|
| | | var tracker = QtProjectTracker.Get(selectedProject);
|
| | | var tracker = QtProjectTracker.Get(selectedProject, selectedProject.FullName);
|
| | | QtProjectIntellisense.Refresh(tracker.Project);
|
| | | }
|
| | | break;
|
| | | case CommandId.ProjectAddNewQtClassProjectId: {
|
| | | try {
|
| | | var project = HelperFunctions.GetSelectedProject(QtVsToolsPackage.Instance.Dte);
|
| | | if (!HelperFunctions.IsQtProject(project))
|
| | | return;
|
| | |
|
| | | var vcProject = project.Object as VCProject;
|
| | | if (vcProject == null)
|
| | | return;
|
| | |
|
| | | var loop = true;
|
| | | do {
|
| | | var classWizard = new Wizards.ClassWizard.AddClassWizard();
|
| | | loop = classWizard.Run(QtVsToolsPackage.Instance.Dte, vcProject.Name,
|
| | | vcProject.ProjectDirectory) == Wizards.WizardResult.Exception;
|
| | | } while (loop);
|
| | | } catch {
|
| | | // Deliberately ignore any kind of exception but close the dialog.
|
| | | }
|
| | | }
|
| | | break;
|
| | | }
|
| | |
| | | return;
|
| | |
|
| | | var project = HelperFunctions.GetSelectedProject(QtVsToolsPackage.Instance.Dte);
|
| | | var isQtProject = HelperFunctions.IsQtProject(project);
|
| | | var isQMakeProject = HelperFunctions.IsQMakeProject(project);
|
| | | var isQtProject = HelperFunctions.IsVsToolsProject(project);
|
| | | var isQMakeProject = HelperFunctions.IsQtProject(project);
|
| | | var isQtMsBuildEnabled = QtProject.IsQtMsBuildEnabled(project);
|
| | |
|
| | | if (!isQtProject && !isQMakeProject) {
|
| | |
| | | }
|
| | |
|
| | | switch ((CommandId)command.CommandID.ID) {
|
| | | // TODO: Fix these functionality and re-enable the menu items
|
| | | case CommandId.ConvertToQtProjectId:
|
| | | case CommandId.ConvertToQmakeProjectId: {
|
| | | command.Visible = false;
|
| | | }
|
| | | break;
|
| | | case CommandId.ImportPriFileProjectId:
|
| | | case CommandId.ExportPriFileProjectId:
|
| | | case CommandId.ExportProFileProjectId:
|
| | | case CommandId.CreateNewTsFileProjectId:
|
| | | command.Visible = true;
|
| | | command.Enabled = HelperFunctions.IsVsToolsProject(HelperFunctions
|
| | | .GetSelectedProject(QtVsToolsPackage.Instance.Dte));
|
| | | break;
|
| | | case CommandId.lUpdateOnProjectId:
|
| | | case CommandId.lReleaseOnProjectId:
|
| | | command.Visible = true;
|
| | | command.Enabled = HelperFunctions.IsQtProject(HelperFunctions
|
| | | .GetSelectedProject(QtVsToolsPackage.Instance.Dte));
|
| | | command.Enabled = Translation.ToolsAvailable(project);
|
| | | break;
|
| | | //case CommandId.ConvertToQmakeProjectId:
|
| | | case CommandId.QtProjectSettingsProjectId:
|
| | | case CommandId.ProjectAddNewQtClassProjectId: {
|
| | | case CommandId.QtProjectSettingsProjectId: {
|
| | | var status = vsCommandStatus.vsCommandStatusSupported;
|
| | | if (project != null) {
|
| | | if (isQtProject)
|
| | |
| | | command.Visible = ((status & vsCommandStatus.vsCommandStatusInvisible) == 0);
|
| | | }
|
| | | break;
|
| | | //case CommandId.ConvertToQtProjectId:
|
| | | case CommandId.ChangeProjectQtVersionProjectId: {
|
| | | var status = vsCommandStatus.vsCommandStatusSupported;
|
| | | if ((project == null) || isQtProject)
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using EnvDTE80;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using QtVsTools.Core;
|
| | | using QtVsTools.VisualStudio;
|
| | | using System;
|
| | | using System.ComponentModel.Design;
|
| | | using System.Windows.Forms;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | |
|
| | | namespace QtVsTools
|
| | | {
|
| | | using Core;
|
| | | using QtMsBuild;
|
| | | using VisualStudio;
|
| | |
|
| | | /// <summary>
|
| | | /// Command handler
|
| | |
| | | /// <summary>
|
| | | /// Command menu group (command set GUID).
|
| | | /// </summary>
|
| | | public static readonly Guid SolutionContextMenuGuid = new Guid("6dcda34f-4d22-4d6a-a176-5507069c5a3e");
|
| | | private static readonly Guid SolutionContextMenuGuid = new Guid("6dcda34f-4d22-4d6a-a176-5507069c5a3e");
|
| | |
|
| | | /// <summary>
|
| | | /// Gets the instance of the command.
|
| | | /// </summary>
|
| | | public static QtSolutionContextMenu Instance
|
| | | private static QtSolutionContextMenu Instance
|
| | | {
|
| | | get;
|
| | | private set;
|
| | | set;
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// Initializes the singleton instance of the command.
|
| | | /// </summary>
|
| | | /// <param name="package">Owner package, not null.</param>
|
| | | public static void Initialize(Package package)
|
| | | public static void Initialize()
|
| | | {
|
| | | Instance = new QtSolutionContextMenu(package);
|
| | | Instance = new QtSolutionContextMenu();
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | | /// VS Package that provides this command, not null.
|
| | | /// </summary>
|
| | | private readonly Package m_package;
|
| | |
|
| | | /// <summary>
|
| | | /// Command ID.
|
| | |
| | | /// Initializes a new instance of the <see cref="QtMainMenu"/> class.
|
| | | /// Adds our command handlers for menu (commands must exist in the command table file)
|
| | | /// </summary>
|
| | | /// <param name="package">Owner package, not null.</param>
|
| | | private QtSolutionContextMenu(Package package)
|
| | | private QtSolutionContextMenu()
|
| | | {
|
| | | if (package == null)
|
| | | throw new ArgumentNullException("package");
|
| | |
|
| | | m_package = package;
|
| | |
|
| | | var commandService = VsServiceProvider
|
| | | .GetService<IMenuCommandService, OleMenuCommandService>();
|
| | | if (commandService == null)
|
| | |
| | | var command = sender as OleMenuCommand;
|
| | | if (command == null)
|
| | | return;
|
| | | command.Enabled = command.Visible = true;
|
| | |
|
| | | switch (command.CommandID.ID) {
|
| | | case (int)CommandId.ChangeSolutionQtVersionId:
|
| | | var projects = HelperFunctions.ProjectsInSolution(QtVsToolsPackage.Instance.Dte);
|
| | | foreach (var project in projects) {
|
| | | if (!HelperFunctions.IsVsToolsProject(project)
|
| | | && HelperFunctions.IsQtProject(project)) {
|
| | | command.Enabled = command.Visible = true;
|
| | | return;
|
| | | }
|
| | | }
|
| | | command.Enabled = command.Visible = false;
|
| | | break;
|
| | | default:
|
| | | command.Enabled = command.Visible = true;
|
| | | break;
|
| | | }
|
| | | }
|
| | |
|
| | | private void execHandler(object sender, EventArgs e)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var command = sender as OleMenuCommand;
|
| | | if (command == null)
|
| | | return;
|
| | |
|
| | | var dte = QtVsToolsPackage.Instance.Dte;
|
| | | switch (command.CommandID.ID) {
|
| | | case (int)CommandId.lUpdateOnSolutionId:
|
| | | switch ((CommandId)command.CommandID.ID) {
|
| | | case CommandId.lUpdateOnSolutionId:
|
| | | Translation.RunlUpdate(QtVsToolsPackage.Instance.Dte.Solution);
|
| | | break;
|
| | | case (int)CommandId.lReleaseOnSolutionId:
|
| | | case CommandId.lReleaseOnSolutionId:
|
| | | Translation.RunlRelease(QtVsToolsPackage.Instance.Dte.Solution);
|
| | | break;
|
| | | case (int)CommandId.ChangeSolutionQtVersionId:
|
| | | string newQtVersion = null;
|
| | | using (var formChangeQtVersion = new FormChangeQtVersion()) {
|
| | | formChangeQtVersion.UpdateContent(ChangeFor.Solution);
|
| | | if (formChangeQtVersion.ShowDialog() != DialogResult.OK)
|
| | | return;
|
| | | newQtVersion = formChangeQtVersion.GetSelectedQtVersion();
|
| | | }
|
| | | if (newQtVersion == null)
|
| | | return;
|
| | |
|
| | | string currentPlatform = null;
|
| | | try {
|
| | | var config2 = QtVsToolsPackage.Instance.Dte.Solution.SolutionBuild
|
| | | .ActiveConfiguration as SolutionConfiguration2;
|
| | | currentPlatform = config2.PlatformName;
|
| | | } catch { }
|
| | | if (string.IsNullOrEmpty(currentPlatform))
|
| | | return;
|
| | |
|
| | | foreach (var project in HelperFunctions.ProjectsInSolution(dte)) {
|
| | | if (HelperFunctions.IsQtProject(project)) {
|
| | | var OldQtVersion = QtVersionManager.The().GetProjectQtVersion(project,
|
| | | currentPlatform);
|
| | | if (OldQtVersion == null)
|
| | | OldQtVersion = QtVersionManager.The().GetDefaultVersion();
|
| | |
|
| | | var created = false;
|
| | | var qtProject = QtProject.Create(project);
|
| | | if (qtProject.PromptChangeQtVersion(OldQtVersion, newQtVersion))
|
| | | qtProject.ChangeQtVersion(OldQtVersion, newQtVersion, ref created);
|
| | | }
|
| | | }
|
| | | QtVersionManager.The().SaveSolutionQtVersion(dte.Solution, newQtVersion);
|
| | | case CommandId.ChangeSolutionQtVersionId:
|
| | | Legacy.QtMenu.ShowFormChangeSolutionQtVersion();
|
| | | break;
|
| | | case (int)CommandId.SolutionConvertToQtMsBuild: {
|
| | | QtMsBuildConverter.SolutionToQtMsBuild();
|
| | | }
|
| | | case CommandId.SolutionConvertToQtMsBuild:
|
| | | QtMsBuildConverter.SolutionToQtMsBuild();
|
| | | break;
|
| | | case (int)CommandId.SolutionEnableProjectTracking: {
|
| | | case CommandId.SolutionEnableProjectTracking: {
|
| | | foreach (var project in HelperFunctions.ProjectsInSolution(dte)) {
|
| | | if (HelperFunctions.IsQtProject(project))
|
| | | QtProjectTracker.Get(project);
|
| | | if (HelperFunctions.IsVsToolsProject(project))
|
| | | QtProjectTracker.Get(project, project.FullName);
|
| | | }
|
| | | }
|
| | | break;
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Globalization;
|
| | | using System.Resources;
|
| | |
|
| | | namespace QtVsTools
|
| | |
| | | {
|
| | | static SR loader;
|
| | | readonly ResourceManager resources;
|
| | | static readonly Object obj = new Object();
|
| | | static readonly object obj = new object();
|
| | |
|
| | | internal const string OK = "OK";
|
| | | internal const string Cancel = "Cancel";
|
| | |
|
| | | internal static CultureInfo appCultureInfo;
|
| | | internal static CultureInfo defaultCultureInfo;
|
| | |
|
| | | internal SR(int localeId)
|
| | | internal SR()
|
| | | {
|
| | | defaultCultureInfo = CultureInfo.GetCultureInfo("en");
|
| | | appCultureInfo = CultureInfo.GetCultureInfo(localeId);
|
| | | if (appCultureInfo.Name.StartsWith("en", StringComparison.Ordinal))
|
| | | appCultureInfo = null;
|
| | | resources = new ResourceManager("QtVsTools.Package.Resources", GetType().Assembly);
|
| | | }
|
| | |
|
| | | private static SR GetLoader(int localeId)
|
| | | private static SR GetLoader()
|
| | | {
|
| | | if (loader == null) {
|
| | | lock (obj) {
|
| | | if (loader == null)
|
| | | loader = new SR(localeId);
|
| | | loader = new SR();
|
| | | }
|
| | | }
|
| | | return loader;
|
| | | }
|
| | |
|
| | | private static CultureInfo Culture
|
| | | {
|
| | | get { return appCultureInfo; }
|
| | | }
|
| | |
|
| | | public static string GetString(string name, params object[] args)
|
| | | {
|
| | | var res = GetString(name);
|
| | | if (!string.IsNullOrEmpty(res) && args != null && args.Length > 0)
|
| | | var sys = GetLoader();
|
| | | if (sys == null)
|
| | | return null;
|
| | |
|
| | | var res = sys.resources.GetString(name, null);
|
| | | if (args != null && args.Length > 0 && !string.IsNullOrEmpty(res))
|
| | | return string.Format(res, args);
|
| | | return res;
|
| | | }
|
| | |
|
| | | public static string GetString(string name)
|
| | | {
|
| | | return GetString(name, QtVsToolsPackage.Instance);
|
| | | }
|
| | |
|
| | | public static string GetString(string name, QtVsToolsPackage vsixInstance)
|
| | | {
|
| | | var sys = GetLoader(vsixInstance.Dte.LocaleID);
|
| | | if (sys == null)
|
| | | return null;
|
| | |
|
| | | string result;
|
| | | try {
|
| | | result = sys.resources.GetString(name, Culture);
|
| | | } catch (Exception) {
|
| | | result = sys.resources.GetString(name, defaultCultureInfo);
|
| | | }
|
| | |
|
| | | return result;
|
| | | return GetString(name, null);
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using Microsoft.VisualStudio;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using QtVsTools.Core;
|
| | | using QtVsTools.VisualStudio;
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.Diagnostics;
|
| | | using System.IO;
|
| | | using System.Linq;
|
| | | using System.Text;
|
| | | using System.Threading;
|
| | | using System.Threading.Tasks;
|
| | | using System.Windows.Forms;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | |
|
| | | namespace QtVsTools
|
| | | {
|
| | | using static Core.HelperFunctions;
|
| | | using Core;
|
| | | using QtMsBuild;
|
| | |
|
| | | /// <summary>
|
| | |
| | | /// </summary>
|
| | | public static class Translation
|
| | | {
|
| | | public static void RunlRelease(VCFile vcFile)
|
| | | {
|
| | | var vcProj = vcFile.project as VCProject;
|
| | | var project = vcProj?.Object as EnvDTE.Project;
|
| | | RunTranslationTarget(BuildAction.Release,
|
| | | project, new[] { vcFile.RelativePath });
|
| | | }
|
| | |
|
| | | public static void RunlRelease(VCFile[] vcFiles)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var vcProj = vcFiles.FirstOrDefault()?.project as VCProject;
|
| | | var project = vcProj?.Object as EnvDTE.Project;
|
| | | RunTranslationTarget(BuildAction.Release,
|
| | |
| | |
|
| | | public static void RunlRelease(EnvDTE.Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | RunTranslationTarget(BuildAction.Release, project);
|
| | | }
|
| | |
|
| | | public static void RunlRelease(EnvDTE.Solution solution)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (solution == null)
|
| | | return;
|
| | |
|
| | |
| | |
|
| | | public static void RunlUpdate(VCFile vcFile)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var vcProj = vcFile.project as VCProject;
|
| | | var project = vcProj?.Object as EnvDTE.Project;
|
| | | RunTranslationTarget(BuildAction.Update,
|
| | |
| | |
|
| | | public static void RunlUpdate(VCFile[] vcFiles)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var vcProj = vcFiles.FirstOrDefault()?.project as VCProject;
|
| | | var project = vcProj?.Object as EnvDTE.Project;
|
| | | RunTranslationTarget(BuildAction.Update,
|
| | |
| | |
|
| | | public static void RunlUpdate(EnvDTE.Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | RunTranslationTarget(BuildAction.Update, project);
|
| | | }
|
| | |
|
| | | enum BuildAction { Update, Release }
|
| | | internal enum BuildAction { Update, Release }
|
| | |
|
| | | static void RunTranslationTarget(
|
| | | BuildAction buildAction,
|
| | | EnvDTE.Project project,
|
| | | IEnumerable<string> selectedFiles = null)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | using (WaitDialog.Start(
|
| | | "Qt Visual Studio Tools", "Running translation tool...")) {
|
| | |
|
| | |
| | | if (qtPro.FormatVersion < Resources.qtMinFormatVersion_Settings) {
|
| | | Messages.Print("translation: Legacy project format");
|
| | | try {
|
| | | Legacy_RunTranslation(buildAction, qtPro, selectedFiles);
|
| | | } catch (Exception e) {
|
| | | Messages.Print(
|
| | | e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
|
| | | Legacy.Translation.Run(buildAction, qtPro, selectedFiles);
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | }
|
| | | return;
|
| | | }
|
| | |
| | | if (selectedFiles != null)
|
| | | properties["SelectedFiles"] = string.Join(";", selectedFiles);
|
| | |
|
| | | QtProjectBuild.StartBuild(project, activeConfigId, properties, new[] { target });
|
| | | QtProjectBuild.StartBuild(
|
| | | project, project.FullName, activeConfigId, properties, new[] { target });
|
| | | }
|
| | | }
|
| | |
|
| | | public static void RunlUpdate(EnvDTE.Solution solution)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (solution == null)
|
| | | return;
|
| | |
|
| | |
| | | RunlUpdate(project);
|
| | | }
|
| | |
|
| | | static void Legacy_RunTranslation(
|
| | | BuildAction buildAction,
|
| | | QtProject qtProject,
|
| | | IEnumerable<string> tsFiles)
|
| | | {
|
| | | if (tsFiles == null) {
|
| | | tsFiles = (qtProject.VCProject
|
| | | .GetFilesEndingWith(".ts") as IVCCollection)
|
| | | .Cast<VCFile>()
|
| | | .Select(vcFile => vcFile.RelativePath);
|
| | | if (tsFiles == null) {
|
| | | Messages.Print("translation: no translation files found");
|
| | | return;
|
| | | }
|
| | | }
|
| | | string tempFile = null;
|
| | | foreach (var file in tsFiles.Where(file => file != null))
|
| | | Legacy_RunTranslation(buildAction, qtProject, file, ref tempFile);
|
| | | }
|
| | |
|
| | | static void Legacy_RunTranslation(
|
| | | BuildAction buildAction,
|
| | | QtProject qtProject,
|
| | | string tsFile,
|
| | | ref string tempFile)
|
| | | {
|
| | | var qtVersion = qtProject.GetQtVersion();
|
| | | var qtInstallPath = QtVersionManager.The().GetInstallPath(qtVersion);
|
| | | if (string.IsNullOrEmpty(qtInstallPath)) {
|
| | | Messages.Print("translation: Error accessing Qt installation");
|
| | | return;
|
| | | }
|
| | |
|
| | | var procInfo = new ProcessStartInfo
|
| | | {
|
| | | WorkingDirectory = qtProject.ProjectDir,
|
| | | CreateNoWindow = true,
|
| | | UseShellExecute = false,
|
| | | RedirectStandardError = true,
|
| | | RedirectStandardOutput = true,
|
| | | Arguments = ""
|
| | | };
|
| | | switch (buildAction) {
|
| | | case BuildAction.Update:
|
| | | Messages.Print("\r\n--- (lupdate) file: " + tsFile);
|
| | | procInfo.FileName = Path.Combine(qtInstallPath, "bin", "lupdate.exe");
|
| | | var options = QtVSIPSettings.GetLUpdateOptions();
|
| | | if (!string.IsNullOrEmpty(options))
|
| | | procInfo.Arguments += options + " ";
|
| | | if (tempFile == null) {
|
| | | var inputFiles = GetProjectFiles(qtProject.Project, FilesToList.FL_HFiles)
|
| | | .Union(GetProjectFiles(qtProject.Project, FilesToList.FL_CppFiles))
|
| | | .Union(GetProjectFiles(qtProject.Project, FilesToList.FL_UiFiles))
|
| | | .Union(GetProjectFiles(qtProject.Project, FilesToList.FL_QmlFiles));
|
| | | tempFile = Path.GetTempFileName();
|
| | | File.WriteAllLines(tempFile, inputFiles);
|
| | | }
|
| | | procInfo.Arguments += string.Format("\"@{0}\" -ts \"{1}\"", tempFile, tsFile);
|
| | | break;
|
| | | case BuildAction.Release:
|
| | | Messages.Print("\r\n--- (lrelease) file: " + tsFile);
|
| | | procInfo.FileName = Path.Combine(qtInstallPath, "bin", "lrelease.exe");
|
| | | options = QtVSIPSettings.GetLReleaseOptions();
|
| | | if (!string.IsNullOrEmpty(options))
|
| | | procInfo.Arguments += options + " ";
|
| | | procInfo.Arguments += string.Format("\"{0}\"", tsFile);
|
| | | break;
|
| | | }
|
| | | using (var proc = Process.Start(procInfo)) {
|
| | | proc.OutputDataReceived += (object sender, DataReceivedEventArgs e) =>
|
| | | {
|
| | | if (!string.IsNullOrEmpty(e.Data))
|
| | | Messages.Print(e.Data);
|
| | | };
|
| | | proc.ErrorDataReceived += (object sender, DataReceivedEventArgs e) =>
|
| | | {
|
| | | if (!string.IsNullOrEmpty(e.Data))
|
| | | Messages.Print(e.Data);
|
| | | };
|
| | | proc.BeginOutputReadLine();
|
| | | proc.BeginErrorReadLine();
|
| | | proc.WaitForExit();
|
| | | switch (proc.ExitCode) {
|
| | | case 0:
|
| | | Messages.Print("translation: ok");
|
| | | break;
|
| | | default:
|
| | | Messages.Print(string.Format("translation: ERROR {0}", proc.ExitCode));
|
| | | break;
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | public static void CreateNewTranslationFile(EnvDTE.Project project)
|
| | | public static bool ToolsAvailable(EnvDTE.Project project)
|
| | | {
|
| | | if (project == null)
|
| | | return;
|
| | | return false;
|
| | | if (QtProject.GetPropertyValue(project, "ApplicationType") == "Linux")
|
| | | return true;
|
| | |
|
| | | using (var transDlg = new AddTranslationDialog(project)) {
|
| | | if (transDlg.ShowDialog() == DialogResult.OK) {
|
| | | try {
|
| | | var qtPro = QtProject.Create(project);
|
| | | var file = qtPro.AddFileInFilter(Filters.TranslationFiles(),
|
| | | transDlg.TranslationFile, true);
|
| | | RunlUpdate(file);
|
| | | } catch (QtVSException e) {
|
| | | Messages.DisplayErrorMessage(e.Message);
|
| | | } catch (System.Exception ex) {
|
| | | Messages.DisplayErrorMessage(ex.Message);
|
| | | }
|
| | | }
|
| | | var qtToolsPath = QtProject.GetPropertyValue(project, "QtToolsPath");
|
| | | if (string.IsNullOrEmpty(qtToolsPath)) {
|
| | | var qtVersion = QtVersionManager.The().GetProjectQtVersion(project);
|
| | | var qtInstallPath = QtVersionManager.The().GetInstallPath(qtVersion);
|
| | | if (string.IsNullOrEmpty(qtInstallPath))
|
| | | return false;
|
| | | qtToolsPath = Path.Combine(qtInstallPath, "bin");
|
| | | }
|
| | | return File.Exists(Path.Combine(qtToolsPath, "lupdate.exe"))
|
| | | && File.Exists(Path.Combine(qtToolsPath, "lrelease.exe"));
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.Linq;
|
| | | using System.Threading;
|
| | | using System.Threading.Tasks;
|
| | | using System.Windows.Threading;
|
| | | using Microsoft.VisualStudio.Text;
|
| | |
| | | /// </summary>
|
| | | class SharedTagList : Concurrent
|
| | | {
|
| | | SortedList<int, TrackingTag> data = new SortedList<int, TrackingTag>();
|
| | | readonly SortedList<int, TrackingTag> data = new SortedList<int, TrackingTag>();
|
| | | object owner;
|
| | |
|
| | | public bool Ready { get; private set; }
|
| | |
| | |
|
| | | class TrackingTagComparer : Comparer<TrackingTag>
|
| | | {
|
| | | ITextSnapshot snapshot;
|
| | | readonly ITextSnapshot snapshot;
|
| | | public TrackingTagComparer(ITextSnapshot snapshot)
|
| | | {
|
| | | this.snapshot = snapshot;
|
| | |
| | | /// <returns>Instance of T corresponding to the given TrackingTag</returns>
|
| | | protected abstract T GetClassification(TrackingTag tag);
|
| | |
|
| | | protected ITextView TextView { get; private set; }
|
| | | protected ITextBuffer Buffer { get; private set; }
|
| | | private ITextView TextView { get; }
|
| | | private ITextBuffer Buffer { get; }
|
| | |
|
| | | readonly object criticalSection = new object();
|
| | |
|
| | | string classificationType;
|
| | | readonly string classificationType;
|
| | | ParserKey currentParserKey;
|
| | | TagListKey currentTagListKey;
|
| | | SharedTagList currentTagList;
|
| | | Dispatcher dispatcher;
|
| | | DispatcherTimer timer;
|
| | | readonly Dispatcher dispatcher;
|
| | | readonly DispatcherTimer timer;
|
| | | bool flag = false;
|
| | |
|
| | | protected QmlAsyncClassifier(
|
| | |
| | | currentTagList = null;
|
| | | this.classificationType = classificationType;
|
| | |
|
| | | AsyncParse(buffer.CurrentSnapshot);
|
| | | Parse(buffer.CurrentSnapshot);
|
| | | }
|
| | |
|
| | | private void TextView_Closed(object sender, EventArgs e)
|
| | |
| | | private void Buffer_Changed(object sender, TextContentChangedEventArgs e)
|
| | | {
|
| | | timer.Stop();
|
| | | AsyncParse(e.After);
|
| | | Parse(e.After);
|
| | | }
|
| | |
|
| | | private void Timer_Tick(object sender, EventArgs e)
|
| | | {
|
| | | timer.Stop();
|
| | | AsyncParse(Buffer.CurrentSnapshot);
|
| | | Parse(Buffer.CurrentSnapshot);
|
| | | }
|
| | |
|
| | | private async void AsyncParse(ITextSnapshot snapshot)
|
| | | private void Parse(ITextSnapshot snapshot)
|
| | | {
|
| | | lock (criticalSection) {
|
| | | if (flag)
|
| | |
| | | ParserKey oldParserKey = null;
|
| | | TagListKey oldTagListKey = null;
|
| | |
|
| | | await Task.Run(() =>
|
| | | _ = Task.Run(() =>
|
| | | {
|
| | | var parser = ParserStore.Instance.Get(this, newParserKey);
|
| | |
|
| | |
| | | flag = false;
|
| | | }
|
| | |
|
| | | await Task.Run(() =>
|
| | | _ = Task.Run(() =>
|
| | | {
|
| | | if (oldParserKey != null)
|
| | | ParserStore.Instance.Release(this, oldParserKey);
|
| | |
| | | public TValue Value { get; set; }
|
| | | public HashSet<object> ClientObjects { get; set; }
|
| | | }
|
| | | Dictionary<TKey, ValueRef> data = new Dictionary<TKey, ValueRef>();
|
| | | readonly Dictionary<TKey, ValueRef> data = new Dictionary<TKey, ValueRef>();
|
| | |
|
| | | static readonly object staticCriticalSection = new object();
|
| | | readonly object criticalSection = new object();
|
| | |
| | | public TValue Get(object client, TKey key)
|
| | | {
|
| | | lock (criticalSection) {
|
| | | ValueRef valueRef;
|
| | | if (!data.TryGetValue(key, out valueRef)) {
|
| | | if (!data.TryGetValue(key, out ValueRef valueRef)) {
|
| | | valueRef = new ValueRef
|
| | | {
|
| | | Value = GetDefaultValue(key),
|
| | |
| | | {
|
| | | IDisposable disposable = null;
|
| | | lock (criticalSection) {
|
| | | ValueRef valueRef;
|
| | | if (data.TryGetValue(key, out valueRef)) {
|
| | | if (data.TryGetValue(key, out ValueRef valueRef)) {
|
| | | valueRef.ClientObjects.Remove(client);
|
| | | if (valueRef.ClientObjects.Count == 0) {
|
| | | data.Remove(key);
|
| | |
| | |
|
| | | class TagListKey
|
| | | {
|
| | | public string Classification { get; private set; }
|
| | | public ITextSnapshot Snapshot { get; private set; }
|
| | | private string Classification { get; }
|
| | | private ITextSnapshot Snapshot { get; }
|
| | | public TagListKey(string classification, ITextSnapshot snapshot)
|
| | | {
|
| | | Classification = classification;
|
| | |
| | |
|
| | | class ParserKey
|
| | | {
|
| | | public ITextSnapshot Snapshot { get; private set; }
|
| | | public ITextSnapshot Snapshot { get; }
|
| | | public ParserKey(ITextSnapshot snapshot)
|
| | | {
|
| | | Snapshot = snapshot;
|
| | |
| | |
|
| | | /// Highlighting of syntax errors
|
| | |
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.ComponentModel.Composition;
|
| | | using System.Threading.Tasks;
|
| | | using System.Windows.Threading;
|
| | | using Microsoft.VisualStudio.Text;
|
| | | using Microsoft.VisualStudio.Text.Classification;
|
| | | using Microsoft.VisualStudio.Text.Editor;
|
| | |
| | | using Microsoft.VisualStudio.Text.Tagging;
|
| | | using Microsoft.VisualStudio.TextManager.Interop;
|
| | | using Microsoft.VisualStudio.Utilities;
|
| | | using QtVsTools.Qml.Syntax;
|
| | | using QtVsTools.VisualStudio;
|
| | |
|
| | | namespace QtVsTools.Qml.Classification
|
| | | {
|
| | | using QtVsTools.VisualStudio;
|
| | | using Syntax;
|
| | |
|
| | | [Export(typeof(IViewTaggerProvider))]
|
| | | [ContentType("qml")]
|
| | | [TagType(typeof(ClassificationTag))]
|
| | |
| | |
|
| | | int IVsTextViewFilter.GetDataTipText(TextSpan[] pSpan, out string pbstrText)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | pbstrText = "";
|
| | | var dbgMode = new DBGMODE[1];
|
| | | if (debugger.GetMode(dbgMode) != VSConstants.S_OK
|
| | |
| | | OLECMD[] prgCmds,
|
| | | IntPtr pCmdText)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return nextTarget.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
|
| | | }
|
| | |
|
| | |
| | | IntPtr pvaIn,
|
| | | IntPtr pvaOut)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | return nextTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
|
| | | }
|
| | |
|
| | | class ExprTrackingTag : TrackingTag
|
| | | {
|
| | | public IOrderedEnumerable<AstNode> Exprs { get; private set; }
|
| | | public IOrderedEnumerable<AstNode> Exprs { get; }
|
| | |
|
| | | public ExprTrackingTag(
|
| | | ITextSnapshot snapshot,
|
| | |
| | |
|
| | | class ExprTag : ClassificationTag
|
| | | {
|
| | | public IOrderedEnumerable<AstNode> Exprs { get; private set; }
|
| | | public IOrderedEnumerable<AstNode> Exprs { get; }
|
| | |
|
| | | public ExprTag(IOrderedEnumerable<AstNode> exprs, IClassificationType type)
|
| | | : base(type)
|
| | |
| | | /// This file implements the actual highlighting of the text according to the
|
| | | /// classification of the syntax elements recognized by the QML parser.
|
| | |
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.ComponentModel.Composition;
|
| | | using System.Threading.Tasks;
|
| | | using System.Windows.Threading;
|
| | | using Microsoft.VisualStudio.Text;
|
| | | using Microsoft.VisualStudio.Text.Classification;
|
| | | using Microsoft.VisualStudio.Text.Editor;
|
| | |
| | | /// </summary>
|
| | | public class TrackingTag : ITag
|
| | | {
|
| | | public ITextSnapshot Snapshot { get; private set; }
|
| | | public int Start { get; private set; }
|
| | | public int Length { get; private set; }
|
| | | public ITrackingSpan Span { get; private set; }
|
| | | public ITextSnapshot Snapshot { get; }
|
| | | public int Start { get; }
|
| | | private int Length { get; }
|
| | | public ITrackingSpan Span { get; }
|
| | | public TrackingTag(ITextSnapshot snapshot, int start, int length)
|
| | | {
|
| | | Snapshot = snapshot;
|
| | |
| | | public const string TypeName = "typename.qml";
|
| | | public const string Binding = "binding.qml";
|
| | |
|
| | | public SyntaxElement SyntaxElement { get; private set; }
|
| | | public SourceLocation SourceLocation { get; private set; }
|
| | | public IClassificationType ClassificationType { get; private set; }
|
| | | private SyntaxElement SyntaxElement { get; }
|
| | | private SourceLocation SourceLocation { get; }
|
| | | public IClassificationType ClassificationType { get; }
|
| | |
|
| | | private QmlSyntaxTag(ITextSnapshot snapshot, SourceLocation location)
|
| | | : base(snapshot, location.Offset, location.Length)
|
| | |
| | | return new QmlSyntaxTag(snapshot, parentNode, classificationType, fullNameLocation);
|
| | | }
|
| | |
|
| | | public static readonly HashSet<string> QmlBasicTypes = new HashSet<string> {
|
| | | private static readonly HashSet<string> QmlBasicTypes = new HashSet<string> {
|
| | | "bool", "double", "enumeration", "int",
|
| | | "list", "real", "string", "url", "var",
|
| | | "date", "point", "rect", "size", "alias"
|
| | |
| | |
|
| | | public class QmlDiagnosticsTag : TrackingTag
|
| | | {
|
| | | public DiagnosticMessage DiagnosticMessage { get; private set; }
|
| | | private DiagnosticMessage DiagnosticMessage { get; }
|
| | | public QmlDiagnosticsTag(ITextSnapshot snapshot, DiagnosticMessage diagnosticMessage)
|
| | | : base(snapshot, diagnosticMessage.Location.Offset, diagnosticMessage.Location.Length)
|
| | | {
|
| | |
| | | static readonly string[] ValidExtensions = new string[] { ".qml", ".js" };
|
| | |
|
| | | public QmlEngine Engine { get; private set; }
|
| | | public IDebugBreakpointRequest2 Request { get; private set; }
|
| | | public enum_BP_LOCATION_TYPE LocationType { get; private set; }
|
| | | public BP_REQUEST_INFO RequestInfo { get; private set; }
|
| | | private IDebugBreakpointRequest2 Request { get; set; }
|
| | | private enum_BP_LOCATION_TYPE LocationType { get; set; }
|
| | | private BP_REQUEST_INFO RequestInfo { get; set; }
|
| | | public string FileName { get; private set; }
|
| | | public TEXT_POSITION BeginPosition { get; private set; }
|
| | | public TEXT_POSITION EndPosition { get; private set; }
|
| | | private TEXT_POSITION EndPosition { get; set; }
|
| | | public bool Enabled { get; private set; }
|
| | |
|
| | | HashSet<Breakpoint> breakpoints;
|
| | |
| | | if (docPosition == null)
|
| | | return false;
|
| | |
|
| | | string fileName;
|
| | | if (docPosition.GetFileName(out fileName) != VSConstants.S_OK)
|
| | | if (docPosition.GetFileName(out string fileName) != VSConstants.S_OK)
|
| | | return false;
|
| | |
|
| | | if (!ValidExtensions.Where(x => string.Equals(x, Path.GetExtension(fileName))).Any())
|
| | |
| | | IDebugBreakpointResolution2 // "This interface represents the information that describes a
|
| | | // bound breakpoint."
|
| | | {
|
| | | public QmlDebugger Debugger { get; private set; }
|
| | | public QmlEngine Engine { get; private set; }
|
| | | private QmlDebugger Debugger { get; set; }
|
| | | private QmlEngine Engine { get; set; }
|
| | | public Program Program { get; private set; }
|
| | | public PendingBreakpoint Parent { get; private set; }
|
| | | public CodeContext CodeContext { get; private set; }
|
| | | public bool Enabled { get; set; }
|
| | | private CodeContext CodeContext { get; set; }
|
| | | private bool Enabled { get; set; }
|
| | |
|
| | | bool supressNotify;
|
| | |
|
| | |
| | | FileSystem = FileSystem.Create();
|
| | | }
|
| | |
|
| | | Dictionary<Guid, Program> programs = new Dictionary<Guid, Program>();
|
| | | readonly Dictionary<Guid, Program> programs = new Dictionary<Guid, Program>();
|
| | | public IEnumerable<Program> Programs
|
| | | {
|
| | | get { return ThreadSafe(() => programs.Values.ToList()); }
|
| | | }
|
| | |
|
| | | HashSet<PendingBreakpoint> pendingBreakpoints = new HashSet<PendingBreakpoint>();
|
| | | readonly HashSet<PendingBreakpoint> pendingBreakpoints = new HashSet<PendingBreakpoint>();
|
| | | public IEnumerable<PendingBreakpoint> PendingBreakpoints
|
| | | {
|
| | | get { return ThreadSafe(() => pendingBreakpoints.ToList()); }
|
| | |
| | | if (string.IsNullOrEmpty(pszOptions))
|
| | | return VSConstants.E_FAIL;
|
| | |
|
| | | uint procId;
|
| | | if (!uint.TryParse(pszOptions, out procId))
|
| | | if (!uint.TryParse(pszOptions, out uint procId))
|
| | | return VSConstants.E_FAIL;
|
| | |
|
| | | var env = bstrEnv.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
| | |
| | | FileSystem.RegisterRccFile(rccFile);
|
| | | }
|
| | |
|
| | | IDebugProcess2 nativeProc;
|
| | | var nativeProcId = new AD_PROCESS_ID
|
| | | {
|
| | | ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM,
|
| | | dwProcessId = procId
|
| | | };
|
| | | if (pPort.GetProcess(nativeProcId, out nativeProc) != VSConstants.S_OK)
|
| | | if (pPort.GetProcess(nativeProcId, out IDebugProcess2 nativeProc) != VSConstants.S_OK)
|
| | | return VSConstants.E_FAIL;
|
| | |
|
| | | var program = Program.Create(this, nativeProc, pszExe, pszArgs);
|
| | |
| | | if (program == null)
|
| | | return VSConstants.E_FAIL;
|
| | |
|
| | | IDebugPort2 port;
|
| | | if (process.GetPort(out port) != VSConstants.S_OK)
|
| | | if (process.GetPort(out IDebugPort2 port) != VSConstants.S_OK)
|
| | | return VSConstants.E_FAIL;
|
| | |
|
| | | string portName;
|
| | | port.GetPortName(out portName);
|
| | |
|
| | | Guid guidPort;
|
| | | port.GetPortId(out guidPort);
|
| | |
|
| | | IDebugDefaultPort2 defaultPort = (IDebugDefaultPort2)port;
|
| | |
|
| | | IDebugPortNotify2 portNotify;
|
| | | if (defaultPort.GetPortNotify(out portNotify) != VSConstants.S_OK)
|
| | | if (defaultPort.GetPortNotify(out IDebugPortNotify2 portNotify) != VSConstants.S_OK)
|
| | | return VSConstants.E_FAIL;
|
| | |
|
| | | if (portNotify.AddProgramNode(program) != VSConstants.S_OK)
|
| | |
| | |
|
| | | DebugEvent.Send(new EngineCreateEvent(this));
|
| | |
|
| | | Guid pguidProgramId;
|
| | | if (rgpPrograms[0].GetProgramId(out pguidProgramId) != VSConstants.S_OK)
|
| | | if (rgpPrograms[0].GetProgramId(out Guid pguidProgramId) != VSConstants.S_OK)
|
| | | return VSConstants.E_FAIL;
|
| | |
|
| | | program.ProgramId = pguidProgramId;
|
| | |
| | |
|
| | | int IDebugEngineLaunch2.CanTerminateProcess(IDebugProcess2 pProcess)
|
| | | {
|
| | | Guid procId;
|
| | | if (pProcess.GetProcessId(out procId) != VSConstants.S_OK)
|
| | | if (pProcess.GetProcessId(out Guid procId) != VSConstants.S_OK)
|
| | | return VSConstants.E_FAIL;
|
| | |
|
| | | Program program;
|
| | | if (!programs.TryGetValue(procId, out program))
|
| | | return VSConstants.S_FALSE;
|
| | |
|
| | | return VSConstants.S_OK;
|
| | | return programs.TryGetValue(procId, out _) ? VSConstants.S_OK : VSConstants.S_FALSE;
|
| | | }
|
| | |
|
| | | public bool ProgramIsRunning(Program program)
|
| | |
| | |
|
| | | int IDebugEngineLaunch2.TerminateProcess(IDebugProcess2 pProcess)
|
| | | {
|
| | | Guid procId;
|
| | | if (pProcess.GetProcessId(out procId) != VSConstants.S_OK)
|
| | | if (pProcess.GetProcessId(out Guid procId) != VSConstants.S_OK)
|
| | | return VSConstants.E_FAIL;
|
| | |
|
| | | Program program;
|
| | | if (!programs.TryGetValue(procId, out program))
|
| | | if (!programs.TryGetValue(procId, out Program program))
|
| | | return VSConstants.S_FALSE;
|
| | |
|
| | | programs.Remove(procId);
|
| | |
| | |
|
| | | int IDebugEngine2.ContinueFromSynchronousEvent(IDebugEvent2 pEvent)
|
| | | {
|
| | | var evtProgramDestroy = pEvent as ProgramDestroyEvent;
|
| | | if (evtProgramDestroy != null)
|
| | | if (pEvent is ProgramDestroyEvent evtProgramDestroy)
|
| | | evtProgramDestroy.Program.Dispose();
|
| | |
|
| | | return VSConstants.S_OK;
|
| | |
| | |
|
| | | #region //////////////////// Concurrent ///////////////////////////////////////////////////
|
| | |
|
| | | LocalConcurrent concurrent = new LocalConcurrent();
|
| | | readonly LocalConcurrent concurrent = new LocalConcurrent();
|
| | | class LocalConcurrent : Concurrent
|
| | | {
|
| | | public void LocalThreadSafe(Action action)
|
| | |
| | | // such as stopping at a breakpoint, and non-critical information, such as a
|
| | | // debugging message."
|
| | | {
|
| | | public Guid InterfaceId { get; protected set; }
|
| | | public uint Attributes { get; protected set; }
|
| | | private Guid InterfaceId { get; }
|
| | | private uint Attributes { get; }
|
| | |
|
| | | protected const uint ASYNCHRONOUS = (uint)enum_EVENTATTRIBUTES.EVENT_ASYNCHRONOUS;
|
| | | protected const uint STOPPING = (uint)enum_EVENTATTRIBUTES.EVENT_ASYNC_STOP;
|
| | |
| | | (uint)enum_EVENTATTRIBUTES.EVENT_STOPPING
|
| | | | (uint)enum_EVENTATTRIBUTES.EVENT_SYNCHRONOUS;
|
| | |
|
| | | protected QmlEngine Engine { get; set; }
|
| | | protected IDebugProgram2 Program { get; set; }
|
| | | protected IDebugThread2 Thread { get; set; }
|
| | | protected IDebugEventCallback2 Callback { get; set; }
|
| | | protected QmlEngine Engine { get; }
|
| | | private IDebugProgram2 Program { get; }
|
| | | private IDebugThread2 Thread { get; }
|
| | | private IDebugEventCallback2 Callback { get; }
|
| | |
|
| | | protected DebugEvent(
|
| | | QmlEngine engine,
|
| | |
| | |
|
| | | class ProgramDestroyEvent : DebugEvent, IDebugProgramDestroyEvent2
|
| | | {
|
| | | uint exitCode;
|
| | | public new Program Program { get; private set; }
|
| | | readonly uint exitCode;
|
| | | public Program Program { get; }
|
| | |
|
| | | public ProgramDestroyEvent(Program program, uint exitCode)
|
| | | : base(program.Engine, typeof(IDebugProgramDestroyEvent2).GUID,
|
| | |
| | |
|
| | | class ThreadDestroyEvent : DebugEvent, IDebugThreadDestroyEvent2
|
| | | {
|
| | | uint exitCode;
|
| | | readonly uint exitCode;
|
| | |
|
| | | public ThreadDestroyEvent(Program program, uint exitCode)
|
| | | : base(program.Engine, typeof(IDebugThreadDestroyEvent2).GUID,
|
| | |
| | |
|
| | | class BreakpointBoundEvent : DebugEvent, IDebugBreakpointBoundEvent2
|
| | | {
|
| | | public Breakpoint Breakpoint { get; private set; }
|
| | | private Breakpoint Breakpoint { get; }
|
| | | public BreakpointBoundEvent(Breakpoint breakpoint)
|
| | | : base(breakpoint.Program.Engine, typeof(IDebugBreakpointBoundEvent2).GUID,
|
| | | ASYNCHRONOUS, breakpoint.Program, breakpoint.Program)
|
| | |
| | |
|
| | | class BreakpointEvent : DebugEvent, IDebugBreakpointEvent2
|
| | | {
|
| | | IEnumDebugBoundBreakpoints2 boundBreakpoints;
|
| | | readonly IEnumDebugBoundBreakpoints2 boundBreakpoints;
|
| | |
|
| | | public BreakpointEvent(Program program,
|
| | | IEnumDebugBoundBreakpoints2 boundBreakpoints)
|
| | |
| | |
|
| | | class ExpressionEvaluationCompleteEvent : DebugEvent, IDebugExpressionEvaluationCompleteEvent2
|
| | | {
|
| | | public Expression Expression { get; private set; }
|
| | | public Property Property { get; private set; }
|
| | | private Expression Expression { get; }
|
| | | private Property Property { get; }
|
| | |
|
| | | public ExpressionEvaluationCompleteEvent(
|
| | | IDebugEventCallback2 callback,
|
| | |
| | |
|
| | | class OutputStringEvent : DebugEvent, IDebugOutputStringEvent2
|
| | | {
|
| | | string outputString;
|
| | | readonly string outputString;
|
| | |
|
| | | public OutputStringEvent(QmlEngine engine, string outputString)
|
| | | : base(engine, typeof(IDebugOutputStringEvent2).GUID, ASYNCHRONOUS)
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Threading.Tasks;
|
| | | using Microsoft.VisualStudio;
|
| | | using Microsoft.VisualStudio.Debugger.Interop;
|
| | |
| | | IDebugExpression2 // "This interface represents a parsed expression ready for binding
|
| | | // and evaluating."
|
| | | {
|
| | | public string ExpressionString { get; private set; }
|
| | | private string ExpressionString { get; set; }
|
| | |
|
| | | public StackFrame StackFrame { get; private set; }
|
| | | private StackFrame StackFrame { get; set; }
|
| | | public QmlEngine Engine { get; private set; }
|
| | | public Program Program { get; private set; }
|
| | | public QmlDebugger Debugger { get; private set; }
|
| | | public CodeContext CodeContext { get; private set; }
|
| | | private QmlDebugger Debugger { get; set; }
|
| | | private CodeContext CodeContext { get; set; }
|
| | |
|
| | | public static Expression Create(StackFrame frame, string expr)
|
| | | {
|
| | |
| | | enum_EVALFLAGS dwFlags,
|
| | | IDebugEventCallback2 pExprCallback)
|
| | | {
|
| | | Task.Run(() =>
|
| | | _ = Task.Run(() =>
|
| | | {
|
| | | var value = Debugger.Evaluate(StackFrame.FrameNumber, ExpressionString);
|
| | | if (value != null)
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using Microsoft.VisualStudio.Debugger.Interop;
|
| | | using System;
|
| | | using System.Collections;
|
| | | using System.Collections.Generic;
|
| | | using System.Linq;
|
| | | using System.Reflection;
|
| | |
|
| | | namespace QtVsTools.Qml.Debug.AD7
|
| | | {
|
| | |
| | | public class Mapping<TStruct, TFieldMask> : Mapping,
|
| | | IEnumerable<MapField<TStruct, TFieldMask>>
|
| | | {
|
| | | List<MapField<TStruct, TFieldMask>> fieldMaps;
|
| | | readonly List<MapField<TStruct, TFieldMask>> fieldMaps;
|
| | |
|
| | | protected static Action<Ref<TStruct>, TFieldMask> UpdateMask { get; set; }
|
| | | private static Action<Ref<TStruct>, TFieldMask> UpdateMask { get; set; }
|
| | |
|
| | | public Mapping(Action<Ref<TStruct>, TFieldMask> updateMask)
|
| | | {
|
| | |
| | | TFieldMask fieldMask,
|
| | | out TStruct infoStruct)
|
| | | {
|
| | | var mappingToStruct = mapping as Mapping<TStruct, TFieldMask>;
|
| | | if (mappingToStruct != null)
|
| | | if (mapping is Mapping<TStruct, TFieldMask> mappingToStruct)
|
| | | mappingToStruct.Map(this as TDerived, fieldMask, out infoStruct);
|
| | | else
|
| | | infoStruct = default(TStruct);
|
| | |
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.IO;
|
| | | using System.Linq;
|
| | | using System.Text;
|
| | | using System.Threading;
|
| | | using System.Windows.Threading;
|
| | | using Microsoft.VisualStudio;
|
| | | using Microsoft.VisualStudio.Debugger.Interop;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | | using QtVsTools.VisualStudio;
|
| | |
|
| | | namespace QtVsTools.Qml.Debug.AD7
|
| | | {
|
| | | using VisualStudio;
|
| | |
|
| | | sealed partial class Program : Disposable, IDebuggerEventSink,
|
| | |
|
| | | IDebugProgramNode2, // "This interface represents a program that can be debugged."
|
| | |
| | |
|
| | | public QmlEngine Engine { get; private set; }
|
| | |
|
| | | public List<StackFrame> CurrentFrames { get; private set; }
|
| | | private List<StackFrame> CurrentFrames { get; set; }
|
| | |
|
| | | public const string Name = "QML Debugger";
|
| | | public Guid ProcessId { get; private set; }
|
| | | private const string Name = "QML Debugger";
|
| | | public Guid ProcessId { get; set; }
|
| | | public Guid ProgramId { get; set; }
|
| | | public IDebugProcess2 NativeProc { get; private set; }
|
| | | public uint NativeProcId { get; private set; }
|
| | | public string ExecPath { get; private set; }
|
| | | public string ExecArgs { get; private set; }
|
| | | public IVsDebugger VsDebugger { get; private set; }
|
| | | Dispatcher vsDebuggerThreadDispatcher;
|
| | | private IDebugProcess2 NativeProc { get; set; }
|
| | | private uint NativeProcId { get; set; }
|
| | | private string ExecPath { get; set; }
|
| | | private string ExecArgs { get; set; }
|
| | | private IVsDebugger VsDebugger { get; set; }
|
| | | private Dispatcher vsDebuggerThreadDispatcher;
|
| | |
|
| | | private readonly static object criticalSectionGlobal = new object();
|
| | | static bool originalBreakAllProcesses = BreakAllProcesses;
|
| | | static int runningPrograms = 0;
|
| | | private static readonly object criticalSectionGlobal = new object();
|
| | | private static bool originalBreakAllProcesses = BreakAllProcesses;
|
| | | private static int runningPrograms = 0;
|
| | |
|
| | | public static Program Create(
|
| | | QmlEngine engine,
|
| | |
| | | return false;
|
| | |
|
| | | VsDebugger = VsServiceProvider.GetService<IVsDebugger>();
|
| | | if (VsDebugger != null)
|
| | | VsDebugger.AdviseDebugEventCallback(this as IDebugEventCallback2);
|
| | | if (VsDebugger != null) {
|
| | | ThreadHelper.JoinableTaskFactory.Run(async () =>
|
| | | {
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | VsDebugger.AdviseDebugEventCallback(this);
|
| | | });
|
| | | }
|
| | | vsDebuggerThreadDispatcher = Dispatcher.CurrentDispatcher;
|
| | |
|
| | | ProcessId = Guid.NewGuid();
|
| | |
| | | protected override void DisposeManaged()
|
| | | {
|
| | | Debugger.Dispose();
|
| | | if (VsDebugger != null)
|
| | | VsDebugger.UnadviseDebugEventCallback(this as IDebugEventCallback2);
|
| | | if (VsDebugger != null) {
|
| | | ThreadHelper.JoinableTaskFactory.Run(async () =>
|
| | | {
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | VsDebugger.UnadviseDebugEventCallback(this as IDebugEventCallback2);
|
| | | });
|
| | | }
|
| | |
|
| | | lock (criticalSectionGlobal) {
|
| | | runningPrograms--;
|
| | |
| | | {
|
| | | var debugMode = new DBGMODE[1];
|
| | | int res = VSConstants.S_FALSE;
|
| | | vsDebuggerThreadDispatcher
|
| | | .BeginInvoke(new Action(() => res = VsDebugger.GetMode(debugMode)), new object[0])
|
| | | .Wait();
|
| | |
|
| | | QtVsToolsPackage.Instance.JoinableTaskFactory.Run(async () =>
|
| | | {
|
| | | await QtVsToolsPackage.Instance.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | res = VsDebugger.GetMode(debugMode);
|
| | | });
|
| | |
|
| | | if (res != VSConstants.S_OK)
|
| | | return false;
|
| | |
| | | {
|
| | | get
|
| | | {
|
| | | return ((bool)QtVsToolsPackage.Instance.Dte
|
| | | .Properties["Debugging", "General"]
|
| | | .Item("BreakAllProcesses")
|
| | | .Value);
|
| | | return ThreadHelper.JoinableTaskFactory.Run(async () => {
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | return ((bool)QtVsToolsPackage.Instance.Dte
|
| | | .Properties["Debugging", "General"]
|
| | | .Item("BreakAllProcesses")
|
| | | .Value);
|
| | | });
|
| | | }
|
| | | set
|
| | | {
|
| | | QtVsToolsPackage.Instance.Dte
|
| | | .Properties["Debugging", "General"]
|
| | | .Item("BreakAllProcesses")
|
| | | .let_Value(value ? "True" : "False");
|
| | | ThreadHelper.JoinableTaskFactory.Run(async () =>
|
| | | {
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | QtVsToolsPackage.Instance.Dte
|
| | | .Properties["Debugging", "General"]
|
| | | .Item("BreakAllProcesses")
|
| | | .let_Value(value ? "True" : "False");
|
| | | });
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.Linq;
|
| | | using System.Text;
|
| | | using Microsoft.VisualStudio;
|
| | | using Microsoft.VisualStudio.Debugger.Interop;
|
| | |
|
| | |
| | | // property, or some other property. The property is usually the result of
|
| | | // an expression evaluation."
|
| | | {
|
| | | public QmlDebugger Debugger { get; private set; }
|
| | | private QmlDebugger Debugger { get; set; }
|
| | |
|
| | | public QmlEngine Engine { get; private set; }
|
| | | public Program Program { get; private set; }
|
| | | public StackFrame StackFrame { get; private set; }
|
| | | public CodeContext CodeContext { get; private set; }
|
| | | private QmlEngine Engine { get; set; }
|
| | | private Program Program { get; set; }
|
| | | private StackFrame StackFrame { get; set; }
|
| | | private CodeContext CodeContext { get; set; }
|
| | |
|
| | | public Property Parent { get; private set; }
|
| | | public SortedDictionary<string, Property> Children { get; private set; }
|
| | | private Property Parent { get; set; }
|
| | | private SortedDictionary<string, Property> Children { get; set; }
|
| | |
|
| | | public int FrameNumber { get; private set; }
|
| | | public int ScopeNumber { get; private set; }
|
| | | public JsValue JsValue { get; private set; }
|
| | | public string Name { get; private set; }
|
| | | public string FullName { get; private set; }
|
| | | public string Type { get; private set; }
|
| | | public string Value { get; private set; }
|
| | | private int FrameNumber { get; set; }
|
| | | private int ScopeNumber { get; set; }
|
| | | private JsValue JsValue { get; set; }
|
| | | private string Name { get; set; }
|
| | | private string FullName { get; set; }
|
| | | private string Type { get; set; }
|
| | | private string Value { get; set; }
|
| | |
|
| | | public static Property Create(
|
| | | StackFrame frame,
|
| | |
| | |
|
| | | static string GetChildKey(string childName)
|
| | | {
|
| | | int childIndex;
|
| | | if (int.TryParse(childName, out childIndex))
|
| | | if (int.TryParse(childName, out int childIndex))
|
| | | return string.Format("{0:D9}", childIndex);
|
| | | else
|
| | | return childName;
|
| | | return childName;
|
| | | }
|
| | |
|
| | | int IDebugProperty2.SetValueAsString(string pszValue, uint dwRadix, uint dwTimeout)
|
| | |
| | |
|
| | | public DEBUG_PROPERTY_INFO GetInfo(enum_DEBUGPROP_INFO_FLAGS dwFields)
|
| | | {
|
| | | DEBUG_PROPERTY_INFO info;
|
| | | Info.Map(MappingToDEBUG_PROPERTY_INFO, dwFields, out info);
|
| | | Info.Map(MappingToDEBUG_PROPERTY_INFO, dwFields, out DEBUG_PROPERTY_INFO info);
|
| | | return info;
|
| | | }
|
| | |
|
| | |
| | | public static readonly Guid Registers
|
| | | = new Guid("223ae797-bd09-4f28-8241-2763bdc5f713");
|
| | |
|
| | | public static readonly Guid Locals
|
| | | private static readonly Guid Locals
|
| | | = new Guid("b200f725-e725-4c53-b36a-1ec27aef12ef");
|
| | |
|
| | | public static readonly Guid AllLocals
|
| | | private static readonly Guid AllLocals
|
| | | = new Guid("196db21f-5f22-45a9-b5a3-32cddb30db06");
|
| | |
|
| | | public static readonly Guid Args
|
| | | = new Guid("804bccea-0475-4ae7-8a46-1862688ab863");
|
| | |
|
| | | public static readonly Guid LocalsPlusArgs
|
| | | private static readonly Guid LocalsPlusArgs
|
| | | = new Guid("e74721bb-10c0-40f5-807f-920d37f95419");
|
| | |
|
| | | public static readonly Guid AllLocalsPlusArgs
|
| | | private static readonly Guid AllLocalsPlusArgs
|
| | | = new Guid("939729a8-4cb0-4647-9831-7ff465240d5f");
|
| | |
|
| | | public static bool LocalsSelected(ref Guid guidFilter)
|
| | |
| | | using System.Threading.Tasks;
|
| | | using Microsoft.VisualStudio;
|
| | | using Microsoft.VisualStudio.Debugger.Interop;
|
| | | using Microsoft.VisualStudio.Threading;
|
| | |
|
| | | namespace QtVsTools.Qml.Debug.AD7
|
| | | {
|
| | |
| | | public Program Program { get; private set; }
|
| | |
|
| | | public CodeContext Context { get; private set; }
|
| | | public Dictionary<int, Dictionary<string, Property>> Properties { get; private set; }
|
| | | private Dictionary<int, Dictionary<string, Property>> Properties { get; set; }
|
| | |
|
| | | public string Name { get; private set; }
|
| | | public int FrameNumber { get; private set; }
|
| | | public IEnumerable<int> Scopes { get; private set; }
|
| | | public Task InitThread { get; private set; }
|
| | | private string Name { get; set; }
|
| | | public int FrameNumber { get; set; }
|
| | | private IEnumerable<int> Scopes { get; set; }
|
| | | private JoinableTask InitThread { get; set; }
|
| | |
|
| | | static public StackFrame Create(
|
| | | public static StackFrame Create(
|
| | | string name,
|
| | | int number,
|
| | | IEnumerable<int> scopes,
|
| | |
| | | Name = string.Format("{0}@{1}:{2}", name, context.FilePath, context.FileLine + 1);
|
| | | FrameNumber = number;
|
| | | Scopes = scopes;
|
| | | InitThread = Task.Run(() => InitializeProperties());
|
| | | InitThread = QtVsToolsPackage.Instance.JoinableTaskFactory.RunAsync(async () =>
|
| | | {
|
| | | InitializeProperties();
|
| | | await Task.Yield();
|
| | | });
|
| | | return true;
|
| | | }
|
| | |
|
| | |
| | | if (guidFilter != Guid.Empty && !Property.Filter.LocalsSelected(ref guidFilter))
|
| | | return VSConstants.S_OK;
|
| | |
|
| | | InitThread.Wait();
|
| | | InitThread.Join();
|
| | | pcelt = 0;
|
| | | ppEnum = PropertyEnum.Create(Properties
|
| | | .SelectMany(x => x.Value
|
| | |
| | | uint dwTimeout,
|
| | | out IEnumDebugPropertyInfo2 ppEnum)
|
| | | {
|
| | | uint pcelt;
|
| | | return ((IDebugStackFrame2)this)
|
| | | .EnumProperties(dwFields, dwRadix, guidFilter, dwTimeout, out pcelt, out ppEnum);
|
| | | .EnumProperties(dwFields, dwRadix, guidFilter, dwTimeout, out _, out ppEnum);
|
| | | }
|
| | |
|
| | | #region //////////////////// Info /////////////////////////////////////////////////////////
|
| | |
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using QtVsTools.Core;
|
| | | using QtVsTools.Core.QtMsBuild;
|
| | | using QtVsTools.SyntaxAnalysis;
|
| | | using static QtVsTools.SyntaxAnalysis.RegExpr;
|
| | |
|
| | | namespace QtVsTools.Qml.Debug
|
| | | {
|
| | | using AD7;
|
| | | using Common;
|
| | | using Core;
|
| | | using Core.QtMsBuild;
|
| | | using SyntaxAnalysis;
|
| | | using VisualStudio;
|
| | |
|
| | | using static SyntaxAnalysis.RegExpr;
|
| | |
|
| | | class Launcher : Disposable, IDebugEventCallback2
|
| | | {
|
| | | public static Launcher Instance { get; private set; }
|
| | | LazyFactory Lazy { get; } = new LazyFactory();
|
| | |
|
| | | private static Launcher Instance { get; set; }
|
| | | IVsDebugger debugger;
|
| | | IVsDebugger4 debugger4;
|
| | |
|
| | | HashSet<Guid> _ExcludedProcesses;
|
| | | HashSet<Guid> ExcludedProcesses => _ExcludedProcesses
|
| | | ?? (_ExcludedProcesses = new HashSet<Guid>());
|
| | | HashSet<Guid> ExcludedProcesses => Lazy.Get(() =>
|
| | | ExcludedProcesses, () => new HashSet<Guid>());
|
| | |
|
| | | public static void Initialize()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | Instance = new Launcher();
|
| | | Instance.debugger = VsServiceProvider.GetService<IVsDebugger>();
|
| | | Instance.debugger4 = VsServiceProvider.GetService<IVsDebugger, IVsDebugger4>();
|
| | |
|
| | | if (Instance.debugger != null && Instance.debugger4 != null)
|
| | | Instance.debugger.AdviseDebugEventCallback(Instance);
|
| | | }
|
| | |
|
| | | protected override void DisposeManaged()
|
| | | {
|
| | | if (debugger != null)
|
| | | debugger.UnadviseDebugEventCallback(this);
|
| | | if (debugger != null) {
|
| | | ThreadHelper.JoinableTaskFactory.Run(async () =>
|
| | | {
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | debugger.UnadviseDebugEventCallback(this);
|
| | | });
|
| | | }
|
| | | }
|
| | |
|
| | | int IDebugEventCallback2.Event(
|
| | |
| | | ref Guid riidEvent,
|
| | | uint dwAttrib)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (!QtVsToolsPackage.Instance.Options.QmlDebuggerEnabled)
|
| | | return VSConstants.S_OK;
|
| | |
|
| | |
| | | if (pProcess == null && pProgram.GetProcess(out pProcess) != VSConstants.S_OK)
|
| | | return VSConstants.S_OK;
|
| | |
|
| | | Guid procGuid;
|
| | | if (pProcess.GetProcessId(out procGuid) != VSConstants.S_OK)
|
| | | if (pProcess.GetProcessId(out Guid procGuid) != VSConstants.S_OK)
|
| | | return VSConstants.S_OK;
|
| | |
|
| | | // Run only once per process
|
| | |
| | | else
|
| | | return VSConstants.S_OK;
|
| | |
|
| | | string execPath;
|
| | | uint procId;
|
| | | if (!GetProcessInfo(pProcess, native, out execPath, out procId))
|
| | | if (!GetProcessInfo(pProcess, native, out string execPath, out uint procId))
|
| | | return VSConstants.S_OK;
|
| | |
|
| | | string execCmd;
|
| | | IEnumerable<string> rccItems;
|
| | | if (!GetProjectInfo(execPath, native, out execCmd, out rccItems))
|
| | | if (!GetProjectInfo(execPath, native, out string execCmd, out IEnumerable<string> rccItems))
|
| | | return VSConstants.S_OK;
|
| | |
|
| | | LaunchDebug(execPath, execCmd, procId, rccItems);
|
| | |
| | |
|
| | | Guid GetEngineId(IDebugProgram2 pProgram)
|
| | | {
|
| | | string engineName;
|
| | | Guid engineGuid;
|
| | | if (pProgram.GetEngineInfo(out engineName, out engineGuid) != VSConstants.S_OK)
|
| | | if (pProgram.GetEngineInfo(out _, out Guid engineGuid) != VSConstants.S_OK)
|
| | | return Guid.Empty;
|
| | | return engineGuid;
|
| | | }
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | static RegExpr wslPathRegex = new Token("WSLPATH", SkipWs_Disable, StartOfFile
|
| | | static readonly RegExpr wslPathRegex = new Token("WSLPATH", SkipWs_Disable, StartOfFile
|
| | | & "/mnt/" & new Token("DRIVE", CharWord) & "/" & new Token("PATH", AnyChar.Repeat()))
|
| | | {
|
| | | new Rule<WslPath>
|
| | |
| | | Update("PATH", (WslPath wslPath, string path) => wslPath.Path = path),
|
| | | }
|
| | | };
|
| | | static RegExpr.Parser wslPathParser = wslPathRegex.Render();
|
| | | static readonly RegExpr.Parser wslPathParser = wslPathRegex.Render();
|
| | |
|
| | | bool GetProcessInfo(IDebugProcess2 pProcess, bool native, out string execPath, out uint procId)
|
| | | {
|
| | | execPath = "";
|
| | | procId = 0;
|
| | |
|
| | | string fileName;
|
| | | if (pProcess.GetName(enum_GETNAME_TYPE.GN_FILENAME, out fileName) != VSConstants.S_OK)
|
| | | if (pProcess.GetName(enum_GETNAME_TYPE.GN_FILENAME, out string fileName) != VSConstants.S_OK)
|
| | | return false;
|
| | |
|
| | | var pProcessId = new AD_PROCESS_ID[1];
|
| | |
| | |
|
| | | bool GetProjectInfo(string execPath, bool native, out string execCmd, out IEnumerable<string> rccItems)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | execCmd = "";
|
| | | rccItems = null;
|
| | |
|
| | |
| | | uint procId,
|
| | | IEnumerable<string> rccItems)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | var targets = new[] { new VsDebugTargetInfo4
|
| | | {
|
| | | dlo = (uint)DEBUG_LAUNCH_OPERATION.DLO_CreateProcess,
|
| | |
| | | try {
|
| | | debugger4.LaunchDebugTargets4((uint)targets.Length, targets, processInfo);
|
| | |
|
| | | } catch (System.Exception e) {
|
| | | OutputWriteLine(e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.IO;
|
| | | using System.Linq;
|
| | | using System.Threading.Tasks;
|
| | | using QtVsTools.SyntaxAnalysis;
|
| | | using static QtVsTools.SyntaxAnalysis.RegExpr;
|
| | | using RegExprParser = QtVsTools.SyntaxAnalysis.RegExpr.Parser;
|
| | |
|
| | | namespace QtVsTools.Qml.Debug
|
| | | {
|
| | | using Common;
|
| | | using SyntaxAnalysis;
|
| | | using V4;
|
| | |
|
| | | using RegExprParser = SyntaxAnalysis.RegExpr.Parser;
|
| | |
|
| | | using static SyntaxAnalysis.RegExpr;
|
| | |
|
| | | struct FrameInfo
|
| | | {
|
| | |
| | |
|
| | | class QmlDebugger : Disposable, IMessageEventSink
|
| | | {
|
| | | static LazyFactory StaticLazy { get; } = new LazyFactory();
|
| | |
|
| | | IDebuggerEventSink sink;
|
| | | ProtocolDriver driver;
|
| | | string connectionHostName;
|
| | |
| | | List<Request> outbox;
|
| | | Dictionary<int, IBreakpoint> breakpoints;
|
| | |
|
| | | public bool Started { get; private set; }
|
| | | private bool Started { get; set; }
|
| | |
|
| | | public bool Running { get; private set; }
|
| | | private bool Running { get; set; }
|
| | |
|
| | | public string Version { get; private set; }
|
| | | private string Version { get; set; }
|
| | |
|
| | | public uint? ThreadId { get { return driver.ThreadId; } }
|
| | |
|
| | |
| | | if (!Started) {
|
| | | Running = Started = true;
|
| | | LeaveCriticalSection();
|
| | | Task.Run(() => ConnectToDebugger());
|
| | | _ = Task.Run(() => ConnectToDebugger());
|
| | |
|
| | | } else if (!Running) {
|
| | | Running = true;
|
| | |
| | | setBreakpoint.Arguments.Line = (int)breakpoint.Line;
|
| | | setBreakpoint.Tag = breakpoint;
|
| | | if (driver.ConnectionState == DebugClientState.Connected)
|
| | | setBreakpoint.SendAsync();
|
| | | setBreakpoint.SendRequest();
|
| | | else
|
| | | ThreadSafe(() => outbox.Add(setBreakpoint));
|
| | | }
|
| | |
| | |
|
| | | var reqClearBreak = Message.Create<ClearBreakpointRequest>(driver);
|
| | | reqClearBreak.Arguments.Breakpoint = breakpointNum[breakpoint];
|
| | | reqClearBreak.SendAsync();
|
| | | reqClearBreak.SendRequest();
|
| | | }
|
| | |
|
| | | void RefreshFrames()
|
| | |
| | |
|
| | | } else {
|
| | | foreach (int breakpointId in evtBreak.Body.Breakpoints) {
|
| | | IBreakpoint breakpoint;
|
| | | if (!breakpoints.TryGetValue(breakpointId, out breakpoint))
|
| | | if (!breakpoints.TryGetValue(breakpointId, out IBreakpoint breakpoint))
|
| | | continue;
|
| | | breakpoint.NotifyBreak();
|
| | | }
|
| | |
| | | {
|
| | | if (oldState != DebugClientState.Unavailable
|
| | | && newState == DebugClientState.Disconnected) {
|
| | | Task.Run(() => sink.NotifyClientDisconnected());
|
| | | _ = Task.Run(() => sink.NotifyClientDisconnected());
|
| | | }
|
| | | }
|
| | |
|
| | | void IMessageEventSink.NotifyRequestResponded(Request msgRequest)
|
| | | {
|
| | | if (msgRequest is SetBreakpointRequest)
|
| | | Task.Run(() => SetBreakpointResponded(msgRequest as SetBreakpointRequest));
|
| | | _ = Task.Run(() => SetBreakpointResponded(msgRequest as SetBreakpointRequest));
|
| | | }
|
| | |
|
| | | void IMessageEventSink.NotifyEvent(Event msgEvent)
|
| | | {
|
| | | if (msgEvent is BreakEvent)
|
| | | Task.Run(() => BreakNotified(msgEvent as BreakEvent));
|
| | | _ = Task.Run(() => BreakNotified(msgEvent as BreakEvent));
|
| | | }
|
| | |
|
| | | void IMessageEventSink.NotifyMessage(Message msg)
|
| | |
| | |
|
| | | public static bool CheckCommandLine(string execPath, string args)
|
| | | {
|
| | | ushort portFrom;
|
| | | ushort portTo;
|
| | | string hostName;
|
| | | string fileName;
|
| | | bool block;
|
| | | return ParseCommandLine(
|
| | | execPath, args, out portFrom, out portTo, out hostName, out fileName, out block);
|
| | | return ParseCommandLine(execPath, args, out _, out _, out _, out _, out _);
|
| | | }
|
| | |
|
| | | /// <summary>
|
| | |
| | | /// <summary>
|
| | | /// Regex-based parser for QML debug connection parameters
|
| | | /// </summary>
|
| | | static RegExprParser ConnectParamsParser => _ConnectParamsParser ?? (
|
| | | _ConnectParamsParser = new Token(TokenId.ConnectParams, RxConnectParams)
|
| | | static RegExprParser ConnectParamsParser => StaticLazy.Get(() =>
|
| | | ConnectParamsParser, () => new Token(TokenId.ConnectParams, RxConnectParams)
|
| | | {
|
| | | new Rule<ConnectParams>
|
| | | {
|
| | |
| | | }
|
| | | }
|
| | | .Render());
|
| | | static RegExprParser _ConnectParamsParser;
|
| | |
|
| | | /// <summary>
|
| | | /// Regular expression for parsing connection parameters string in the form:
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2018 The Qt Company Ltd.
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | |
| | |
|
| | | namespace QtVsTools.Qml.Debug
|
| | | {
|
| | | using QtVsTools.Core;
|
| | |
|
| | | struct QmlFile
|
| | | {
|
| | | public string QrcPath;
|
| | |
| | | using (var reader = XmlReader.Create(new StringReader(xmlText), settings)) {
|
| | | rccXml = XDocument.Load(reader);
|
| | | }
|
| | | } catch (Exception e) {
|
| | | System.Diagnostics.Debug.WriteLine(
|
| | | e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | return;
|
| | | }
|
| | |
|
| | |
| | |
|
| | | qrcPath = string.Format("qrc:///{0}", qrcPath);
|
| | |
|
| | | QmlFile file;
|
| | | if (!files.TryGetValue(qrcPath, out file))
|
| | | if (!files.TryGetValue(qrcPath, out QmlFile file))
|
| | | return default(QmlFile);
|
| | |
|
| | | return file;
|
| | |
| | | return default(QmlFile);
|
| | | }
|
| | |
|
| | | QmlFile file;
|
| | | if (files.TryGetValue(fullPath, out file))
|
| | | if (files.TryGetValue(fullPath, out QmlFile file))
|
| | | return file;
|
| | |
|
| | | return new QmlFile
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System.Collections.Generic;
|
| | | using System.ComponentModel;
|
| | | using System.Runtime.Serialization;
|
| | | using System.Threading;
|
| | |
|
| | | namespace QtVsTools.Qml.Debug.V4
|
| | | {
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.Linq;
|
| | | using System.Runtime.Serialization;
|
| | |
| | | set { Atomic(() => tag == null, () => tag = value); }
|
| | | }
|
| | |
|
| | | public virtual ProtocolDriver.PendingRequest SendAsync()
|
| | | public virtual ProtocolDriver.PendingRequest SendRequest()
|
| | | {
|
| | | return Driver.SendRequest(this);
|
| | | }
|
| | |
|
| | | public new Response Send()
|
| | | {
|
| | | return SendAsync().WaitForResponse();
|
| | | return SendRequest().WaitForResponse();
|
| | | }
|
| | |
|
| | | public static new Response Send<T>(ProtocolDriver driver, Action<T> initMsg = null)
|
| | |
| | |
|
| | | public new virtual TResponse Send()
|
| | | {
|
| | | var pendingRequest = SendAsync();
|
| | | var pendingRequest = SendRequest();
|
| | | if (!pendingRequest.RequestSent)
|
| | | return null;
|
| | |
|
| | |
| | | **
|
| | | ****************************************************************************/
|
| | |
|
| | | using QtVsTools.Options;
|
| | | using System;
|
| | | using System.Collections.Concurrent;
|
| | | using System.IO;
|
| | | using System.Net.Sockets;
|
| | | using System.Runtime.InteropServices;
|
| | | using System.Runtime.Serialization;
|
| | | using System.Runtime.Serialization.Json;
|
| | | using System.Text;
|
| | | using System.Threading;
|
| | | using System.Threading.Tasks;
|
| | |
| | | IConnectionEventSink sink;
|
| | | IntPtr client;
|
| | | Task clientThread;
|
| | | EventWaitHandle clientCreated = new EventWaitHandle(false, EventResetMode.ManualReset);
|
| | | readonly EventWaitHandle clientCreated = new EventWaitHandle(false, EventResetMode.ManualReset);
|
| | | EventWaitHandle clientConnected;
|
| | |
|
| | | public uint? ThreadId { get; private set; }
|
| | |
| | | if (state != value) {
|
| | | var oldState = state;
|
| | | state = value;
|
| | | Task.Run(() => sink.NotifyStateTransition(this, oldState, value));
|
| | | _ = Task.Run(() => sink.NotifyStateTransition(this, oldState, value));
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | {
|
| | | this.sink = sink;
|
| | |
|
| | | Task.WaitAny(new[]
|
| | | QtVsToolsPackage.Instance.JoinableTaskFactory.Run(async () =>
|
| | | {
|
| | | // Try to start client thread
|
| | | // Unblock if thread was abruptly terminated (e.g. DLL not found)
|
| | | clientThread = Task.Run(() => ClientThread()),
|
| | | await Task.WhenAny(new[]
|
| | | {
|
| | | // Try to start client thread
|
| | | // Unblock if thread was abruptly terminated (e.g. DLL not found)
|
| | | clientThread = Task.Run(() => ClientThread()),
|
| | |
|
| | | // Unblock if client was created (i.e. client thread is running)
|
| | | Task.Run(() => clientCreated.WaitOne())
|
| | | // Unblock if client was created (i.e. client thread is running)
|
| | | Task.Run(() => clientCreated.WaitOne())
|
| | | });
|
| | | });
|
| | |
|
| | | if (State == DebugClientState.Unavailable) {
|
| | |
| | | {
|
| | | if (State != DebugClientState.Unavailable) {
|
| | | NativeMethods.DebugClientShutdown(client);
|
| | | clientThread.Wait();
|
| | |
|
| | | QtVsToolsPackage.Instance.JoinableTaskFactory.Run(
|
| | | async () => await Task.WhenAll(new[] { clientThread }));
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | var hostNameData = Encoding.UTF8.GetBytes(hostName);
|
| | |
|
| | | uint timeout = (uint)QtVsToolsPackage.Instance.Options.QmlDebuggerTimeout;
|
| | | Task.Run(() =>
|
| | | _ = Task.Run(() =>
|
| | | {
|
| | | var connectTimer = new System.Diagnostics.Stopwatch();
|
| | | connectTimer.Start();
|
| | |
| | |
|
| | | uint timeout = (uint)QtVsToolsPackage.Instance.Options.QmlDebuggerTimeout;
|
| | | if (timeout != 0) {
|
| | | Task.Run(() =>
|
| | | _ = Task.Run(() =>
|
| | | {
|
| | | var connectTimer = new System.Diagnostics.Stopwatch();
|
| | | connectTimer.Start();
|
| | |
| | | IMessageEventSink sink;
|
| | | DebugClient client;
|
| | | int nextRequestSeq = 0;
|
| | | Dictionary<int, PendingRequest> pendingRequests = new Dictionary<int, PendingRequest>();
|
| | | readonly Dictionary<int, PendingRequest> pendingRequests = new Dictionary<int, PendingRequest>();
|
| | | Task eventHandlingThread;
|
| | | EventWaitHandle eventReceived = new EventWaitHandle(false, EventResetMode.AutoReset);
|
| | | ConcurrentQueue<Event> eventQueue = new ConcurrentQueue<Event>();
|
| | | readonly EventWaitHandle eventReceived = new EventWaitHandle(false, EventResetMode.AutoReset);
|
| | | readonly ConcurrentQueue<Event> eventQueue = new ConcurrentQueue<Event>();
|
| | |
|
| | | public uint? ThreadId { get { return client.ThreadId; } }
|
| | |
|
| | |
| | | protected override void DisposeFinally()
|
| | | {
|
| | | eventReceived.Set();
|
| | | eventHandlingThread.Wait();
|
| | | QtVsToolsPackage.Instance.JoinableTaskFactory.Run(
|
| | | async () => await Task.WhenAll(new[] { eventHandlingThread }));
|
| | | eventReceived.Dispose();
|
| | | }
|
| | |
|
| | |
| | | {
|
| | | while (!Disposing) {
|
| | | eventReceived.WaitOne();
|
| | | Event evt;
|
| | | while (!Disposing && eventQueue.TryDequeue(out evt))
|
| | | while (!Disposing && eventQueue.TryDequeue(out Event evt))
|
| | | sink.NotifyEvent(evt);
|
| | | }
|
| | | }
|
| | |
| | |
|
| | | public class PendingRequest : Finalizable
|
| | | {
|
| | | public Request Request { get; private set; }
|
| | | EventWaitHandle responded;
|
| | | public Request Request { get; }
|
| | | readonly EventWaitHandle responded;
|
| | |
|
| | | public PendingRequest()
|
| | | {
|
| | |
| | | /// </summary>
|
| | | public class DiagnosticMessage
|
| | | {
|
| | | public DiagnosticMessageKind Kind { get; set; }
|
| | | public SourceLocation Location { get; set; }
|
| | | private DiagnosticMessageKind Kind { get; }
|
| | | public SourceLocation Location { get; }
|
| | | public DiagnosticMessage(DiagnosticMessageKind kind, int offset, int length)
|
| | | {
|
| | | Kind = kind;
|
| | |
| | |
|
| | | IntPtr qmlTextPtr = IntPtr.Zero;
|
| | | IntPtr qmlParserPtr = IntPtr.Zero;
|
| | |
|
| | | List<Token> tokens;
|
| | | readonly List<Token> tokens;
|
| | | public IEnumerable<Token> Tokens
|
| | | {
|
| | | get { return tokens; }
|
| | | }
|
| | |
|
| | | List<DiagnosticMessage> diagnosticMessages;
|
| | | readonly List<DiagnosticMessage> diagnosticMessages;
|
| | | public IEnumerable<DiagnosticMessage> DiagnosticMessages
|
| | | {
|
| | | get { return diagnosticMessages; }
|
| | | }
|
| | |
|
| | | public int FirstErrorOffset { get; private set; }
|
| | | private int FirstErrorOffset { get; set; }
|
| | |
|
| | | List<AstNode> visitedNodes;
|
| | | readonly List<AstNode> visitedNodes;
|
| | | public IEnumerable<AstNode> AstNodes { get { return visitedNodes; } }
|
| | |
|
| | | public bool ParsedCorrectly { get; private set; }
|
| | |
|
| | | Dictionary<IntPtr, AstNode> nodesBytPtr;
|
| | | Dictionary<IntPtr, List<KeyValuePair<AstNode, PropertyInfo>>> pendingDereferences;
|
| | | readonly Dictionary<IntPtr, AstNode> nodesBytPtr;
|
| | | readonly Dictionary<IntPtr, List<KeyValuePair<AstNode, PropertyInfo>>> pendingDereferences;
|
| | |
|
| | | Parser()
|
| | | {
|
| | |
| | | if (ptrRef == IntPtr.Zero)
|
| | | return;
|
| | |
|
| | | AstNode nodeRef;
|
| | | if (nodesBytPtr.TryGetValue(ptrRef, out nodeRef)) {
|
| | | if (nodesBytPtr.TryGetValue(ptrRef, out AstNode nodeRef)) {
|
| | | nodeProperty.SetValue(node, nodeRef);
|
| | | } else {
|
| | | List<KeyValuePair<AstNode, PropertyInfo>> pendingRefList;
|
| | |
| | |
|
| | | public class AstNode : SyntaxElement
|
| | | {
|
| | | public AstNodeKind Kind { get; private set; }
|
| | | public AstNodeKind Kind { get; }
|
| | | public AstNode(AstNodeKind kind) { Kind = kind; }
|
| | | public SourceLocation FirstSourceLocation { get; set; }
|
| | | public SourceLocation LastSourceLocation { get; set; }
|
| | |
| | | /// </summary>
|
| | | public class Token : SyntaxElement
|
| | | {
|
| | | public TokenKind Kind { get; private set; }
|
| | | private TokenKind Kind { get; set; }
|
| | | public SourceLocation Location { get; private set; }
|
| | | protected Token() { }
|
| | | public static Token Create(TokenKind kind, int offset, int length)
|
| | |
| | | <!--
|
| | | *****************************************************************************
|
| | | **
|
| | | ** 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.
|
| | |
| | | <Group guid="ProjectContextMenuGuid" id="ProjectContextOthersMenuGroup" priority="0x0600">
|
| | | <Parent guid="ProjectContextMenuGuid" id="QtProjectSubMenu"/>
|
| | | </Group>
|
| | | <Group guid="ProjectContextMenuGuid" id="ProjectContextAddNewQtClassMenuGroup" priority="0x0600">
|
| | | <Parent guid="guidSHLMainMenu" id="cmdidShellWindowNavigate7"/>
|
| | | </Group>
|
| | |
|
| | | <!-- Endregion Project context menu groups -->
|
| | |
|
| | | <Group guid="ProjectContextMenuGuid" id="ProjectContextAddNewQtClassMenuGroup" priority="0x0600">
|
| | | <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_PROJECT" />
|
| | | </Group>
|
| | |
|
| | | <Group guid="ItemContextMenuGuid" id="ItemContextTsMenuGroup" priority="0x0600">
|
| | | <Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_ITEMNODE" />
|
| | |
| | | <ButtonText>qt.io</ButtonText>
|
| | | </Strings>
|
| | | </Button>
|
| | | <Button guid="MainMenuGuid" id="ViewGettingStartedId" priority="0x0100" type="Button">
|
| | | <Parent guid="MainMenuGuid" id="VersionMenuGroup" />
|
| | | <Icon guid="MenuImages" id="QtLogoBitmap" />
|
| | | <CommandFlag>DynamicVisibility</CommandFlag>
|
| | | <CommandFlag>DefaultInvisible</CommandFlag>
|
| | | <Strings>
|
| | | <ButtonText>Getting Started</ButtonText>
|
| | | </Strings>
|
| | | </Button>
|
| | |
|
| | | <Button guid="MainMenuGuid" id="F1QtHelpId" priority="0x0100" type="Button">
|
| | | <Parent guid="MainMenuGuid" id="VersionMenuGroup" />
|
| | |
| | | </Strings>
|
| | | </Button>
|
| | |
|
| | | <Button guid="MainMenuGuid" id="CreateNewTsFileId" priority="0x0100" type="Button">
|
| | | <Parent guid="MainMenuGuid" id="OthersMenuGroup" />
|
| | | <CommandFlag>DefaultDisabled</CommandFlag>
|
| | | <CommandFlag>DynamicVisibility</CommandFlag>
|
| | | <CommandFlag>DefaultInvisible</CommandFlag>
|
| | | <Strings>
|
| | | <ButtonText>Create New Translation File</ButtonText>
|
| | | <ToolTipText>Create a new translation file that you can open in Qt Linguist</ToolTipText>
|
| | | </Strings>
|
| | | </Button>
|
| | | <Button guid="MainMenuGuid" id="ConvertToQtMsBuild" priority="0x0100" type="Button">
|
| | | <Parent guid="MainMenuGuid" id="OthersMenuGroup" />
|
| | | <CommandFlag>DefaultDisabled</CommandFlag>
|
| | |
| | | <CommandFlag>DynamicVisibility</CommandFlag>
|
| | | <Strings>
|
| | | <ButtonText>Convert custom build steps to Qt/MSBuild</ButtonText>
|
| | | </Strings>
|
| | | </Button>
|
| | | <Button guid="MainMenuGuid" id="ConvertToQtId" priority="0x0100" type="Button">
|
| | | <Parent guid="MainMenuGuid" id="OthersMenuGroup" />
|
| | | <CommandFlag>DefaultDisabled</CommandFlag>
|
| | | <CommandFlag>DefaultInvisible</CommandFlag>
|
| | | <CommandFlag>DynamicVisibility</CommandFlag>
|
| | | <Strings>
|
| | | <ButtonText>Convert Project to Qt VS Tools Project</ButtonText>
|
| | | </Strings>
|
| | | </Button>
|
| | | <Button guid="MainMenuGuid" id="ConvertToQmakeId" priority="0x0100" type="Button">
|
| | | <Parent guid="MainMenuGuid" id="OthersMenuGroup" />
|
| | | <CommandFlag>DefaultDisabled</CommandFlag>
|
| | | <CommandFlag>DynamicVisibility</CommandFlag>
|
| | | <CommandFlag>DefaultInvisible</CommandFlag>
|
| | | <Strings>
|
| | | <ButtonText>Convert Project to QMake Generated Project</ButtonText>
|
| | | </Strings>
|
| | | </Button>
|
| | | <Button guid="MainMenuGuid" id="QtProjectSettingsId" priority="0x0100" type="Button">
|
| | |
| | | </Strings>
|
| | | </Button>
|
| | |
|
| | | <Button guid="ProjectContextMenuGuid" id="CreateNewTsFileProjectId" priority="0x0100" type="Button">
|
| | | <Parent guid="ProjectContextMenuGuid" id="ProjectContextTsMenuGroup" />
|
| | | <CommandFlag>DefaultDisabled</CommandFlag>
|
| | | <CommandFlag>DynamicVisibility</CommandFlag>
|
| | | <Strings>
|
| | | <ButtonText>Create New Translation File</ButtonText>
|
| | | <ToolTipText>Create a new translation file that you can open in Qt Linguist</ToolTipText>
|
| | | </Strings>
|
| | | </Button>
|
| | | <Button guid="ProjectContextMenuGuid" id="lUpdateOnProjectId" priority="0x0100" type="Button">
|
| | | <Parent guid="ProjectContextMenuGuid" id="ProjectContextTsMenuGroup" />
|
| | | <Icon guid="MenuImages" id="LaunchLinguistBitmap" />
|
| | |
| | | <ButtonText>Refresh IntelliSense</ButtonText>
|
| | | </Strings>
|
| | | </Button>
|
| | | <Button guid="ProjectContextMenuGuid" id="ConvertToQtProjectId" priority="0x0100" type="Button">
|
| | | <Parent guid="ProjectContextMenuGuid" id="ProjectContextOthersMenuGroup" />
|
| | | <CommandFlag>DefaultDisabled</CommandFlag>
|
| | | <CommandFlag>DefaultInvisible</CommandFlag>
|
| | | <CommandFlag>DynamicVisibility</CommandFlag>
|
| | | <Strings>
|
| | | <ButtonText>Convert Project to Qt VS Tools Project</ButtonText>
|
| | | </Strings>
|
| | | </Button>
|
| | | <Button guid="ProjectContextMenuGuid" id="ConvertToQmakeProjectId" priority="0x0100" type="Button">
|
| | | <Parent guid="ProjectContextMenuGuid" id="ProjectContextOthersMenuGroup" />
|
| | | <CommandFlag>DefaultDisabled</CommandFlag>
|
| | | <CommandFlag>DynamicVisibility</CommandFlag>
|
| | | <Strings>
|
| | | <ButtonText>Convert Project to QMake Generated Project</ButtonText>
|
| | | </Strings>
|
| | | </Button>
|
| | | <Button guid="ProjectContextMenuGuid" id="QtProjectSettingsProjectId" priority="0x0100" type="Button">
|
| | | <Parent guid="ProjectContextMenuGuid" id="ProjectContextOthersMenuGroup" />
|
| | | <CommandFlag>DefaultDisabled</CommandFlag>
|
| | |
| | | <CommandFlag>DynamicVisibility</CommandFlag>
|
| | | <Strings>
|
| | | <ButtonText>Change Project's Qt Version</ButtonText>
|
| | | </Strings>
|
| | | </Button>
|
| | | <Button guid="ProjectContextMenuGuid" id="ProjectAddNewQtClassProjectId" priority="0x0100" type="Button">
|
| | | <Parent guid="ProjectContextMenuGuid" id="ProjectContextAddNewQtClassMenuGroup" />
|
| | | <Icon guid="MenuImages" id="AddNewQtClassBitmap" />
|
| | | <CommandFlag>DefaultDisabled</CommandFlag>
|
| | | <CommandFlag>DefaultInvisible</CommandFlag>
|
| | | <CommandFlag>DynamicVisibility</CommandFlag>
|
| | | <Strings>
|
| | | <ButtonText>Add Qt Class...</ButtonText>
|
| | | </Strings>
|
| | | </Button>
|
| | |
|
| | |
| | | -->
|
| | | <Bitmap guid="MenuImages" href="Resources\menuimages.png" usedList="LaunchDesignerBitmap,
|
| | | LaunchLinguistBitmap, OpenProFileBitmap, ImportPriFileBitmap, ExportProFileBitmap,
|
| | | CreateProFileBitmap, QtLogoBitmap, AddNewQtClassBitmap" />
|
| | | CreateProFileBitmap, QtLogoBitmap" />
|
| | | </Bitmaps>
|
| | | </Commands>
|
| | |
|
| | |
| | | <IDSymbol name="QtVersionId" value="0x0500" />
|
| | | <IDSymbol name="ViewQtHelpId" value="0x0501" />
|
| | | <IDSymbol name="F1QtHelpId" value="0x0502" />
|
| | | <IDSymbol name="ViewGettingStartedId" value="0x0503" />
|
| | |
|
| | | <IDSymbol name="LaunchMenuGroup" value="0x1021" />
|
| | | <IDSymbol name="LaunchDesignerId" value="0x0100" />
|
| | |
| | | <IDSymbol name="ExportProFileId" value="0x0105" />
|
| | |
|
| | | <IDSymbol name="OthersMenuGroup" value="0x1023" />
|
| | | <IDSymbol name="CreateNewTsFileId" value="0x0107" />
|
| | | <IDSymbol name="ConvertToQtMsBuild" value="0x0130" />
|
| | | <IDSymbol name="ConvertToQtId" value="0x0124" />
|
| | | <IDSymbol name="ConvertToQmakeId" value="0x0108" />
|
| | | <IDSymbol name="QtProjectSettingsId" value="0x0109" />
|
| | | <IDSymbol name="ChangeProjectQtVersionId" value="0x0126" />
|
| | |
|
| | |
| | | <IDSymbol name="ExportProFileProjectId" value="0x0116" />
|
| | |
|
| | | <IDSymbol name="ProjectContextTsMenuGroup" value="0x1028" />
|
| | | <IDSymbol name="CreateNewTsFileProjectId" value="0x0117" />
|
| | | <IDSymbol name="lUpdateOnProjectId" value="0x0118" />
|
| | | <IDSymbol name="lReleaseOnProjectId" value="0x0119" />
|
| | |
|
| | | <IDSymbol name="ProjectContextOthersMenuGroup" value="0x1029" />
|
| | | <IDSymbol name="ProjectConvertToQtMsBuild" value="0x0130" />
|
| | | <IDSymbol name="ProjectRefreshIntelliSense" value="0x0131" />
|
| | | <IDSymbol name="ConvertToQtProjectId" value="0x0120" />
|
| | | <IDSymbol name="ConvertToQmakeProjectId" value="0x0121" />
|
| | | <IDSymbol name="QtProjectSettingsProjectId" value="0x0122" />
|
| | | <IDSymbol name="ChangeProjectQtVersionProjectId" value="0x0123" />
|
| | |
|
| | | <IDSymbol name="ProjectContextAddNewQtClassMenuGroup" value="0x1031" />
|
| | | <IDSymbol name="ProjectAddNewQtClassProjectId" value="0x0200" />
|
| | |
|
| | | <!-- Endregion Project context menu button Ids -->
|
| | |
|
| | |
| | | <IDSymbol name="ExportProFileBitmap" value="5" />
|
| | | <IDSymbol name="CreateProFileBitmap" value="6" />
|
| | | <IDSymbol name="QtLogoBitmap" value="7" />
|
| | | <IDSymbol name="AddNewQtClassBitmap" value="8" />
|
| | | </GuidSymbol>
|
| | | </Symbols>
|
| | |
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2021 The Qt Company Ltd.
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | |
| | |
|
| | | using Microsoft.VisualStudio.ProjectSystem;
|
| | | using Microsoft.VisualStudio.ProjectSystem.Properties;
|
| | | using Microsoft.Internal.VisualStudio.PlatformUI;
|
| | | using System;
|
| | | using System.Collections.Generic;
|
| | | using System.ComponentModel.Composition;
|
| | | using System.Linq;
|
| | | using System.Threading.Tasks;
|
| | |
|
| | | namespace QtVsTools.QtMsBuild
|
| | | {
|
| | | using QtVsTools.Core;
|
| | | using Core;
|
| | |
|
| | | [Export(typeof(IPropertyPageUIValueEditor))]
|
| | | [ExportMetadata("Name", "QtModulesEditor")]
|
| | |
| | | {
|
| | | await Task.Yield();
|
| | |
|
| | | var modules = QtModules.Instance.GetAvailableModules()
|
| | | var qtSettings = ruleProperty.ContainingRule;
|
| | | var qtVersion = await qtSettings.GetPropertyValueAsync("QtInstall");
|
| | |
|
| | | var vm = QtVersionManager.The();
|
| | | var versionInfo = vm.GetVersionInfo(qtVersion);
|
| | | if (versionInfo == null)
|
| | | versionInfo = vm.GetVersionInfo(vm.GetDefaultVersion());
|
| | |
|
| | | var modules = QtModules.Instance.GetAvailableModules(versionInfo.qtMajor)
|
| | | .Where(x => !string.IsNullOrEmpty(x.proVarQT))
|
| | | .Select(x => new QtModulesPopup.Module
|
| | | {
|
| | |
| | | })
|
| | | .ToList();
|
| | |
|
| | | var allQT = modules.SelectMany(x => x.QT).ToHashSet();
|
| | | var selectedQT = currentValue.ToString().Split(';').ToHashSet();
|
| | | var extraQT = selectedQT.Except(allQT);
|
| | | HashSet<string> selectedQt = null;
|
| | | IEnumerable<string> extraQt = null;
|
| | | if (currentValue != null) {
|
| | | var allQt = modules.SelectMany(x => x.QT).ToHashSet();
|
| | | selectedQt = currentValue.ToString().Split(';').ToHashSet();
|
| | | extraQt = selectedQt.Except(allQt);
|
| | |
|
| | | foreach (var module in modules)
|
| | | module.IsSelected = module.QT.Intersect(selectedQT).Count() == module.QT.Count;
|
| | | foreach (var module in modules)
|
| | | module.IsSelected = module.QT.Intersect(selectedQt).Count() == module.QT.Count;
|
| | | }
|
| | |
|
| | | var popup = new QtModulesPopup();
|
| | | popup.SetModules(modules);
|
| | | popup.SetModules(modules.OrderBy(module => module.Name));
|
| | |
|
| | | if (popup.ShowModal().GetValueOrDefault()) {
|
| | | selectedQT = modules
|
| | | selectedQt = modules
|
| | | .Where(x => x.IsSelected)
|
| | | .SelectMany(x => x.QT)
|
| | | .Union(extraQT)
|
| | | .Union(extraQt ?? Enumerable.Empty<string>())
|
| | | .ToHashSet();
|
| | | }
|
| | | return string.Join(";", selectedQT);
|
| | | return selectedQt == null ? "" : string.Join(";", selectedQt);
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | <!--
|
| | | *****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2021 The Qt Company Ltd.
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | |
| | | **
|
| | | *****************************************************************************
|
| | | -->
|
| | | <local:VsToolsDialogWindow x:Class="QtVsTools.QtMsBuild.QtModulesPopup"
|
| | | <vsui:DialogWindow x:Class="QtVsTools.QtMsBuild.QtModulesPopup"
|
| | | xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
| | | xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
| | | xmlns:local="clr-namespace:QtVsTools"
|
| | | xmlns:vsui="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.15.0"
|
| | | ResizeMode="CanResize"
|
| | | Width="800" MaxHeight="550"
|
| | | MouseDown="Window_MouseDown"
|
| | |
| | | <Button IsCancel="True" MinHeight="23" MinWidth="74">_Cancel</Button>
|
| | | </WrapPanel>
|
| | | </Grid>
|
| | | </local:VsToolsDialogWindow>
|
| | | </vsui:DialogWindow>
|
| | |
| | | /****************************************************************************
|
| | | **
|
| | | ** Copyright (C) 2021 The Qt Company Ltd.
|
| | | ** Copyright (C) 2022 The Qt Company Ltd.
|
| | | ** Contact: https://www.qt.io/licensing/
|
| | | **
|
| | | ** This file is part of the Qt VS Tools.
|
| | |
| | | using System.Windows;
|
| | | using System.Windows.Controls;
|
| | | using System.Windows.Input;
|
| | | using Microsoft.VisualStudio.PlatformUI;
|
| | |
|
| | | namespace QtVsTools.QtMsBuild
|
| | | {
|
| | | public partial class QtModulesPopup : VsToolsDialogWindow
|
| | | public partial class QtModulesPopup : DialogWindow
|
| | | {
|
| | | public class Module
|
| | | {
|
| | |
| | | private void PopupListBox_KeyDown(object sender, KeyEventArgs e)
|
| | | {
|
| | | if (e.Key == Key.Enter || e.Key == Key.Space) {
|
| | | var module = PopupListBox.SelectedItem as Module;
|
| | | if (module != null && module.IsEnabled)
|
| | | if (PopupListBox.SelectedItem is Module module && module.IsEnabled)
|
| | | module.CheckBox.IsChecked = (module.CheckBox.IsChecked != true);
|
| | | }
|
| | | }
|
| | |
| | | using Microsoft.VisualStudio.TaskStatusCenter;
|
| | | using Microsoft.VisualStudio.Threading;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | | using EnvDTE;
|
| | |
|
| | | using Thread = System.Threading.Thread;
|
| | |
|
| | | namespace QtVsTools.QtMsBuild
|
| | | {
|
| | | using Common;
|
| | | using Core;
|
| | | using VisualStudio;
|
| | | using Thread = System.Threading.Thread;
|
| | | using static Common.EnumExt;
|
| | |
|
| | | class QtProjectBuild : Concurrent<QtProjectBuild>
|
| | | {
|
| | | static PunisherQueue<QtProjectBuild> _BuildQueue;
|
| | | static PunisherQueue<QtProjectBuild> BuildQueue =>
|
| | | StaticThreadSafeInit(() => _BuildQueue,
|
| | | () => _BuildQueue = new PunisherQueue<QtProjectBuild>(
|
| | | getItemKey: (QtProjectBuild build) =>
|
| | | {
|
| | | return build.ConfiguredProject;
|
| | | })
|
| | | );
|
| | | static LazyFactory StaticLazy { get; } = new LazyFactory();
|
| | |
|
| | | static ConcurrentStopwatch _RequestTimer;
|
| | | static ConcurrentStopwatch RequestTimer =>
|
| | | StaticThreadSafeInit(() => _RequestTimer, () => _RequestTimer = new ConcurrentStopwatch());
|
| | | public enum Target
|
| | | {
|
| | | // Mark project as dirty, but do not request a build
|
| | | [String("QtVsTools.QtMsBuild.QtProjectBuild.Target.SetOutdated")] SetOutdated
|
| | | }
|
| | |
|
| | | static IVsTaskStatusCenterService _StatusCenter;
|
| | | static IVsTaskStatusCenterService StatusCenter => StaticThreadSafeInit(() => _StatusCenter,
|
| | | () => _StatusCenter = VsServiceProvider
|
| | | .GetService<SVsTaskStatusCenterService, IVsTaskStatusCenterService>());
|
| | | static PunisherQueue<QtProjectBuild> BuildQueue => StaticLazy.Get(() =>
|
| | | BuildQueue, () => new PunisherQueue<QtProjectBuild>(
|
| | | getItemKey: (QtProjectBuild build) =>
|
| | | {
|
| | | return build.ConfiguredProject;
|
| | | }));
|
| | |
|
| | | static ConcurrentStopwatch RequestTimer => StaticLazy.Get(() =>
|
| | | RequestTimer, () => new ConcurrentStopwatch());
|
| | |
|
| | | static IVsTaskStatusCenterService StatusCenter => StaticLazy.Get(() =>
|
| | | StatusCenter, () => VsServiceProvider
|
| | | .GetService<SVsTaskStatusCenterService, IVsTaskStatusCenterService>());
|
| | |
|
| | | EnvDTE.Project Project { get; set; }
|
| | | VCProject VcProject { get; set; }
|
| | | UnconfiguredProject UnconfiguredProject { get; set; }
|
| | | ConfiguredProject ConfiguredProject { get; set; }
|
| | | Dictionary<string, string> Properties { get; set; }
|
| | |
| | |
|
| | | public static void StartBuild(
|
| | | EnvDTE.Project project,
|
| | | string projectPath,
|
| | | string configName,
|
| | | Dictionary<string, string> properties,
|
| | | IEnumerable<string> targets,
|
| | |
| | | if (configName == null)
|
| | | throw new ArgumentException("Configuration name cannot be null.");
|
| | |
|
| | | Task.Run(() => StartBuildAsync(project, configName, properties, targets, verbosity));
|
| | | _ = Task.Run(() => StartBuildAsync(
|
| | | project, projectPath, configName, properties, targets, verbosity));
|
| | | }
|
| | |
|
| | | public static async Task StartBuildAsync(
|
| | | EnvDTE.Project project,
|
| | | string projectPath,
|
| | | string configName,
|
| | | Dictionary<string, string> properties,
|
| | | IEnumerable<string> targets,
|
| | |
| | | throw new ArgumentException("Configuration name cannot be null.");
|
| | |
|
| | | RequestTimer.Restart();
|
| | | var tracker = QtProjectTracker.Get(project, projectPath);
|
| | | await tracker.Initialized;
|
| | |
|
| | | if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
|
| | | Messages.Print(string.Format(
|
| | | "{0:HH:mm:ss.FFF} QtProjectBuild({1}): Request [{2}] {3}",
|
| | | DateTime.Now, Thread.CurrentThread.ManagedThreadId,
|
| | | configName, project.FullName));
|
| | | configName, tracker.UnconfiguredProject.FullPath));
|
| | | }
|
| | |
|
| | | var tracker = QtProjectTracker.Get(project);
|
| | | await tracker.Initialized;
|
| | |
|
| | | var knownConfigs = await tracker.UnconfiguredProject.Services
|
| | | .ProjectConfigurationsService.GetKnownProjectConfigurationsAsync();
|
| | |
| | | BuildQueue.Enqueue(new QtProjectBuild()
|
| | | {
|
| | | Project = project,
|
| | | VcProject = tracker.VcProject,
|
| | | UnconfiguredProject = tracker.UnconfiguredProject,
|
| | | ConfiguredProject = configuredProject,
|
| | | Properties = properties?.ToDictionary(x => x.Key, x => x.Value),
|
| | |
| | | StaticThreadSafeInit(() => BuildDispatcher,
|
| | | () => BuildDispatcher = Task.Run(BuildDispatcherLoopAsync))
|
| | | .Forget();
|
| | | }
|
| | |
|
| | | public static void SetOutdated(
|
| | | EnvDTE.Project project,
|
| | | string projectPath,
|
| | | string configName,
|
| | | LoggerVerbosity verbosity = LoggerVerbosity.Quiet)
|
| | | {
|
| | | if (project == null)
|
| | | throw new ArgumentException("Project cannot be null.");
|
| | | if (configName == null)
|
| | | throw new ArgumentException("Configuration name cannot be null.");
|
| | |
|
| | | _ = Task.Run(() => SetOutdatedAsync(project, projectPath, configName, verbosity));
|
| | | }
|
| | |
|
| | | public static async Task SetOutdatedAsync(
|
| | | EnvDTE.Project project,
|
| | | string projectPath,
|
| | | string configName,
|
| | | LoggerVerbosity verbosity = LoggerVerbosity.Quiet)
|
| | | {
|
| | | await StartBuildAsync(
|
| | | project,
|
| | | projectPath,
|
| | | configName,
|
| | | null,
|
| | | new[] { Target.SetOutdated.Cast<string>() },
|
| | | verbosity);
|
| | | }
|
| | |
|
| | | public static void Reset()
|
| | |
| | | }
|
| | | await Task.Delay(100);
|
| | | }
|
| | | QtProjectBuild buildRequest;
|
| | | if (BuildQueue.TryDequeue(out buildRequest)) {
|
| | | if (BuildQueue.TryDequeue(out QtProjectBuild buildRequest)) {
|
| | | if (dispatchStatus == null) {
|
| | | dispatchStatus = StatusCenter.PreRegister(
|
| | | new TaskHandlerOptions
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | async Task<bool> BuildProjectAsync(ProjectWriteLockReleaser writeAccess)
|
| | | {
|
| | | var msBuildProject = await writeAccess.GetProjectAsync(ConfiguredProject);
|
| | |
|
| | | if (Targets.Any(t => t == Target.SetOutdated.Cast<string>())) {
|
| | | msBuildProject.MarkDirty();
|
| | | await writeAccess.ReleaseAsync();
|
| | | return true;
|
| | | }
|
| | |
|
| | | var solutionPath = QtProjectTracker.SolutionPath;
|
| | | var configProps = new Dictionary<string, string>(
|
| | | ConfiguredProject.ProjectConfiguration.Dimensions.ToImmutableDictionary())
|
| | | {
|
| | | { "SolutionPath", solutionPath },
|
| | | { "SolutionFileName", Path.GetFileName(solutionPath) },
|
| | | { "SolutionName", Path.GetFileNameWithoutExtension(solutionPath) },
|
| | | { "SolutionExt", Path.GetExtension(solutionPath) },
|
| | | { "SolutionDir", Path.GetDirectoryName(solutionPath).TrimEnd('\\') + '\\' }
|
| | | };
|
| | |
|
| | | foreach (var property in Properties)
|
| | | configProps[property.Key] = property.Value;
|
| | |
|
| | | var projectInstance = new ProjectInstance(msBuildProject.Xml,
|
| | | configProps, null, new ProjectCollection());
|
| | |
|
| | | var loggerVerbosity = LoggerVerbosity;
|
| | | if (QtVsToolsPackage.Instance.Options.BuildDebugInformation)
|
| | | loggerVerbosity = QtVsToolsPackage.Instance.Options.BuildLoggerVerbosity;
|
| | | var buildParams = new BuildParameters()
|
| | | {
|
| | | Loggers = (loggerVerbosity != LoggerVerbosity.Quiet)
|
| | | ? new[] { new QtProjectLogger() { Verbosity = loggerVerbosity } }
|
| | | : null
|
| | | };
|
| | |
|
| | | var buildRequest = new BuildRequestData(projectInstance,
|
| | | Targets.ToArray(),
|
| | | hostServices: null,
|
| | | flags: BuildRequestDataFlags.ProvideProjectStateAfterBuild);
|
| | |
|
| | | if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
|
| | | Messages.Print(string.Format(
|
| | | "{0:HH:mm:ss.FFF} QtProjectBuild({1}): Build [{2}] {3}",
|
| | | DateTime.Now, Thread.CurrentThread.ManagedThreadId,
|
| | | ConfiguredProject.ProjectConfiguration.Name,
|
| | | UnconfiguredProject.FullPath));
|
| | | Messages.Print("=== Targets");
|
| | | foreach (var target in buildRequest.TargetNames)
|
| | | Messages.Print(string.Format(" {0}", target));
|
| | | Messages.Print("=== Properties");
|
| | | foreach (var property in Properties) {
|
| | | Messages.Print(string.Format(" {0}={1}",
|
| | | property.Key, property.Value));
|
| | | }
|
| | | }
|
| | |
|
| | | BuildResult result = null;
|
| | | while (result == null) {
|
| | | try {
|
| | | result = BuildManager.DefaultBuildManager.Build(
|
| | | buildParams, buildRequest);
|
| | | } catch (InvalidOperationException) {
|
| | | if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
|
| | | Messages.Print(string.Format(
|
| | | "{0:HH:mm:ss.FFF} QtProjectBuild({1}): [{2}] "
|
| | | + "Warning: Another build is in progress; waiting...",
|
| | | DateTime.Now,
|
| | | Thread.CurrentThread.ManagedThreadId,
|
| | | ConfiguredProject.ProjectConfiguration.Name));
|
| | | }
|
| | | await Task.Delay(3000);
|
| | | }
|
| | | }
|
| | |
|
| | | if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
|
| | | string resMsg;
|
| | | StringBuilder resInfo = new StringBuilder();
|
| | | if (result?.OverallResult == BuildResultCode.Success) {
|
| | | resMsg = "Build ok";
|
| | | } else {
|
| | | resMsg = "Build FAIL";
|
| | | if (result == null) {
|
| | | resInfo.AppendLine("####### Build returned 'null'");
|
| | | } else {
|
| | | resInfo.AppendLine("####### Build returned 'Failure' code");
|
| | | if (result.ResultsByTarget != null) {
|
| | | foreach (var tr in result.ResultsByTarget) {
|
| | | var res = tr.Value;
|
| | | if (res.ResultCode != TargetResultCode.Failure)
|
| | | continue;
|
| | | resInfo.AppendFormat("### Target '{0}' FAIL\r\n", tr.Key);
|
| | | if (res.Items != null && res.Items.Length > 0) {
|
| | | resInfo.AppendFormat(
|
| | | "Items: {0}\r\n", string.Join(", ", res.Items
|
| | | .Select(it => it.ItemSpec)));
|
| | | }
|
| | | var e = tr.Value?.Exception;
|
| | | if (e != null) {
|
| | | resInfo.AppendFormat(
|
| | | "Exception: {0}\r\nStacktrace:\r\n{1}\r\n",
|
| | | e.Message, e.StackTrace);
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | Messages.Print(string.Format(
|
| | | "{0:HH:mm:ss.FFF} QtProjectBuild({1}): [{2}] {3}\r\n{4}",
|
| | | DateTime.Now, Thread.CurrentThread.ManagedThreadId,
|
| | | ConfiguredProject.ProjectConfiguration.Name,
|
| | | resMsg, resInfo.ToString()));
|
| | | }
|
| | |
|
| | | bool ok = false;
|
| | | if (result == null
|
| | | || result.ResultsByTarget == null
|
| | | || result.OverallResult != BuildResultCode.Success) {
|
| | | Messages.Print(string.Format("{0}: background build FAILED!",
|
| | | Path.GetFileName(UnconfiguredProject.FullPath)));
|
| | | } else {
|
| | | var checkResults = result.ResultsByTarget
|
| | | .Where(x => Targets.Contains(x.Key))
|
| | | .Select(x => x.Value);
|
| | | ok = checkResults.Any()
|
| | | && checkResults.All(x => x.ResultCode == TargetResultCode.Success);
|
| | | if (ok)
|
| | | msBuildProject.MarkDirty();
|
| | | }
|
| | | await writeAccess.ReleaseAsync();
|
| | | return ok;
|
| | | }
|
| | |
|
| | | async Task BuildAsync()
|
| | | {
|
| | | if (LoggerVerbosity != LoggerVerbosity.Quiet) {
|
| | |
| | | * Properties: {1}
|
| | | * Targets: {2}
|
| | | ",
|
| | | /*{0}*/ Project.Name,
|
| | | /*{0}*/ Path.GetFileNameWithoutExtension(UnconfiguredProject.FullPath),
|
| | | /*{1}*/ string.Join("", Properties
|
| | | .Select(property => string.Format(@"
|
| | | {0} = {1}", /*{0}*/ property.Key, /*{1}*/ property.Value))),
|
| | |
| | |
|
| | | bool ok = false;
|
| | | try {
|
| | | ProjectWriteLockReleaser writeAccess;
|
| | | var timer = ConcurrentStopwatch.StartNew();
|
| | | while (timer.IsRunning) {
|
| | | try {
|
| | | writeAccess = await lockService.WriteLockAsync();
|
| | | #if VS2017
|
| | | using (var writeAccess = await lockService.WriteLockAsync())
|
| | | ok = await BuildProjectAsync(writeAccess);
|
| | | #else
|
| | | await lockService.WriteLockAsync(
|
| | | async (ProjectWriteLockReleaser writeAccess) =>
|
| | | {
|
| | | ok = await BuildProjectAsync(writeAccess);
|
| | | });
|
| | | #endif
|
| | | timer.Stop();
|
| | | } catch (InvalidOperationException) {
|
| | | if (timer.ElapsedMilliseconds >= 5000)
|
| | | throw;
|
| | | #if VS2017
|
| | | using (var readAccess = await lockService.ReadLockAsync())
|
| | | await readAccess.ReleaseAsync();
|
| | | #else
|
| | | await lockService.ReadLockAsync(
|
| | | async (ProjectLockReleaser readAccess) =>
|
| | | {
|
| | | await readAccess.ReleaseAsync();
|
| | | });
|
| | | #endif
|
| | | }
|
| | | }
|
| | |
|
| | | using (writeAccess) {
|
| | | var msBuildProject = await writeAccess.GetProjectAsync(ConfiguredProject);
|
| | |
|
| | | var solutionPath = QtProjectTracker.SolutionPath;
|
| | | var configProps = new Dictionary<string, string>(
|
| | | ConfiguredProject.ProjectConfiguration.Dimensions.ToImmutableDictionary())
|
| | | {
|
| | | { "SolutionPath", solutionPath },
|
| | | { "SolutionFileName", Path.GetFileName(solutionPath) },
|
| | | { "SolutionName", Path.GetFileNameWithoutExtension(solutionPath) },
|
| | | { "SolutionExt", Path.GetExtension(solutionPath) },
|
| | | { "SolutionDir", Path.GetDirectoryName(solutionPath).TrimEnd('\\') + '\\' }
|
| | | };
|
| | |
|
| | | foreach (var property in Properties)
|
| | | configProps[property.Key] = property.Value;
|
| | |
|
| | | var projectInstance = new ProjectInstance(msBuildProject.Xml,
|
| | | configProps, null, new ProjectCollection());
|
| | |
|
| | | var loggerVerbosity = LoggerVerbosity;
|
| | | if (QtVsToolsPackage.Instance.Options.BuildDebugInformation)
|
| | | loggerVerbosity = QtVsToolsPackage.Instance.Options.BuildLoggerVerbosity;
|
| | | var buildParams = new BuildParameters()
|
| | | {
|
| | | Loggers = (loggerVerbosity != LoggerVerbosity.Quiet)
|
| | | ? new[] { new QtProjectLogger() { Verbosity = loggerVerbosity } }
|
| | | : null
|
| | | };
|
| | |
|
| | | var buildRequest = new BuildRequestData(projectInstance,
|
| | | Targets.ToArray(),
|
| | | hostServices: null,
|
| | | flags: BuildRequestDataFlags.ProvideProjectStateAfterBuild);
|
| | |
|
| | | if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
|
| | | Messages.Print(string.Format(
|
| | | "{0:HH:mm:ss.FFF} QtProjectBuild({1}): Build [{2}] {3}",
|
| | | DateTime.Now, Thread.CurrentThread.ManagedThreadId,
|
| | | ConfiguredProject.ProjectConfiguration.Name,
|
| | | UnconfiguredProject.FullPath));
|
| | | Messages.Print("=== Targets");
|
| | | foreach (var target in buildRequest.TargetNames)
|
| | | Messages.Print(string.Format(" {0}", target));
|
| | | Messages.Print("=== Properties");
|
| | | foreach (var property in Properties) {
|
| | | Messages.Print(string.Format(" {0}={1}",
|
| | | property.Key, property.Value));
|
| | | }
|
| | | }
|
| | |
|
| | | BuildResult result = null;
|
| | | while (result == null) {
|
| | | try {
|
| | | result = BuildManager.DefaultBuildManager.Build(
|
| | | buildParams, buildRequest);
|
| | | } catch (InvalidOperationException) {
|
| | | if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
|
| | | Messages.Print(string.Format(
|
| | | "{0:HH:mm:ss.FFF} QtProjectBuild({1}): [{2}] "
|
| | | + "Warning: Another build is in progress; waiting...",
|
| | | DateTime.Now,
|
| | | Thread.CurrentThread.ManagedThreadId,
|
| | | ConfiguredProject.ProjectConfiguration.Name));
|
| | | }
|
| | | await Task.Delay(3000);
|
| | | }
|
| | | }
|
| | |
|
| | | if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
|
| | | string resMsg;
|
| | | StringBuilder resInfo = new StringBuilder();
|
| | | if (result?.OverallResult == BuildResultCode.Success) {
|
| | | resMsg = "Build ok";
|
| | | } else {
|
| | | resMsg = "Build FAIL";
|
| | | if (result == null) {
|
| | | resInfo.AppendLine("####### Build returned 'null'");
|
| | | } else {
|
| | | resInfo.AppendLine("####### Build returned 'Failure' code");
|
| | | if (result.ResultsByTarget != null) {
|
| | | foreach (var tr in result.ResultsByTarget) {
|
| | | var res = tr.Value;
|
| | | if (res.ResultCode != TargetResultCode.Failure)
|
| | | continue;
|
| | | resInfo.AppendFormat("### Target '{0}' FAIL\r\n", tr.Key);
|
| | | if (res.Items != null && res.Items.Length > 0) {
|
| | | resInfo.AppendFormat(
|
| | | "Items: {0}\r\n", string.Join(", ", res.Items
|
| | | .Select(it => it.ItemSpec)));
|
| | | }
|
| | | var e = tr.Value?.Exception;
|
| | | if (e != null) {
|
| | | resInfo.AppendFormat(
|
| | | "Exception: {0}\r\nStacktrace:\r\n{1}\r\n",
|
| | | e.Message, e.StackTrace);
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | | Messages.Print(string.Format(
|
| | | "{0:HH:mm:ss.FFF} QtProjectBuild({1}): [{2}] {3}\r\n{4}",
|
| | | DateTime.Now, Thread.CurrentThread.ManagedThreadId,
|
| | | ConfiguredProject.ProjectConfiguration.Name,
|
| | | resMsg, resInfo.ToString()));
|
| | | }
|
| | |
|
| | | if (result == null
|
| | | || result.ResultsByTarget == null
|
| | | || result.OverallResult != BuildResultCode.Success) {
|
| | | Messages.Print(string.Format("{0}: background build FAILED!",
|
| | | Path.GetFileName(UnconfiguredProject.FullPath)));
|
| | | } else {
|
| | | var checkResults = result.ResultsByTarget
|
| | | .Where(x => Targets.Contains(x.Key))
|
| | | .Select(x => x.Value);
|
| | | ok = checkResults.Any()
|
| | | && checkResults.All(x => x.ResultCode == TargetResultCode.Success);
|
| | | if (ok)
|
| | | msBuildProject.MarkDirty();
|
| | | }
|
| | | await writeAccess.ReleaseAsync();
|
| | | }
|
| | |
|
| | | if (ok) {
|
| | | var vcProject = Project.Object as VCProject;
|
| | | var vcConfigs = vcProject.Configurations as IVCCollection;
|
| | | var vcConfigs = VcProject.Configurations as IVCCollection;
|
| | | var vcConfig = vcConfigs.Item(ConfiguredProject.ProjectConfiguration.Name) as VCConfiguration;
|
| | | var props = vcConfig.Rules.Item("QtRule10_Settings") as IVCRulePropertyStorage;
|
| | | props.SetPropertyValue("QtLastBackgroundBuild", DateTime.UtcNow.ToString("o"));
|
| | | props?.SetPropertyValue("QtLastBackgroundBuild", DateTime.UtcNow.ToString("o"));
|
| | | }
|
| | | } catch (Exception e) {
|
| | | Messages.Print(string.Format("{0}: background build ERROR: {1}",
|
| | |
| | | Messages.Print(string.Format(
|
| | | @"
|
| | | == {0}: build {1}",
|
| | | Project.Name, ok ? "successful" : "ERROR"));
|
| | | Path.GetFileNameWithoutExtension(UnconfiguredProject.FullPath),
|
| | | ok ? "successful" : "ERROR"));
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | using System.Linq;
|
| | | using System.Threading.Tasks;
|
| | | using Microsoft.Build.Framework;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Threading;
|
| | |
|
| | | using Task = System.Threading.Tasks.Task;
|
| | | using Thread = System.Threading.Thread;
|
| | |
|
| | | namespace QtVsTools.QtMsBuild
|
| | | {
|
| | | using Core;
|
| | | using Thread = System.Threading.Thread;
|
| | |
|
| | | static class QtProjectIntellisense
|
| | | {
|
| | |
| | | string configId = null,
|
| | | IEnumerable<string> selectedFiles = null)
|
| | | {
|
| | | if (project == null || !QtProjectTracker.IsTracked(project))
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (project == null || !QtProjectTracker.IsTracked(project.FullName))
|
| | | return;
|
| | |
|
| | | if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
|
| | | Messages.Print(string.Format(
|
| | | "{0:HH:mm:ss.FFF} QtProjectIntellisense({1}): Refreshing: [{2}] {3}",
|
| | | DateTime.Now, Thread.CurrentThread.ManagedThreadId,
|
| | | (configId != null) ? configId : "(all configs)", project.FullName));
|
| | | }
|
| | | Task.Run(() => RefreshAsync(project, configId, selectedFiles));
|
| | | string projectPath = project.FullName;
|
| | | _ = Task.Run(() => RefreshAsync(project, projectPath, configId, selectedFiles, false));
|
| | | }
|
| | |
|
| | | public static async Task RefreshAsync(
|
| | | EnvDTE.Project project,
|
| | | string projectPath,
|
| | | string configId = null,
|
| | | IEnumerable<string> selectedFiles = null)
|
| | | IEnumerable<string> selectedFiles = null,
|
| | | bool refreshQtVars = false)
|
| | | {
|
| | | if (project == null || !QtProjectTracker.IsTracked(project))
|
| | | if (project == null || !QtProjectTracker.IsTracked(projectPath))
|
| | | return;
|
| | | var tracker = QtProjectTracker.Get(project);
|
| | | var tracker = QtProjectTracker.Get(project, projectPath);
|
| | | await tracker.Initialized;
|
| | |
|
| | | var properties = new Dictionary<string, string>();
|
| | |
| | | }
|
| | |
|
| | | foreach (var config in configs) {
|
| | | await QtProjectBuild.StartBuildAsync(
|
| | | project, config, properties, targets,
|
| | | LoggerVerbosity.Quiet);
|
| | | if (refreshQtVars) {
|
| | | await QtProjectBuild.StartBuildAsync(
|
| | | project, projectPath, config, properties, targets,
|
| | | LoggerVerbosity.Quiet);
|
| | | } else {
|
| | | await QtProjectBuild.SetOutdatedAsync(
|
| | | project, projectPath, config, LoggerVerbosity.Quiet);
|
| | | }
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | using System;
|
| | | using System.Collections.Concurrent;
|
| | | using System.Collections.Generic;
|
| | | using System.IO;
|
| | | using System.Linq;
|
| | | using System.Threading;
|
| | | using System.Threading.Tasks;
|
| | | using System.Threading.Tasks.Dataflow;
|
| | | using Microsoft.Build.Evaluation;
|
| | | using Microsoft.Build.Framework;
|
| | | using Microsoft.VisualStudio.ProjectSystem;
|
| | | using Microsoft.VisualStudio.ProjectSystem.Properties;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.TaskStatusCenter;
|
| | | using Microsoft.VisualStudio.Threading;
|
| | | using EnvDTE;
|
| | | using Microsoft.VisualStudio.VCProjectEngine;
|
| | |
|
| | | using Task = System.Threading.Tasks.Task;
|
| | |
|
| | | namespace QtVsTools.QtMsBuild
|
| | | {
|
| | | using Common;
|
| | | using Core;
|
| | | using VisualStudio;
|
| | | using Thread = System.Threading.Thread;
|
| | |
|
| | | using SubscriberAction = ActionBlock<IProjectVersionedValue<IProjectSubscriptionUpdate>>;
|
| | |
|
| | | class QtProjectTracker : Concurrent<QtProjectTracker>
|
| | | {
|
| | | static ConcurrentDictionary<string, QtProjectTracker> _Instances;
|
| | | static ConcurrentDictionary<string, QtProjectTracker> Instances =>
|
| | | StaticThreadSafeInit(() => _Instances, () =>
|
| | | _Instances = new ConcurrentDictionary<string, QtProjectTracker>());
|
| | | static LazyFactory StaticLazy { get; } = new LazyFactory();
|
| | |
|
| | | static PunisherQueue<QtProjectTracker> _InitQueue;
|
| | | static PunisherQueue<QtProjectTracker> InitQueue =>
|
| | | StaticThreadSafeInit(() => _InitQueue, () =>
|
| | | _InitQueue = new PunisherQueue<QtProjectTracker>());
|
| | | static ConcurrentDictionary<string, QtProjectTracker> Instances => StaticLazy.Get(() =>
|
| | | Instances, () => new ConcurrentDictionary<string, QtProjectTracker>());
|
| | |
|
| | | static IVsTaskStatusCenterService _StatusCenter;
|
| | | static IVsTaskStatusCenterService StatusCenter => StaticThreadSafeInit(() => _StatusCenter,
|
| | | () => _StatusCenter = VsServiceProvider
|
| | | .GetService<SVsTaskStatusCenterService, IVsTaskStatusCenterService>());
|
| | | static PunisherQueue<QtProjectTracker> InitQueue => StaticLazy.Get(() =>
|
| | | InitQueue, () => new PunisherQueue<QtProjectTracker>());
|
| | |
|
| | | static IVsTaskStatusCenterService StatusCenter => StaticLazy.Get(() =>
|
| | | StatusCenter, () => VsServiceProvider
|
| | | .GetService<SVsTaskStatusCenterService, IVsTaskStatusCenterService>());
|
| | |
|
| | | static Task InitDispatcher { get; set; }
|
| | | static ITaskHandler2 InitStatus { get; set; }
|
| | |
| | | Initialized = new EventWaitHandle(false, EventResetMode.ManualReset);
|
| | | }
|
| | |
|
| | | class Subscriber : IDisposable
|
| | | {
|
| | | public Subscriber(QtProjectTracker tracker, ConfiguredProject config)
|
| | | {
|
| | | Tracker = tracker;
|
| | | Config = config;
|
| | | Subscription = Config.Services.ProjectSubscription.JointRuleSource.SourceBlock
|
| | | .LinkTo(new SubscriberAction(ProjectUpdateAsync),
|
| | | ruleNames: new[]
|
| | | {
|
| | | "ClCompile",
|
| | | "QtRule10_Settings",
|
| | | "QtRule30_Moc",
|
| | | "QtRule40_Rcc",
|
| | | "QtRule60_Repc",
|
| | | "QtRule50_Uic",
|
| | | "QtRule_Translation",
|
| | | "QtRule70_Deploy",
|
| | | },
|
| | | initialDataAsNew: false
|
| | | );
|
| | | }
|
| | |
|
| | | QtProjectTracker Tracker { get; set; }
|
| | | ConfiguredProject Config { get; set; }
|
| | | IDisposable Subscription { get; set; }
|
| | |
|
| | | public void Dispose()
|
| | | {
|
| | | Subscription?.Dispose();
|
| | | Subscription = null;
|
| | | }
|
| | |
|
| | | async Task ProjectUpdateAsync(IProjectVersionedValue<IProjectSubscriptionUpdate> update)
|
| | | {
|
| | | await Tracker.OnProjectUpdateAsync(Config, update.Value);
|
| | | }
|
| | | }
|
| | |
|
| | | public EnvDTE.Project Project { get; private set; }
|
| | | public string ProjectPath { get; private set; }
|
| | | public VCProject VcProject { get; private set; }
|
| | | public UnconfiguredProject UnconfiguredProject { get; private set; }
|
| | | public EventWaitHandle Initialized { get; private set; }
|
| | | List<Subscriber> Subscribers { get; set; }
|
| | | public EventWaitHandle Initialized { get; }
|
| | |
|
| | | public static bool IsTracked(EnvDTE.Project project)
|
| | | public static bool IsTracked(string projectPath)
|
| | | {
|
| | | return Instances.ContainsKey(project.FullName);
|
| | | return Instances.ContainsKey(projectPath);
|
| | | }
|
| | |
|
| | | public static void Add(EnvDTE.Project project)
|
| | | {
|
| | | if (!QtVsToolsPackage.Instance.Options.ProjectTracking)
|
| | | return;
|
| | | Get(project);
|
| | |
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | Get(project, project.FullName);
|
| | | }
|
| | |
|
| | | public static QtProjectTracker Get(EnvDTE.Project project)
|
| | | public static QtProjectTracker Get(EnvDTE.Project project, string projectPath)
|
| | | {
|
| | | lock (StaticCriticalSection) {
|
| | | QtProjectTracker tracker = null;
|
| | | if (Instances.TryGetValue(project.FullName, out tracker))
|
| | | if (Instances.TryGetValue(projectPath, out QtProjectTracker tracker))
|
| | | return tracker;
|
| | | tracker = new QtProjectTracker
|
| | | {
|
| | | Project = project,
|
| | | ProjectPath = projectPath
|
| | | };
|
| | | Instances[project.FullName] = tracker;
|
| | | Instances[projectPath] = tracker;
|
| | | InitQueue.Enqueue(tracker);
|
| | | if (InitDispatcher == null)
|
| | | InitDispatcher = Task.Run(InitDispatcherLoopAsync);
|
| | |
| | | while (!QtVsToolsPackage.Instance.Zombied) {
|
| | | while (InitQueue.IsEmpty)
|
| | | await Task.Delay(100);
|
| | | QtProjectTracker tracker;
|
| | | if (InitQueue.TryDequeue(out tracker)) {
|
| | | if (InitQueue.TryDequeue(out QtProjectTracker tracker)) {
|
| | | if (InitStatus == null) {
|
| | | await QtVsToolsPackage.Instance.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | await QtVsToolsPackage.Instance.JoinableTaskFactory
|
| | | .SwitchToMainThreadAsync();
|
| | | tracker.BeginInitStatus();
|
| | | await TaskScheduler.Default;
|
| | | } else {
|
| | | await QtVsToolsPackage.Instance.JoinableTaskFactory
|
| | | .SwitchToMainThreadAsync();
|
| | | tracker.UpdateInitStatus(0);
|
| | | await TaskScheduler.Default;
|
| | | }
|
| | | await tracker.InitializeAsync();
|
| | | }
|
| | |
| | | async Task InitializeAsync()
|
| | | {
|
| | | int p = 0;
|
| | | await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | UpdateInitStatus(p += 10);
|
| | |
|
| | | await QtVsToolsPackage.Instance.JoinableTaskFactory.SwitchToMainThreadAsync();
|
| | | VcProject = Project.Object as VCProject;
|
| | | if (VcProject == null)
|
| | | return;
|
| | | UpdateInitStatus(p += 10);
|
| | |
|
| | | var context = Project.Object as IVsBrowseObjectContext;
|
| | |
| | |
|
| | | Initialized.Set();
|
| | |
|
| | | Subscribers = new List<Subscriber>();
|
| | | int n = configs.Count;
|
| | | int d = (100 - p) / (n * 2);
|
| | | foreach (var config in configs) {
|
| | | var configProject = await UnconfiguredProject.LoadConfiguredProjectAsync(config);
|
| | | UpdateInitStatus(p += d);
|
| | | Subscribers.Add(new Subscriber(this, configProject));
|
| | | configProject.ProjectUnloading += OnProjectUnloading;
|
| | | configProject.ProjectUnloading += OnProjectUnloadingAsync;
|
| | | if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
|
| | | Messages.Print(string.Format(
|
| | | "{0:HH:mm:ss.FFF} QtProjectTracker({1}): Started tracking [{2}] {3}",
|
| | | DateTime.Now, Thread.CurrentThread.ManagedThreadId,
|
| | | config.Name,
|
| | | UnconfiguredProject.FullPath));
|
| | | config.Name, ProjectPath));
|
| | | }
|
| | | UpdateInitStatus(p += d);
|
| | | }
|
| | | }
|
| | |
|
| | |
|
| | | async Task OnProjectUpdateAsync(ConfiguredProject config, IProjectSubscriptionUpdate update)
|
| | | {
|
| | | var changes = update.ProjectChanges.Values
|
| | | .Where(x => x.Difference.AnyChanges)
|
| | | .Select(x => x.Difference);
|
| | | var changesCount = changes
|
| | | .Select(x => x.AddedItems.Count
|
| | | + x.ChangedItems.Count
|
| | | + x.ChangedProperties.Count
|
| | | + x.RemovedItems.Count
|
| | | + x.RenamedItems.Count)
|
| | | .Sum();
|
| | | var changedProps = changes.SelectMany(x => x.ChangedProperties);
|
| | | if (changesCount == 0
|
| | | || (changesCount == 1
|
| | | && changedProps.Count() == 1
|
| | | && changedProps.First() == "QtLastBackgroundBuild")) {
|
| | | return;
|
| | | }
|
| | |
|
| | | if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) {
|
| | | Messages.Print(string.Format(
|
| | | "{0:HH:mm:ss.FFF} QtProjectTracker({1}): Changed [{2}] {3}",
|
| | | DateTime.Now, Thread.CurrentThread.ManagedThreadId,
|
| | | config.ProjectConfiguration.Name,
|
| | | config.UnconfiguredProject.FullPath));
|
| | | }
|
| | | await QtProjectIntellisense.RefreshAsync(Project, config.ProjectConfiguration.Name);
|
| | | }
|
| | |
|
| | | async Task OnProjectUnloading(object sender, EventArgs args)
|
| | | async Task OnProjectUnloadingAsync(object sender, EventArgs args)
|
| | | {
|
| | | var project = sender as ConfiguredProject;
|
| | | if (project == null || project.Services == null)
|
| | |
| | | project.UnconfiguredProject.FullPath));
|
| | | }
|
| | | lock (CriticalSection) {
|
| | | if (Subscribers != null) {
|
| | | Subscribers.ForEach(s => s.Dispose());
|
| | | Subscribers.Clear();
|
| | | Subscribers = null;
|
| | | }
|
| | | project.ProjectUnloading -= OnProjectUnloading;
|
| | | Instances.TryRemove(Project.FullName, out QtProjectTracker tracker);
|
| | | project.ProjectUnloading -= OnProjectUnloadingAsync;
|
| | | Instances.TryRemove(project.UnconfiguredProject.FullPath, out QtProjectTracker _);
|
| | | }
|
| | | await Task.Yield();
|
| | | }
|
| | |
|
| | | void BeginInitStatus()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | lock (StaticCriticalSection) {
|
| | | if (InitStatus != null)
|
| | | return;
|
| | |
| | | PercentComplete = 0
|
| | | })
|
| | | as ITaskHandler2;
|
| | | } catch (Exception e) {
|
| | | Messages.Print(
|
| | | e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | }
|
| | | InitStatus.RegisterTask(new Task(() => throw new InvalidOperationException()));
|
| | | }
|
| | |
| | | InitStatus.Progress.Report(new TaskProgressData
|
| | | {
|
| | | ProgressText = string.Format("{0} ({1} project(s) remaining)",
|
| | | Project.Name, InitQueue.Count),
|
| | | Path.GetFileNameWithoutExtension(ProjectPath), InitQueue.Count),
|
| | | CanBeCanceled = true,
|
| | | PercentComplete = percentComplete
|
| | | });
|
| | | } catch (Exception e) {
|
| | | Messages.Print(
|
| | | e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | |
|
| | | public async Task<ICollection<IEnumValue>> GetListedValuesAsync()
|
| | | {
|
| | | List<IEnumValue> values = new List<IEnumValue>();
|
| | | using (var qtVersions = Registry.CurrentUser.OpenSubKey(@"Software\Digia\Versions")) {
|
| | |
|
| | | return await Task.FromResult(
|
New file |
| | |
| | | [$RootKey$\ShellFileAssociations\.prf]
|
| | | "DefaultIconMoniker"="0d2e443f-6dbb-4001-99dc-9cd7d5c924e7:0"
|
| | |
|
| | | [$RootKey$\ShellFileAssociations\.pri]
|
| | | "DefaultIconMoniker"="0d2e443f-6dbb-4001-99dc-9cd7d5c924e7:1"
|
| | |
|
| | | [$RootKey$\ShellFileAssociations\.pro]
|
| | | "DefaultIconMoniker"="0d2e443f-6dbb-4001-99dc-9cd7d5c924e7:2"
|
| | |
|
| | | [$RootKey$\ShellFileAssociations\.qml]
|
| | | "DefaultIconMoniker"="0d2e443f-6dbb-4001-99dc-9cd7d5c924e7:3"
|
| | |
|
| | | [$RootKey$\ShellFileAssociations\.qrc]
|
| | | "DefaultIconMoniker"="0d2e443f-6dbb-4001-99dc-9cd7d5c924e7:4"
|
| | |
|
| | | [$RootKey$\ShellFileAssociations\.ts]
|
| | | "DefaultIconMoniker"="0d2e443f-6dbb-4001-99dc-9cd7d5c924e7:5"
|
| | |
|
| | | [$RootKey$\ShellFileAssociations\.ui]
|
| | | "DefaultIconMoniker"="0d2e443f-6dbb-4001-99dc-9cd7d5c924e7:6"
|
| | |
| | | <Reference Include="System.Data" />
|
| | | <Reference Include="System.Design" />
|
| | | <Reference Include="System.Drawing" />
|
| | | <Reference Include="System.ComponentModel.Composition" />
|
| | | <Reference Include="System.Xaml" />
|
| | | <Reference Include="PresentationCore" />
|
| | | <Reference Include="PresentationFramework" />
|
| | | <Reference Include="WindowsBase" />
|
| | | <Reference Include="Microsoft.VisualStudio.ProjectSystem">
|
| | | <HintPath>$(VsInstallRoot)\Common7\IDE\CommonExtensions\Microsoft\Project\Microsoft.VisualStudio.ProjectSystem.dll</HintPath>
|
| | | </Reference>
|
| | | <Reference Include="Microsoft.VisualStudio.Composition">
|
| | | <HintPath>$(VsInstallRoot)\Common7\IDE\PrivateAssemblies\Microsoft.VisualStudio.Composition.dll</HintPath>
|
| | | </Reference>
|
| | | </ItemGroup>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Version specific references
|
| | | // General package references
|
| | | // -->
|
| | | <Import Project="$(SolutionDir)\references.props" />
|
| | | <ItemGroup>
|
| | | <PackageReference Include="System.ComponentModel.Composition"
|
| | | Version="$(Version_System_ComponentModel_Composition)" />
|
| | | <PackageReference Include="Stub.System.Data.SQLite.Core.NetFramework"
|
| | | Version="$(Version_Stub_System_Data_SQLite_Core_NetFramework)"
|
| | | GeneratePathProperty="true" />
|
| | | <PackageReference Include="Newtonsoft.Json"
|
| | | Version="$(Version_Newtonsoft_Json)" />
|
| | | <PackageReference Include="Microsoft.Build"
|
| | | Version="$(Version_Microsoft_Build)" />
|
| | | <PackageReference Include="Microsoft.Build.Framework"
|
| | | Version="$(Version_Microsoft_Build_Framework)" />
|
| | | <PackageReference Include="Microsoft.Build.Tasks.Core"
|
| | | Version="$(Version_Microsoft_Build_Tasks_Core)" />
|
| | | <PackageReference Include="Microsoft.VisualStudio.SDK"
|
| | | Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
|
| | | <PackageReference Include="Microsoft.VSSDK.BuildTools"
|
| | | Version="$(Version_Microsoft_VSSDK_BuildTools)" />
|
| | | <PackageReference Include="Microsoft.VisualStudio.Shell.Framework"
|
| | | Version="$(Version_Microsoft_VisualStudio_Shell_Framework)" />
|
| | | <PackageReference Include="Microsoft.VisualStudio.Validation"
|
| | | Version="$(Version_Microsoft_VisualStudio_Validation)" />
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_Threading)"
|
| | | Version="$(Version_Microsoft_VisualStudio_Threading)" />
|
| | | <PackageReference Include="System.Collections.Immutable"
|
| | | Version="$(Version_System_Collections_Immutable)" />
|
| | | <PackageReference Include="$(Name_Microsoft_VSSDK_BuildTools)" Version="$(Version_Microsoft_VSSDK_BuildTools)" />
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_SDK)" Version="$(Version_Microsoft_VisualStudio_SDK)" ExcludeAssets="runtime" />
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_ProjectSystem)" Version="$(Version_Microsoft_VisualStudio_ProjectSystem)" />
|
| | | <PackageReference Include="$(Name_Newtonsoft_Json)" Version="$(Version_Newtonsoft_Json)" />
|
| | | <PackageReference Include="$(Name_Stub_System_Data_SQLite_Core_NetFramework)" Version="$(Version_Stub_System_Data_SQLite_Core_NetFramework)" GeneratePathProperty="true" />
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_Shell_15)" Version="$(Version_Microsoft_VisualStudio_Shell_15)" />
|
| | | </ItemGroup>
|
| | | <ItemGroup Condition="'$(VisualStudioVersion)'=='17.0'">
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)"
|
| | | Version="$(Version_Microsoft_VisualStudio_VCProjectEngine)" />
|
| | | </ItemGroup>
|
| | | <ItemGroup Condition="'$(VisualStudioVersion)'=='16.0'">
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)"
|
| | | Version="$(Version_Microsoft_VisualStudio_VCProjectEngine)" />
|
| | | </ItemGroup>
|
| | | <ItemGroup Condition="'$(VisualStudioVersion)'=='15.0'">
|
| | | <Reference Include="Microsoft.VisualStudio.VCProjectEngine" />
|
| | | </ItemGroup>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Version specific package references
|
| | | // -->
|
| | | <Choose>
|
| | | <When Condition="'$(VisualStudioVersion)'=='17.0'">
|
| | | <ItemGroup>
|
| | | </ItemGroup>
|
| | | </When>
|
| | | <When Condition="'$(VisualStudioVersion)'=='16.0'">
|
| | | <ItemGroup>
|
| | | </ItemGroup>
|
| | | </When>
|
| | | <When Condition="'$(VisualStudioVersion)'=='15.0'">
|
| | | <ItemGroup>
|
| | | <Reference Include="$(Name_Microsoft_VisualStudio_VCProjectEngine)" />
|
| | | <PackageReference Include="$(Name_Microsoft_VisualStudio_Shell_Framework)" Version="$(Version_Microsoft_VisualStudio_Shell_Framework)" />
|
| | | </ItemGroup>
|
| | | </When>
|
| | | </Choose>
|
| | | <!--
|
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // Solution project references
|
| | |
| | | <Project>{4cee73c9-fcfa-3a72-a0a3-036bdbb3240f}</Project>
|
| | | <Name>qrceditor</Name>
|
| | | <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
| | | </ProjectReference>
|
| | | <ProjectReference Include="..\Templates\qtclass\QtTemplate.Item.QtClass.csproj">
|
| | | <Project>{4981AAE8-9AC7-4758-87EA-FB2397D6C404}</Project>
|
| | | <Name>QtTemplate.Item.QtClass</Name>
|
| | | <VSIXSubPath>ItemTemplates</VSIXSubPath>
|
| | | <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
| | | <IncludeOutputGroupsInVSIX>TemplateProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
|
| | | </ProjectReference>
|
| | | <ProjectReference Include="..\Templates\translation\QtTemplate.Item.Translation.csproj">
|
| | | <Project>{202F4A6D-77CD-4992-AA53-01B585463287}</Project>
|
| | | <Name>QtTemplate.Item.Translation</Name>
|
| | | <VSIXSubPath>ItemTemplates</VSIXSubPath>
|
| | | <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
| | | <IncludeOutputGroupsInVSIX>TemplateProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
|
| | | </ProjectReference>
|
| | | <ProjectReference Include="..\Templates\widgetsclass\QtTemplate.Item.WidgetsClass.csproj">
|
| | | <Project>{020422DA-33AB-4495-A439-7DAC2690795C}</Project>
|
| | | <Name>QtTemplate.Item.WidgetsClass</Name>
|
| | | <VSIXSubPath>ItemTemplates</VSIXSubPath>
|
| | | <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
| | | <IncludeOutputGroupsInVSIX>TemplateProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
|
| | | </ProjectReference>
|
| | | <ProjectReference Include="..\vsqml\vsqml.vcxproj">
|
| | | <Project>{b12702ad-abfb-343a-a199-8e24837244a3}</Project>
|
| | |
| | | <DependsOn>$(SolutionDir)\version.targets;$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
|
| | | <LastGenOutput>AssemblyInfo.tt.cs</LastGenOutput>
|
| | | </T4Template>
|
| | | <Compile Include="Legacy\ProjectQtSettings.cs" />
|
| | | <Compile Include="Legacy\QtMenu.cs" />
|
| | | <Compile Include="Legacy\QtOptionsPage.cs">
|
| | | <SubType>Component</SubType>
|
| | | </Compile>
|
| | | <Compile Include="Legacy\Translation.cs" />
|
| | | <Compile Include="Properties\AssemblyInfo.tt.cs">
|
| | | <AutoGen>True</AutoGen>
|
| | | <DesignTime>True</DesignTime>
|
| | |
| | | <DesignTime>True</DesignTime>
|
| | | <DependentUpon>QtMenus.vsct_TT</DependentUpon>
|
| | | </VSCTCompile>
|
| | | <Content Include="Resources\Vsix.ico" />
|
| | | <EmbeddedResource Include="VSPackage.resx">
|
| | | <MergeWithCTO>true</MergeWithCTO>
|
| | | <ManifestResourceName>VSPackage</ManifestResourceName>
|
| | | </EmbeddedResource>
|
| | | <Compile Include="Package\AddTranslationDialog.cs">
|
| | | <SubType>Form</SubType>
|
| | | </Compile>
|
| | | <Compile Include="Package\ChangeFor.cs" />
|
| | | <Compile Include="Legacy\ChangeFor.cs" />
|
| | | <Compile Include="Common\Concurrent.cs" />
|
| | | <Compile Include="Common\ConcurrentStopwatch.cs" />
|
| | | <Compile Include="Common\Disposable.cs" />
|
| | |
| | | <Compile Include="Editors\Editor.QtLinguist.cs" />
|
| | | <Compile Include="Editors\Editor.QtResourceEditor.cs" />
|
| | | <Compile Include="Package\ExtLoader.cs" />
|
| | | <Compile Include="Package\FormChangeQtVersion.cs">
|
| | | <Compile Include="Legacy\FormChangeQtVersion.cs">
|
| | | <SubType>Form</SubType>
|
| | | </Compile>
|
| | | <Compile Include="Package\FormChangeQtVersion.Designer.cs">
|
| | | <Compile Include="Legacy\FormChangeQtVersion.Designer.cs">
|
| | | <DependentUpon>FormChangeQtVersion.cs</DependentUpon>
|
| | | </Compile>
|
| | | <Compile Include="Package\FormProjectQtSettings.cs">
|
| | | <Compile Include="Legacy\FormProjectQtSettings.cs">
|
| | | <SubType>Form</SubType>
|
| | | </Compile>
|
| | | <Compile Include="Package\FormProjectQtSettings.Designer.cs">
|
| | | <Compile Include="Legacy\FormProjectQtSettings.Designer.cs">
|
| | | <DependentUpon>FormProjectQtSettings.cs</DependentUpon>
|
| | | </Compile>
|
| | | <Compile Include="Options\QtLegacyOptionsPage.cs">
|
| | | <SubType>Component</SubType>
|
| | | </Compile>
|
| | | <Compile Include="Options\QtOptionsPage.cs">
|
| | | <SubType>Component</SubType>
|
| | |
| | | <Compile Include="Options\QtVersionsPage.cs">
|
| | | <SubType>Component</SubType>
|
| | | </Compile>
|
| | | <Compile Include="Package\ProjectQtSettings.cs" />
|
| | | <Compile Include="Package\QMakeWrapper.cs" />
|
| | | <Compile Include="QML\Classification\QmlAsyncClassifier.cs" />
|
| | | <Compile Include="QML\Classification\QmlClassificationFormat.cs" />
|
| | |
| | | <Compile Include="Package\QtSolutionContextMenu.cs" />
|
| | | <Compile Include="Package\SR.cs" />
|
| | | <Compile Include="Package\Translation.cs" />
|
| | | <Compile Include="Package\TranslationItem.cs" />
|
| | | <Compile Include="VisualStudio\VsShell.cs" />
|
| | | <Compile Include="Common\VsToolsDialogWindow.cs" />
|
| | | <Compile Include="Package\Notifications.cs" />
|
| | | <Content Include="..\Changelog">
|
| | | <Link>Changelog</Link>
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | |
| | | <DependsOn>$(SolutionDir)\version.targets;$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
|
| | | <LastGenOutput>source.extension.vsixmanifest</LastGenOutput>
|
| | | </T4Template>
|
| | | <Content Include="Icons\Monikers.imagemanifest">
|
| | | <IncludeInVSIX>true</IncludeInVSIX>
|
| | | </Content>
|
| | | <None Include="source.extension.vsixmanifest">
|
| | | <DependentUpon>source.extension.vsixmanifest_TT</DependentUpon>
|
| | | <SubType>Designer</SubType>
|
| | |
| | | <DependsOn>$(SolutionDir)\version.targets;$(SolutionDir)\version.tt;$(SolutionDir)\common.tt</DependsOn>
|
| | | <LastGenOutput>Overview.html</LastGenOutput>
|
| | | </T4Template>
|
| | | <Content Include="QtVsTools.Icons.pkgdef">
|
| | | <IncludeInVSIX>true</IncludeInVSIX>
|
| | | </Content>
|
| | | <Resource Include="Icons\prf32.png" />
|
| | | <Resource Include="Icons\pri32.png" />
|
| | | <Resource Include="Icons\pro32.png" />
|
| | | <Resource Include="Icons\qml32.png" />
|
| | | <Resource Include="Icons\qrc32.png" />
|
| | | <Resource Include="Icons\ts32.png" />
|
| | | <Resource Include="Icons\ui32.png" />
|
| | | <Content Include="Marketplace\Overview.html">
|
| | | <AutoGen>True</AutoGen>
|
| | | <DesignTime>True</DesignTime>
|
| | |
| | | <IncludeInVSIX>true</IncludeInVSIX>
|
| | | <SubType>Designer</SubType>
|
| | | </Content>
|
| | | <Content Include="qt6modules.xml">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <IncludeInVSIX>true</IncludeInVSIX>
|
| | | </Content>
|
| | | <Content Include="QtVsTools.ico" />
|
| | | <Content Include="QtVsTools.Qml.Debug.pkgdef">
|
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | |
| | | <CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
| | | <IncludeInVSIX>true</IncludeInVSIX>
|
| | | </Content>
|
| | | <EmbeddedResource Include="Package\AddTranslationDialog.resx">
|
| | | <DependentUpon>AddTranslationDialog.cs</DependentUpon>
|
| | | </EmbeddedResource>
|
| | | <EmbeddedResource Include="Package\FormChangeQtVersion.resx">
|
| | | <EmbeddedResource Include="Legacy\FormChangeQtVersion.resx">
|
| | | <DependentUpon>FormChangeQtVersion.cs</DependentUpon>
|
| | | </EmbeddedResource>
|
| | | <EmbeddedResource Include="Package\FormProjectQtSettings.resx">
|
| | | <EmbeddedResource Include="Legacy\FormProjectQtSettings.resx">
|
| | | <DependentUpon>FormProjectQtSettings.cs</DependentUpon>
|
| | | <SubType>Designer</SubType>
|
| | | </EmbeddedResource>
|
| | | <EmbeddedResource Include="Resources.resx">
|
| | | <SubType>Designer</SubType>
|
| | |
| | | </Page>
|
| | | </ItemGroup>
|
| | | <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
| | | <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
|
| | | <Import Project="$(SolutionDir)\transform.targets" />
|
| | | <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
|
| | | <Target Name="QtVsTools_PostBuild" AfterTargets="Build">
|
| | | <Error Condition="!Exists('$(TargetPath)')" Text="Build failed." />
|
| | | <PropertyGroup>
|
| | |
| | | /////////////////////////////////////////////////////////////////////////////////////////////////
|
| | | // NuGet native libs
|
| | | // -->
|
| | | <PropertyGroup
|
| | | Condition="'$(PkgStub_System_Data_SQLite_Core_NetFramework)' != ''">
|
| | | <SQLitePkgDir Condition="'$(SQLitePkgDir)' == ''"
|
| | | >$(PkgStub_System_Data_SQLite_Core_NetFramework)</SQLitePkgDir>
|
| | | <PropertyGroup Condition="'$(PkgStub_System_Data_SQLite_Core_NetFramework)' != ''">
|
| | | <SQLitePkgDir Condition="'$(SQLitePkgDir)' == ''">$(PkgStub_System_Data_SQLite_Core_NetFramework)</SQLitePkgDir>
|
| | | </PropertyGroup>
|
| | | <PropertyGroup
|
| | | Condition="'$(PkgStub_System_Data_SQLite_Core_NetFramework)' == ''">
|
| | | <NuGetGlobalPkgDir Condition="'$(NuGetGlobalPkgDir)' == ''"
|
| | | >$(USERPROFILE)\.nuget\packages</NuGetGlobalPkgDir>
|
| | | <SQLitePkgRoot
|
| | | >$(NuGetGlobalPkgDir)\Stub.System.Data.SQLite.Core.NetFramework</SQLitePkgRoot>
|
| | | <SQLitePkgDir Condition="'$(SQLitePkgDir)' == ''"
|
| | | >$(SQLitePkgRoot)\$(Version_Stub_System_Data_SQLite_Core_NetFramework)</SQLitePkgDir>
|
| | | <PropertyGroup Condition="'$(PkgStub_System_Data_SQLite_Core_NetFramework)' == ''">
|
| | | <NuGetGlobalPkgDir Condition="'$(NuGetGlobalPkgDir)' == ''">$(USERPROFILE)\.nuget\packages</NuGetGlobalPkgDir>
|
| | | <SQLitePkgRoot>$(NuGetGlobalPkgDir)\Stub.System.Data.SQLite.Core.NetFramework</SQLitePkgRoot>
|
| | | <SQLitePkgDir Condition="'$(SQLitePkgDir)' == ''">$(SQLitePkgRoot)\$(Version_Stub_System_Data_SQLite_Core_NetFramework)</SQLitePkgDir>
|
| | | </PropertyGroup>
|
| | | <ItemGroup>
|
| | | <Content Include="$(SQLitePkgDir)\build\net46\x64\SQLite.Interop.dll">
|
| | |
| | | ****************************************************************************/
|
| | |
|
| | | using System;
|
| | | using System.ComponentModel.Design;
|
| | | using System.Diagnostics;
|
| | | using System.Diagnostics.CodeAnalysis;
|
| | | using System.Globalization;
|
| | | using System.IO;
|
| | | using System.Linq;
|
| | | using System.Net.Http;
|
| | | using System.Runtime.InteropServices;
|
| | | using System.Threading;
|
| | | using System.Threading.Tasks;
|
| | | using Task = System.Threading.Tasks.Task;
|
| | | using System.Windows.Forms;
|
| | | using Microsoft.VisualStudio;
|
| | | using Microsoft.VisualStudio.OLE.Interop;
|
| | | using Microsoft.VisualStudio.Settings;
|
| | | using Microsoft.VisualStudio.Shell;
|
| | | using Microsoft.VisualStudio.Shell.Interop;
|
| | |
| | | using Microsoft.Win32;
|
| | | using EnvDTE;
|
| | |
|
| | | using Task = System.Threading.Tasks.Task;
|
| | |
|
| | | namespace QtVsTools
|
| | | {
|
| | | using Core;
|
| | | using QtMsBuild;
|
| | | using SyntaxAnalysis;
|
| | | using static SyntaxAnalysis.RegExpr;
|
| | | using VisualStudio;
|
| | |
|
| | | using static SyntaxAnalysis.RegExpr;
|
| | |
|
| | | [Guid(QtVsToolsPackage.PackageGuidString)]
|
| | | [InstalledProductRegistration("#110", "#112", Version.PRODUCT_VERSION, IconResourceID = 400)]
|
| | |
| | | "Qt", "Versions", 0, 0, true, Sort = 1)]
|
| | |
|
| | | // Legacy options page
|
| | | [ProvideOptionPage(typeof(Options.QtLegacyOptionsPage),
|
| | | [ProvideOptionPage(typeof(Legacy.QtOptionsPage),
|
| | | "Qt", "Legacy Project Format", 0, 0, true, Sort = 2)]
|
| | |
|
| | | public sealed class QtVsToolsPackage : AsyncPackage, IVsServiceProvider, IProjectTracker
|
| | |
| | | public string PkgInstallPath { get; private set; }
|
| | | public Options.QtOptionsPage Options
|
| | | => GetDialogPage(typeof(Options.QtOptionsPage)) as Options.QtOptionsPage;
|
| | | public Options.QtLegacyOptionsPage LegacyOptions
|
| | | => GetDialogPage(typeof(Options.QtLegacyOptionsPage)) as Options.QtLegacyOptionsPage;
|
| | | public Legacy.QtOptionsPage LegacyOptions
|
| | | => GetDialogPage(typeof(Legacy.QtOptionsPage)) as Legacy.QtOptionsPage;
|
| | | public Editors.QtDesigner QtDesigner { get; private set; }
|
| | | public Editors.QtLinguist QtLinguist { get; private set; }
|
| | | public Editors.QtResourceEditor QtResourceEditor { get; private set; }
|
| | | private Editors.QtResourceEditor QtResourceEditor { get; set; }
|
| | |
|
| | | static EventWaitHandle initDone = new EventWaitHandle(false, EventResetMode.ManualReset);
|
| | | static readonly EventWaitHandle initDone = new EventWaitHandle(false, EventResetMode.ManualReset);
|
| | |
|
| | | static QtVsToolsPackage instance = null;
|
| | | public static QtVsToolsPackage Instance
|
| | |
| | | var timeInitBegin = initTimer.Elapsed;
|
| | | VsServiceProvider.Instance = instance = this;
|
| | | QtProject.ProjectTracker = this;
|
| | | Messages.JoinableTaskFactory = JoinableTaskFactory;
|
| | |
|
| | | // determine the package installation directory
|
| | | var uri = new Uri(System.Reflection.Assembly
|
| | |
| | | await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
|
| | | var timeUiThreadBegin = initTimer.Elapsed;
|
| | |
|
| | | if ((Dte = VsServiceProvider.GetService<DTE>()) == null)
|
| | | if ((Dte = await VsServiceProvider.GetServiceAsync<DTE>()) == null)
|
| | | throw new Exception("Unable to get service: DTE");
|
| | |
|
| | | QtVSIPSettings.Options = Options;
|
| | |
| | | eventHandler = new DteEventsHandler(Dte);
|
| | |
|
| | | Qml.Debug.Launcher.Initialize();
|
| | | QtMainMenu.Initialize(this);
|
| | | QtSolutionContextMenu.Initialize(this);
|
| | | QtProjectContextMenu.Initialize(this);
|
| | | QtItemContextMenu.Initialize(this);
|
| | | QtMainMenu.Initialize();
|
| | | QtSolutionContextMenu.Initialize();
|
| | | QtProjectContextMenu.Initialize();
|
| | | QtItemContextMenu.Initialize();
|
| | | RegisterEditorFactory(QtDesigner = new Editors.QtDesigner());
|
| | | RegisterEditorFactory(QtLinguist = new Editors.QtLinguist());
|
| | | RegisterEditorFactory(QtResourceEditor = new Editors.QtResourceEditor());
|
| | | QtHelp.Initialize(this);
|
| | | QtHelp.Initialize();
|
| | |
|
| | | if (!string.IsNullOrEmpty(VsShell.InstallRootDir))
|
| | | HelperFunctions.VCPath = Path.Combine(VsShell.InstallRootDir, "VC");
|
| | |
| | | var timeUiThreadEnd = initTimer.Elapsed;
|
| | |
|
| | | var vm = QtVersionManager.The(initDone);
|
| | | var error = string.Empty;
|
| | | if (vm.HasInvalidVersions(out error))
|
| | | if (vm.HasInvalidVersions(out string error, out bool defaultInvalid)) {
|
| | | if (defaultInvalid)
|
| | | vm.SetLatestQtVersionAsDefault();
|
| | | Messages.Print(error);
|
| | | }
|
| | |
|
| | | ///////////
|
| | | // Install Qt/MSBuild files from package folder to standard location
|
| | |
| | | ================================================================",
|
| | | urlDownloadQtIo, devRelease));
|
| | | }
|
| | | } catch (Exception e) {
|
| | | Messages.Print(
|
| | | e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | } finally {
|
| | | initDone.Set();
|
| | | initTimer.Stop();
|
| | |
| | | eventHandler.SolutionEvents_Opened();
|
| | | }
|
| | |
|
| | | bool TestVersionInstalled()
|
| | | {
|
| | | bool newVersion = false;
|
| | | string versionFile = Path.Combine(PkgInstallPath, "lastversion.txt");
|
| | | if (File.Exists(versionFile)) {
|
| | | string lastVersion = File.ReadAllText(versionFile);
|
| | | newVersion = (lastVersion!= Version.PRODUCT_VERSION);
|
| | | } else {
|
| | | newVersion = true;
|
| | | }
|
| | | if (newVersion)
|
| | | File.WriteAllText(versionFile, Version.PRODUCT_VERSION);
|
| | | return newVersion;
|
| | | }
|
| | |
|
| | | public void VsMainWindowActivated()
|
| | | {
|
| | | if (QtVersionManager.The().GetVersions()?.Length == 0)
|
| | | Notifications.NoQtVersion.Show();
|
| | | if (Options.NotifyInstalled && TestVersionInstalled())
|
| | | Notifications.NotifyInstall.Show();
|
| | | }
|
| | |
|
| | | protected override int QueryClose(out bool canClose)
|
| | | {
|
| | | if (eventHandler != null) {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | if (eventHandler != null)
|
| | | eventHandler.Disconnect();
|
| | | }
|
| | | return base.QueryClose(out canClose);
|
| | | }
|
| | |
|
| | |
| | |
|
| | | File.WriteAllText(Path.Combine(visualizersPath, natvisFile),
|
| | | natvis, System.Text.Encoding.UTF8);
|
| | | } catch (Exception e) {
|
| | | Messages.Print(
|
| | | e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
|
| | | } catch (Exception exception) {
|
| | | exception.Log();
|
| | | }
|
| | | }
|
| | |
|
| | | public string GetNatvisPath()
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | |
|
| | | try {
|
| | | using (var vsRootKey = Registry.CurrentUser.OpenSubKey(Dte.RegistryRoot)) {
|
| | | if (vsRootKey.GetValue("VisualStudioLocation") is string vsLocation)
|
| | |
| | |
|
| | | void IProjectTracker.AddProject(Project project)
|
| | | {
|
| | | ThreadHelper.ThrowIfNotOnUIThread();
|
| | | QtProjectTracker.Add(project);
|
| | | }
|
| | |
|
| | |
| | | <resheader name="writer">
|
| | | <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
| | | </resheader>
|
| | | <data name="ActionDialog_Properties" xml:space="preserve">
|
| | | <value>Properties</value>
|
| | | </data>
|
| | | <data name="AddQtVersionDialog_IncorrectMakefileGenerator" xml:space="preserve">
|
| | | <value>This Qt version uses an unsupported makefile generator (used: {0}, supported: MSVC.NET, MSBUILD)</value>
|
| | | </data>
|
| | | <data name="AddTranslationDialog_FileName" xml:space="preserve">
|
| | | <value>Filename:</value>
|
| | | </data>
|
| | | <data name="AddTranslationDialog_Language" xml:space="preserve">
|
| | | <value>Language:</value>
|
| | | </data>
|
| | | <data name="AddTranslationDialog_Title" xml:space="preserve">
|
| | | <value>Add Translation</value>
|
| | | </data>
|
| | | <data name="Cancel" xml:space="preserve">
|
| | | <value>&Cancel</value>
|
| | | </data>
|
| | | <data name="CannotFindQMake" xml:space="preserve">
|
| | | <value>Cannot find qmake. Make sure you have specified a Qt version.</value>
|
| | | </data>
|
| | |
| | | <data name="ImportPriFileNotResolved" xml:space="preserve">
|
| | | <value>--- (importing .pri file) file: {0} cannot be resolved. Skipping file.</value>
|
| | | </data>
|
| | | <data name="InstalledQtVersions" xml:space="preserve">
|
| | | <value>Installed Qt Versions</value>
|
| | | </data>
|
| | | <data name="NoProjectOpened" xml:space="preserve">
|
| | | <value>No Project Opened</value>
|
| | | </data>
|
| | | <data name="OK" xml:space="preserve">
|
| | | <value>&OK</value>
|
| | | </data>
|
| | | <data name="IncompatibleMacros" xml:space="preserve">
|
| | | <value>The following macros are not compatible: {0}</value>
|
| | | </data>
|
| | | <data name="ProjectQtSettingsButtonText" xml:space="preserve">
|
| | | <value>Qt Project Settings</value>
|
| | | </data>
|
| | | <data name="ProjectQtVersion" xml:space="preserve">
|
| | | <value>Set Project's Qt Version</value>
|
| | | </data>
|
| | | <data name="ProjectQtVersionNotFoundError" xml:space="preserve">
|
| | | <value>There's no Qt version assigned to project {0} for configuration {1}/{2}. Please use the 'Qt Project Settings' editor to change the 'Version' to a valid Qt version for this platform.</value>
|
| | | </data>
|
| | | <data name="QtModules" xml:space="preserve">
|
| | | <value>Qt Modules</value>
|
| | | </data>
|
| | | <data name="SolutionQtVersion" xml:space="preserve">
|
| | | <value>Set Solution's Qt Version</value>
|
| | | </data>
|
| | | <data name="ExportProject_ImportPriFile" xml:space="preserve">
|
| | | <value>Import from .pri File</value>
|
| | |
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QString">
|
| | | <DisplayString>{((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),sub}</DisplayString>
|
| | | <StringView>((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),sub</StringView>
|
| | | <DisplayString>{((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),sub}</DisplayString>
|
| | | <StringView>((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),sub</StringView>
|
| | | <Expand>
|
| | | <Item Name="[size]">d->size</Item>
|
| | | <Item Name="[referenced]">d->ref.atomic._q_value</Item>
|
| | | <ArrayItems>
|
| | | <Size>d->size</Size>
|
| | | <ValuePointer>((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),c</ValuePointer>
|
| | | <ValuePointer>((reinterpret_cast<unsigned short*>(d)) + d->offset / 2),c</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QStringRef">
|
| | | <Intrinsic Name="offset" Expression="(reinterpret_cast<char16_t*>(m_string->d))
|
| | | + m_string->d->offset / 2" />
|
| | | <DisplayString Condition="m_string == nullptr">{m_string,[m_size]} u""</DisplayString>
|
| | | <DisplayString Condition="m_string != nullptr">{offset() + m_position,[m_size]}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[position]" ExcludeView="simple">m_position</Item>
|
| | | <Item Name="[size]" ExcludeView="simple">m_size</Item>
|
| | | <ArrayItems Condition="m_string != nullptr">
|
| | | <Size>m_size</Size>
|
| | | <ValuePointer>offset()+m_position</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QStringView">
|
| | | <DisplayString>{m_data,[m_size]}</DisplayString>
|
| | | <StringView>m_data,[m_size]</StringView>
|
| | | <Expand>
|
| | | <Item Name="[size]" ExcludeView="simple">m_size</Item>
|
| | | <ArrayItems>
|
| | | <Size>m_size</Size>
|
| | | <ValuePointer>m_data</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
| | | <Intrinsic Name="query" Expression="*((QString*)(((char*)(d) + memberOffset(5))))" />
|
| | | <Intrinsic Name="fragment" Expression="*((QString*)(((char*)(d) + memberOffset(6))))" />
|
| | |
|
| | | <DisplayString Condition="!isEmpty(scheme().d->size)">{scheme()}://{host()}{path()}</DisplayString>
|
| | | <DisplayString Condition="isEmpty(scheme().d->size)">{path()}</DisplayString>
|
| | | <DisplayString Condition="!isEmpty(scheme().d->size)">{scheme()}://{host()}{path()}</DisplayString>
|
| | | <DisplayString Condition="isEmpty(scheme().d->size)">{path()}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[scheme]">scheme()</Item>
|
| | | <Item Name="[username]">username()</Item>
|
| | |
| | | <IndexListItems>
|
| | | <Size>d->end - d->begin</Size>
|
| | | <ValueNode>*reinterpret_cast<$T1*>((sizeof($T1) > sizeof(void*))
|
| | | ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
|
| | | : reinterpret_cast<$T1*>(d->array + d->begin + $i))
|
| | | ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
|
| | | : reinterpret_cast<$T1*>(d->array + d->begin + $i))
|
| | | </ValueNode>
|
| | | </IndexListItems>
|
| | | </Expand>
|
| | |
| | | <Size>d->end - d->begin</Size>
|
| | | <ValueNode>
|
| | | *reinterpret_cast<QString*>((sizeof(QString) > sizeof(void*))
|
| | | ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
|
| | | : reinterpret_cast<QString*>(d->array + d->begin + $i))
|
| | | ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
|
| | | : reinterpret_cast<QString*>(d->array + d->begin + $i))
|
| | | </ValueNode>
|
| | | </IndexListItems>
|
| | | </Expand>
|
| | |
| | | <Size>d->end - d->begin</Size>
|
| | | <ValueNode>
|
| | | *reinterpret_cast<QVariant*>((sizeof(QVariant) > sizeof(void*))
|
| | | ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
|
| | | : reinterpret_cast<QVariant*>(d->array + d->begin + $i))
|
| | | ? reinterpret_cast<Node*>(d->array + d->begin + $i)->v
|
| | | : reinterpret_cast<QVariant*>(d->array + d->begin + $i))
|
| | | </ValueNode>
|
| | | </IndexListItems>
|
| | | </Expand>
|
| | |
| | | <Exec>node = *(bucket++)</Exec>
|
| | | <Exec>--n</Exec>
|
| | | <Loop>
|
| | | <Break Condition="!node || !node->next"/>
|
| | | <Break Condition="!node || !node->next"/>
|
| | | <Exec>keyValuePair = reinterpret_cast<Node *>(node)</Exec>
|
| | | <Item Name="[{keyValuePair->key}]">keyValuePair->value</Item>
|
| | | <Exec>node = node->next</Exec>
|
| | |
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QByteArray">
|
| | | <Type Name="##NAMESPACE##::QStringRef">
|
| | | <DisplayString Condition="m_string == nullptr">{m_string,[m_size]} u""</DisplayString>
|
| | | <DisplayString Condition="m_string != nullptr">{m_string->d.ptr+m_position,[m_size]}</DisplayString>
|
| | | <StringView Condition="m_string == nullptr">""</StringView>
|
| | | <StringView Condition="m_string != nullptr">m_string,[m_position+m_size]</StringView>
|
| | | <Expand>
|
| | | <Item Name="[position]" ExcludeView="simple">m_position</Item>
|
| | | <Item Name="[size]" ExcludeView="simple">m_size</Item>
|
| | | <ArrayItems Condition="m_string != nullptr">
|
| | | <Size>m_size</Size>
|
| | | <ValuePointer>m_string->d.ptr+m_position</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QStringView">
|
| | | <DisplayString>{m_data,[m_size]}</DisplayString>
|
| | | <StringView>m_data,[m_size]</StringView>
|
| | | <Expand>
|
| | | <Item Name="[size]" ExcludeView="simple">m_size</Item>
|
| | | <ArrayItems>
|
| | | <Size>m_size</Size>
|
| | | <ValuePointer>m_data</ValuePointer>
|
| | | </ArrayItems>
|
| | | </Expand>
|
| | | </Type>
|
| | |
|
| | | <Type Name="##NAMESPACE##::QByteArray">
|
| | | <DisplayString>"{((reinterpret_cast<char*>(d.ptr))),sb}"</DisplayString>
|
| | | <StringView>((reinterpret_cast<char*>(d.ptr))),sb</StringView>
|
| | | <Expand>
|
| | |
| | | <Intrinsic Name="query" Expression="*((QString*)(((char*)(d) + memberOffset(5))))" />
|
| | | <Intrinsic Name="fragment" Expression="*((QString*)(((char*)(d) + memberOffset(6))))" />
|
| | |
|
| | | <DisplayString Condition="!isEmpty(scheme().d->size)">{scheme()}://{host()}{path()}</DisplayString>
|
| | | <DisplayString Condition="isEmpty(scheme().d->size)">{path()}</DisplayString>
|
| | | <DisplayString Condition="!isEmpty(scheme().d->size)">{scheme()}://{host()}{path()}</DisplayString>
|
| | | <DisplayString Condition="isEmpty(scheme().d->size)">{path()}</DisplayString>
|
| | | <Expand>
|
| | | <Item Name="[scheme]">scheme()</Item>
|
| | | <Item Name="[username]">username()</Item>
|
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?>
|
| | | <QtVsTools>
|
| | |
|
| | | <!-- Qt Essentials -->
|
| | |
|
| | | <Module Id="1">
|
| | | <Name>Qt Core</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtCore</LibraryPrefix>
|
| | | <proVarQT>core</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtCore</IncludePath>
|
| | | <Defines>QT_CORE_LIB</Defines>
|
| | | <Tag>Essential</Tag>
|
| | | </Module>
|
| | | <Module Id="2">
|
| | | <Name>Qt D-Bus</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtDBus</LibraryPrefix>
|
| | | <proVarQT>dbus</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtDBus</IncludePath>
|
| | | <Defines>QT_DBUS_LIB</Defines>
|
| | | <Tag>Essential</Tag>
|
| | | </Module>
|
| | | <Module Id="3">
|
| | | <Name>Qt GUI</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtGui</LibraryPrefix>
|
| | | <proVarQT>gui</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtGui</IncludePath>
|
| | | <Defines>QT_GUI_LIB</Defines>
|
| | | <Tag>Essential</Tag>
|
| | | </Module>
|
| | | <Module Id="4">
|
| | | <Name>Qt Network</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtNetwork</LibraryPrefix>
|
| | | <proVarQT>network</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtNetwork</IncludePath>
|
| | | <Defines>QT_NETWORK_LIB</Defines>
|
| | | <Tag>Essential</Tag>
|
| | | </Module>
|
| | | <Module Id="5">
|
| | | <Name>Qt QML</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtQml</LibraryPrefix>
|
| | | <proVarQT>qml</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtQml</IncludePath>
|
| | | <Defines>QT_QML_LIB</Defines>
|
| | | <Tag>Essential</Tag>
|
| | | </Module>
|
| | | <Module Id="6">
|
| | | <Name>Qt Quick</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtQuick</LibraryPrefix>
|
| | | <proVarQT>quick</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtQuick</IncludePath>
|
| | | <Defines>QT_QUICK_LIB</Defines>
|
| | | <Tag>Essential</Tag>
|
| | | </Module>
|
| | | <Module Id="7">
|
| | | <Name>Qt Quick Controls</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtQuickControls2</LibraryPrefix>
|
| | | <proVarQT>quickcontrols2</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtQuickControls2</IncludePath>
|
| | | <Defines>QT_QUICKCONTROLS2_LIB</Defines>
|
| | | <Tag>Essential</Tag>
|
| | | </Module>
|
| | | <Module Id="8">
|
| | | <Name>Qt Quick Dialogs</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtQuickDialogs2</LibraryPrefix>
|
| | | <proVarQT>quickdialogs2</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtQuickDialogs2</IncludePath>
|
| | | <Defines>QT_QUICKDIALOGS2_LIB</Defines>
|
| | | <Tag>Essential</Tag>
|
| | | </Module>
|
| | | <Module Id="9">
|
| | | <Name>Qt Quick Layouts</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtQuickLayouts</LibraryPrefix>
|
| | | <proVarQT>quicklayouts</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtQuickLayouts</IncludePath>
|
| | | <Defines>QT_QUICKLAYOUTS_LIB</Defines>
|
| | | <Tag>Essential</Tag>
|
| | | </Module>
|
| | | <Module Id="10">
|
| | | <Name>Qt Quick Test</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtQuickTest</LibraryPrefix>
|
| | | <proVarQT>qmltest</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtQuickTest</IncludePath>
|
| | | <Defines>QT_QMLTEST_LIB</Defines>
|
| | | <Tag>Essential</Tag>
|
| | | </Module>
|
| | | <Module Id="11">
|
| | | <Name>Qt Test</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtTest</LibraryPrefix>
|
| | | <proVarQT>testlib</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtTest</IncludePath>
|
| | | <Defines>QT_TESTLIB_LIB</Defines>
|
| | | <Tag>Essential</Tag>
|
| | | </Module>
|
| | | <Module Id="12">
|
| | | <Name>Qt Widgets</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtWidgets</LibraryPrefix>
|
| | | <proVarQT>widgets</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtWidgets</IncludePath>
|
| | | <Defines>QT_WIDGETS_LIB</Defines>
|
| | | <Tag>Essential</Tag>
|
| | | </Module>
|
| | |
|
| | | <!-- Qt Add-Ons-->
|
| | |
|
| | | <Module Id="13">
|
| | | <Name>Active Qt (Server)</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtAxServer</LibraryPrefix>
|
| | | <proVarQT>axserver</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\ActiveQt</IncludePath>
|
| | | <Defines>QAXSERVER</Defines>
|
| | | <Defines>QT_AXSERVER_LIB</Defines>
|
| | | <AdditionalLibraries>Qt6AxBase.lib</AdditionalLibraries>
|
| | | <AdditionalLibrariesDebug>Qt6AxBased.lib</AdditionalLibrariesDebug>
|
| | | </Module>
|
| | | <Module Id="14">
|
| | | <Name>Active Qt (Container)</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtAxContainer</LibraryPrefix>
|
| | | <proVarQT>axcontainer</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\ActiveQt</IncludePath>
|
| | | <Defines>QT_AXCONTAINER_LIB</Defines>
|
| | | <AdditionalLibraries>Qt6AxBase.lib</AdditionalLibraries>
|
| | | <AdditionalLibrariesDebug>Qt6AxBased.lib</AdditionalLibrariesDebug>
|
| | | </Module>
|
| | | <Module Id="15">
|
| | | <Name>Qt Bluetooth</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtBluetooth</LibraryPrefix>
|
| | | <proVarQT>bluetooth</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtBluetooth</IncludePath>
|
| | | <Defines>QT_BLUETOOTH_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="16">
|
| | | <Name>Qt 3D</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>Qt3DCore</LibraryPrefix>
|
| | | <proVarQT>3dcore 3danimation 3dextras 3dinput 3dlogic 3drender</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\Qt3DCore</IncludePath>
|
| | | <IncludePath>$(QTDIR)\include\Qt3DAnimation</IncludePath>
|
| | | <IncludePath>$(QTDIR)\include\Qt3DExtras</IncludePath>
|
| | | <IncludePath>$(QTDIR)\include\Qt3DInput</IncludePath>
|
| | | <IncludePath>$(QTDIR)\include\Qt3DLogic</IncludePath>
|
| | | <IncludePath>$(QTDIR)\include\Qt3DRender</IncludePath>
|
| | | <Defines>QT_3DCORE_LIB</Defines>
|
| | | <Defines>QT_3DANIMATION_LIB</Defines>
|
| | | <Defines>QT_3DEXTRAS_LIB</Defines>
|
| | | <Defines>QT_3DINPUT_LIB</Defines>
|
| | | <Defines>QT_3DLOGIC_LIB</Defines>
|
| | | <Defines>QT_3DRENDER_LIB</Defines>
|
| | | <AdditionalLibraries>Qt63DCore.lib</AdditionalLibraries>
|
| | | <AdditionalLibraries>Qt63DAnimation.lib</AdditionalLibraries>
|
| | | <AdditionalLibraries>Qt63DExtras.lib</AdditionalLibraries>
|
| | | <AdditionalLibraries>Qt63DInput.lib</AdditionalLibraries>
|
| | | <AdditionalLibraries>Qt63DLogic.lib</AdditionalLibraries>
|
| | | <AdditionalLibraries>Qt63DRender.lib</AdditionalLibraries>
|
| | | <AdditionalLibrariesDebug>Qt63DCored.lib</AdditionalLibrariesDebug>
|
| | | <AdditionalLibrariesDebug>Qt63DAnimationd.lib</AdditionalLibrariesDebug>
|
| | | <AdditionalLibrariesDebug>Qt63DExtrasd.lib</AdditionalLibrariesDebug>
|
| | | <AdditionalLibrariesDebug>Qt63DInputd.lib</AdditionalLibrariesDebug>
|
| | | <AdditionalLibrariesDebug>Qt63DLogicd.lib</AdditionalLibrariesDebug>
|
| | | <AdditionalLibrariesDebug>Qt63DRenderd.lib</AdditionalLibrariesDebug>
|
| | | </Module>
|
| | | <Module Id="17">
|
| | | <Name>Qt 5 Core Compatibility APIs</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtCore5Compat</LibraryPrefix>
|
| | | <proVarQT>core5compat</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtCore5Compat</IncludePath>
|
| | | <Defines>QT_CORE5COMPAT_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="18"> <!-- TODO: Split? -->
|
| | | <Name>Qt for Automation</Name>
|
| | | <proVarQT>coap mqtt opcua</proVarQT>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtCoap</LibraryPrefix>
|
| | | <AdditionalLibraries>Qt6Coap.lib</AdditionalLibraries>
|
| | | <AdditionalLibraries>Qt6Coapd.lib</AdditionalLibraries>
|
| | | <AdditionalLibraries>Qt6Mqtt.lib</AdditionalLibraries>
|
| | | <AdditionalLibraries>Qt6Mqttd.lib</AdditionalLibraries>
|
| | | <AdditionalLibraries>Qt6OpcUa.lib</AdditionalLibraries>
|
| | | <AdditionalLibraries>Qt6OpcUad.lib</AdditionalLibraries>
|
| | | </Module>
|
| | | <Module Id="19">
|
| | | <Name>Qt Concurrent</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtConcurrent</LibraryPrefix>
|
| | | <proVarQT>concurrent</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtConcurrent</IncludePath>
|
| | | <Defines>QT_CONCURRENT_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="20">
|
| | | <Name>Qt Help</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtHelp</LibraryPrefix>
|
| | | <proVarQT>help</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtHelp</IncludePath>
|
| | | <Defines>QT_HELP_LIB</Defines>
|
| | | </Module>
|
| | | <!--
|
| | | Image formats
|
| | | -->
|
| | | <Module Id="21">
|
| | | <Name>Qt OpenGL</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtOpenGL</LibraryPrefix>
|
| | | <proVarQT>opengl</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtOpenGL</IncludePath>
|
| | | <Defines>QT_OPENGL_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="22">
|
| | | <Name>Qt Multimedia</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtMultimedia</LibraryPrefix>
|
| | | <proVarQT>multimedia</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtMultimedia</IncludePath>
|
| | | <Defines>QT_MULTIMEDIA_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="23">
|
| | | <Name>Qt Print Support</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtPrintSupport</LibraryPrefix>
|
| | | <proVarQT>printsupport</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtPrintSupport</IncludePath>
|
| | | <Defines>QT_PRINTSUPPORT_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="24">
|
| | | <Name>Qt Quick Widgets</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtQuickWidgets</LibraryPrefix>
|
| | | <proVarQT>quickwidgets</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtQuickWidgets</IncludePath>
|
| | | <Defines>QT_QUICKWIDGETS_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="25">
|
| | | <Name>Qt Remote Objects</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtRemoteObjects</LibraryPrefix>
|
| | | <proVarQT>remoteobjects</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtRemoteObjects</IncludePath>
|
| | | <Defines>QT_REMOTEOBJECTS_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="26">
|
| | | <Name>Qt SCXML</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtScxml</LibraryPrefix>
|
| | | <proVarQT>scxml</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtScxml</IncludePath>
|
| | | <Defines>QT_SCXML_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="27">
|
| | | <Name>Qt Sensors</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtSensors</LibraryPrefix>
|
| | | <proVarQT>sensors</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtSensors</IncludePath>
|
| | | <Defines>QT_SENSORS_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="28">
|
| | | <Name>Qt Serial Bus</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtSerialBus</LibraryPrefix>
|
| | | <proVarQT>serialbus</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtSerialBus</IncludePath>
|
| | | <Defines>QT_SERIALBUS_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="29">
|
| | | <Name>Qt Serial Port</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtSerialPort</LibraryPrefix>
|
| | | <proVarQT>serialport</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtSerialPort</IncludePath>
|
| | | <Defines>QT_SERIALPORT_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="30">
|
| | | <Name>Qt SQL</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtSql</LibraryPrefix>
|
| | | <proVarQT>sql</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtSql</IncludePath>
|
| | | <Defines>QT_SQL_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="31">
|
| | | <Name>Qt State Machine</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtStateMachine</LibraryPrefix>
|
| | | <proVarQT>statemachine</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtStateMachine</IncludePath>
|
| | | <Defines>QT_STATEMACHINE_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="32">
|
| | | <Name>Qt SVG</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtSvg</LibraryPrefix>
|
| | | <proVarQT>svg</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtSvg</IncludePath>
|
| | | <Defines>QT_SVG_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="34">
|
| | | <Name>Qt WebChannel</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtWebChannel</LibraryPrefix>
|
| | | <proVarQT>webchannel</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtWebChannel</IncludePath>
|
| | | <Defines>QT_WEBCHANNEL_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="35">
|
| | | <Name>Qt WebEngine</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtWebEngine</LibraryPrefix>
|
| | | <proVarQT>webenginecore</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtWebEngineCore</IncludePath>
|
| | | <Defines>QT_WEBENGINECORE_LIB</Defines>
|
| | | <AdditionalLibraries>Qt6WebEngine.lib</AdditionalLibraries>
|
| | | <AdditionalLibraries>Qt6WebEngineCore.lib</AdditionalLibraries>
|
| | | <AdditionalLibrariesDebug>Qt6WebEngined.lib</AdditionalLibrariesDebug>
|
| | | <AdditionalLibrariesDebug>Qt6WebEngineCored.lib</AdditionalLibrariesDebug>
|
| | | </Module>
|
| | | <Module Id="36">
|
| | | <Name>Qt WebSockets</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtWebSockets</LibraryPrefix>
|
| | | <proVarQT>websockets</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtWebSockets</IncludePath>
|
| | | <Defines>QT_WEBSOCKETS_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="37">
|
| | | <Name>WebView</Name>
|
| | | <proVarQT>webview</proVarQT>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtWebView</LibraryPrefix>
|
| | | </Module>
|
| | | <Module Id="38">
|
| | | <Name>Qt XML</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtXml</LibraryPrefix>
|
| | | <proVarQT>xml</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtXml</IncludePath>
|
| | | <Defines>QT_XML_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="39">
|
| | | <Name>Qt Positioning</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtPositioning</LibraryPrefix>
|
| | | <proVarQT>positioning</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtPositioning</IncludePath>
|
| | | <Defines>QT_POSITIONING_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="40">
|
| | | <Name>Qt NFC</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtNfc</LibraryPrefix>
|
| | | <proVarQT>nfc</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtNfc</IncludePath>
|
| | | <Defines>QT_NFC_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="41">
|
| | | <Name>Qt Charts</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtCharts</LibraryPrefix>
|
| | | <proVarQT>charts</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtCharts</IncludePath>
|
| | | <Defines>QT_CHARTS_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="42">
|
| | | <Name>Qt Data Visualization</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtDataVisualization</LibraryPrefix>
|
| | | <proVarQT>datavisualization</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtDataVisualization</IncludePath>
|
| | | <Defines>QT_DATAVISUALIZATION_LIB</Defines>
|
| | | </Module>
|
| | | <!--
|
| | | lottie
|
| | | -->
|
| | | <Module Id="44">
|
| | | <Name>Qt Network Authorization</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtNetworkAuth</LibraryPrefix>
|
| | | <proVarQT>networkauth</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtNetworkAuth</IncludePath>
|
| | | <Defines>QT_NETWORKAUTH_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="45">
|
| | | <Name>Qt Virtual Keyboard</Name>
|
| | | <proVarQT>virtualkeyboard</proVarQT>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtVirtualKeyboard</LibraryPrefix>
|
| | | </Module>
|
| | | <Module Id="46">
|
| | | <Name>Qt Quick 3D</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>Qt3DQuick</LibraryPrefix>
|
| | | <proVarQT>3dquick</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\Qt3DQuick</IncludePath>
|
| | | <IncludePath>$(QTDIR)\include\Qt3DQuickAnimation</IncludePath>
|
| | | <IncludePath>$(QTDIR)\include\Qt3DQuickExtras</IncludePath>
|
| | | <IncludePath>$(QTDIR)\include\Qt3DQuickInput</IncludePath>
|
| | | <IncludePath>$(QTDIR)\include\Qt3DQuickRender</IncludePath>
|
| | | <IncludePath>$(QTDIR)\include\Qt3DQuickScene2D</IncludePath>
|
| | | <Defines>QT_3DQUICK_LIB</Defines>
|
| | | <Defines>QT_3DQUICKANIMATION_LIB</Defines>
|
| | | <Defines>QT_3DQUICKEXTRAS_LIB</Defines>
|
| | | <Defines>QT_3DQUICKINPUT_LIB</Defines>
|
| | | <Defines>QT_3DQUICKRENDER_LIB</Defines>
|
| | | <Defines>QT_3DQUICKSCENE2D_LIB</Defines>
|
| | | <AdditionalLibraries>Qt63DQuick.lib</AdditionalLibraries>
|
| | | <AdditionalLibraries>Qt63DQuickAnimation.lib</AdditionalLibraries>
|
| | | <AdditionalLibraries>Qt63DQuickExtras.lib</AdditionalLibraries>
|
| | | <AdditionalLibraries>Qt63DQuickInput.lib</AdditionalLibraries>
|
| | | <AdditionalLibraries>Qt63DQuickRender.lib</AdditionalLibraries>
|
| | | <AdditionalLibraries>Qt63DQuickScene2D.lib</AdditionalLibraries>
|
| | | <AdditionalLibrariesDebug>Qt63DQuickd.lib</AdditionalLibrariesDebug>
|
| | | <AdditionalLibrariesDebug>Qt63DQuickAnimationd.lib</AdditionalLibrariesDebug>
|
| | | <AdditionalLibrariesDebug>Qt63DQuickExtrasd.lib</AdditionalLibrariesDebug>
|
| | | <AdditionalLibrariesDebug>Qt63DQuickInputd.lib</AdditionalLibrariesDebug>
|
| | | <AdditionalLibrariesDebug>Qt63DQuickRenderd.lib</AdditionalLibrariesDebug>
|
| | | <AdditionalLibrariesDebug>Qt63DQuickScene2Dd.lib</AdditionalLibrariesDebug>
|
| | | </Module>
|
| | | <Module Id="47">
|
| | | <Name>Qt Quick Timeline</Name>
|
| | | <proVarQT>quicktimeline</proVarQT>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtQuickTimeline</LibraryPrefix>
|
| | | </Module>
|
| | | <Module Id="48">
|
| | | <Name>Qt Shader Tools</Name>
|
| | | <proVarQT>shadertools</proVarQT>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtShaderTools</LibraryPrefix>
|
| | | </Module>
|
| | | <Module Id="49">
|
| | | <Name>Qt Wayland Compositor</Name>
|
| | | <proVarQT>waylandcompositor</proVarQT>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtWaylandCompositor</LibraryPrefix>
|
| | | </Module>
|
| | | <Module Id="50">
|
| | | <Name>Qt WebEngine Widgets</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtWebEngineWidgets</LibraryPrefix>
|
| | | <proVarQT>webenginewidgets</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtWebEngineCore</IncludePath>
|
| | | <IncludePath>$(QTDIR)\include\QtWebEngineWidgets</IncludePath>
|
| | | <Defines>QT_WEBENGINECORE_LIB</Defines>
|
| | | <Defines>QT_WEBENGINEWIDGETS_LIB</Defines>
|
| | | <AdditionalLibraries>Qt6WebEngineCore.lib</AdditionalLibraries>
|
| | | <AdditionalLibrariesDebug>Qt6WebEngineCored.lib</AdditionalLibrariesDebug>
|
| | | <AdditionalLibraries>Qt6WebEngineWidgets.lib</AdditionalLibraries>
|
| | | <AdditionalLibrariesDebug>Qt6WebEngineWidgetsd.lib</AdditionalLibrariesDebug>
|
| | | </Module>
|
| | | <Module Id="51">
|
| | | <Name>Qt WebEngine Quick</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtWebEngineQuick</LibraryPrefix>
|
| | | <proVarQT>webenginequick</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtWebEngineCore</IncludePath>
|
| | | <IncludePath>$(QTDIR)\include\QtWebEngineQuick</IncludePath>
|
| | | <Defines>QT_WEBENGINECORE_LIB</Defines>
|
| | | <Defines>QT_WEBENGINEQUICK_LIB</Defines>
|
| | | <AdditionalLibraries>Qt6WebEngineCore.lib</AdditionalLibraries>
|
| | | <AdditionalLibrariesDebug>Qt6WebEngineCored.lib</AdditionalLibrariesDebug>
|
| | | <AdditionalLibraries>Qt6WebEngineQuick.lib</AdditionalLibraries>
|
| | | <AdditionalLibrariesDebug>Qt6WebEngineQuickd.lib</AdditionalLibrariesDebug>
|
| | | </Module>
|
| | |
|
| | | <!-- Designer -->
|
| | | <Module Id="52">
|
| | | <Name>Designer</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtDesigner</LibraryPrefix>
|
| | | <HasDLL>true</HasDLL>
|
| | | <proVarQT>designer</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtDesigner</IncludePath>
|
| | | <Defines>QT_DESIGNER_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="53">
|
| | | <Name>Qt UI Tools</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtUiTools</LibraryPrefix>
|
| | | <HasDLL>true</HasDLL>
|
| | | <proVarQT>uitools</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtUiTools</IncludePath>
|
| | | <Defines>QT_UITOOLS_LIB</Defines>
|
| | | </Module>
|
| | | <Module Id="54">
|
| | | <Name>Qt UI Plugin</Name>
|
| | | <Selectable>true</Selectable>
|
| | | <LibraryPrefix>QtUiPlugin</LibraryPrefix>
|
| | | <HasDLL>false</HasDLL>
|
| | | <proVarQT>uiplugin</proVarQT>
|
| | | <IncludePath>$(QTDIR)\include\QtUiPlugin</IncludePath>
|
| | | <Defines>QT_UIPLUGIN_LIB</Defines>
|
| | | <Defines>QDESIGNER_EXPORT_WIDGETS</Defines>
|
| | | </Module>
|
| | | <!-- Designer -->
|
| | |
|
| | | </QtVsTools>
|
QtVsTools.Package/qtmodules.xml
QtVsTools.Package/source.extension.vsixmanifest_TT
QtVsTools.RegExpr/Properties/AssemblyInfo.cs
QtVsTools.RegExpr/QtVsTools.RegExpr.csproj
QtVsTools.RegExpr/expression/CharClassSet.cs
QtVsTools.RegExpr/expression/RegExprAssert.cs
QtVsTools.RegExpr/expression/RegExprRepeat.cs
QtVsTools.RegExpr/expression/RegExprToken.cs
QtVsTools.RegExpr/expression/Renderer.cs
QtVsTools.RegExpr/parser/ParseTree.cs
QtVsTools.RegExpr/parser/Parser.cs
QtVsTools.RegExpr/production/Production.cs
QtVsTools.RegExpr/production/ProductionRule.cs
QtVsTools.RegExpr/production/ProductionRuleAction.cs
QtVsTools.RegExpr/utils/Consts.cs
QtVsTools.Wizards/Common/GuiPage.xaml
QtVsTools.Wizards/Common/GuiPage.xaml.cs
QtVsTools.Wizards/Common/UiClassInclusion.cs
QtVsTools.Wizards/Common/WizardData.cs
QtVsTools.Wizards/Common/WizardIntroPage.xaml
QtVsTools.Wizards/Common/WizardIntroPage.xaml.cs
QtVsTools.Wizards/Common/WizardPage.cs
QtVsTools.Wizards/Common/WizardResult.cs
QtVsTools.Wizards/Common/WizardWindow.xaml
QtVsTools.Wizards/Common/WizardWindow.xaml.cs
QtVsTools.Wizards/ItemWizard/QtClass/QtClassPage.xaml
QtVsTools.Wizards/ItemWizard/QtClass/QtClassPage.xaml.cs
QtVsTools.Wizards/ItemWizard/QtClass/QtClassWizard.cs
QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml
QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml.cs
QtVsTools.Wizards/ItemWizard/Translation/TranslationWizard.cs
QtVsTools.Wizards/ItemWizard/WidgetsClass/WidgetsClassWizard.cs
QtVsTools.Wizards/ProjectWizard/ConfigPage.xaml
QtVsTools.Wizards/ProjectWizard/ConfigPage.xaml.cs
QtVsTools.Wizards/ProjectWizard/Console/ConsoleWizard.cs
QtVsTools.Wizards/ProjectWizard/Designer/DesignerPage.xaml
QtVsTools.Wizards/ProjectWizard/Designer/DesignerPage.xaml.cs
QtVsTools.Wizards/ProjectWizard/Designer/DesignerWizard.cs
QtVsTools.Wizards/ProjectWizard/Empty/EmptyWizard.cs
QtVsTools.Wizards/ProjectWizard/Gui/GuiWizard.cs
QtVsTools.Wizards/ProjectWizard/Library/LibraryClassPage.xaml
QtVsTools.Wizards/ProjectWizard/Library/LibraryClassPage.xaml.cs
QtVsTools.Wizards/ProjectWizard/Library/LibraryWizard.cs
QtVsTools.Wizards/ProjectWizard/ProjectTemplateWizard.cs
QtVsTools.Wizards/ProjectWizard/Quick/QuickWizard.cs
QtVsTools.Wizards/ProjectWizard/Server/ServerPage.xaml
QtVsTools.Wizards/ProjectWizard/Server/ServerPage.xaml.cs
QtVsTools.Wizards/ProjectWizard/Server/ServerWizard.cs
QtVsTools.Wizards/QtVsTools.Wizards.csproj
QtVsTools.Wizards/Util/ClassNameValidationRule.cs
QtVsTools.Wizards/Util/FileExistsInFilterValidationRule.cs
QtVsTools.Wizards/Util/FileNameValidationRule.cs
QtVsTools.Wizards/Util/NativeMethods.cs
QtVsTools.Wizards/Util/UiClassInclusionConverter.cs
QtVsTools.Wizards/Util/UnsafeNativeMethods.cs
QtVsTools.Wizards/Util/VCLanguageManagerValidationRule.cs
QtVsTools.Wizards/Util/VCRulePropertyStorageHelper.cs
README.md
Templates/console/QtTemplate.Project.Console.csproj
Templates/console/console.vcxproj.filters
Templates/designer/QtTemplate.Project.Designer.csproj
Templates/designer/designer.vcxproj.filters
Templates/designer/plugin.h
Templates/designer/widget.h
Templates/dialogbuttonbottom/QtTemplate.Item.DialogButtonBottom.csproj
Templates/dialogbuttonright/QtTemplate.Item.DialogButtonRight.csproj
Templates/empty/QtTemplate.Project.Empty.csproj
Templates/gui/QtTemplate.Project.Gui.csproj
Templates/gui/gui.vcxproj.filters
Templates/gui/gui.vstemplate_TT
Templates/gui/main.cpp
Templates/gui/widget.cpp
Templates/gui/widget.h
Templates/gui/widget.qrc
Templates/lib/QtTemplate.Project.Lib.csproj
Templates/lib/lib.vcxproj.filters
Templates/mainwindow/QtTemplate.Item.MainWindow.csproj
Templates/qml/QtTemplate.Item.QMLFile.csproj
Templates/qmldir/QtTemplate.Item.QMLDir.csproj
Templates/qtclass/Properties/AssemblyInfo.cs
Templates/qtclass/QtTemplate.Item.QtClass.csproj
Templates/qtclass/header.h
Templates/qtclass/qtclass.ico
Templates/qtclass/qtclass.vstemplate_TT
Templates/qtclass/source.cpp
Templates/quick/QtTemplate.Project.Quick.csproj
Templates/quick/quick.vcxproj.filters
Templates/resource/QtTemplate.Item.Resource.csproj
Templates/server/QtTemplate.Project.Server.csproj
Templates/server/header.h
Templates/server/server.vcxproj.filters
Templates/translation/Properties/AssemblyInfo.cs
Templates/translation/QtTemplate.Item.Translation.csproj
Templates/translation/translation.ico
Templates/translation/translation.ts
Templates/translation/translation.vstemplate_TT
Templates/widget/QtTemplate.Item.Widget.csproj
Templates/widgetsclass/Properties/AssemblyInfo.cs
Templates/widgetsclass/QtTemplate.Item.WidgetsClass.csproj
Templates/widgetsclass/widget.cpp
Templates/widgetsclass/widget.h
Templates/widgetsclass/widget.ui
Templates/widgetsclass/widgetsclass.ico
Templates/widgetsclass/widgetsclass.vstemplate_TT
Tests/BigSolution/generator/Program.cs
Tests/BigSolution/template/BigProjectNNN/BigProjectNNN.vcxproj
Tests/BigSolution/template/BigProjectNNN/BigProjectQtClassNNN.h
Tests/BigSolution/template/BigSolution.sln
Tests/BigSolution/template/QtClassLibrary/QtClass.cpp
Tests/BigSolution/template/QtClassLibrary/QtClass.h
Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.cpp
Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.h
Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.vcxproj
Tests/BigSolution/template/QtClassLibrary/QtClassLibrary.vcxproj.filters
Tests/BigSolution/template/QtClassLibrary/qtclasslibrary_global.h
Tests/BigSolution/template/StaticLib/Header.h
Tests/BigSolution/template/StaticLib/StaticLib.cpp
Tests/BigSolution/template/StaticLib/StaticLib.vcxproj
Tests/BigSolution/template/StaticLib/StaticLib.vcxproj.filters
Tests/BigSolution/template/loop_msbuild.bat
Tests/ProjectFormats/100/QtProjectV100.cpp
Tests/ProjectFormats/100/QtProjectV100.h
Tests/ProjectFormats/100/QtProjectV100.pro
Tests/ProjectFormats/100/QtProjectV100.qrc
Tests/ProjectFormats/100/QtProjectV100.ui
Tests/ProjectFormats/100/QtProjectV100.vcxproj
Tests/ProjectFormats/100/QtProjectV100.vcxproj.filters
Tests/ProjectFormats/100/main.cpp
Tests/ProjectFormats/200/QtProjectV200.cpp
Tests/ProjectFormats/200/QtProjectV200.h
Tests/ProjectFormats/200/QtProjectV200.qrc
Tests/ProjectFormats/200/QtProjectV200.sln
Tests/ProjectFormats/200/QtProjectV200.ui
Tests/ProjectFormats/200/QtProjectV200.vcxproj
Tests/ProjectFormats/200/QtProjectV200.vcxproj.filters
Tests/ProjectFormats/200/main.cpp
Tests/ProjectFormats/300/QtProjectV300.cpp
Tests/ProjectFormats/300/QtProjectV300.h
Tests/ProjectFormats/300/QtProjectV300.qrc
Tests/ProjectFormats/300/QtProjectV300.sln
Tests/ProjectFormats/300/QtProjectV300.ui
Tests/ProjectFormats/300/QtProjectV300.vcxproj
Tests/ProjectFormats/300/QtProjectV300.vcxproj.filters
Tests/ProjectFormats/300/main.cpp
Tests/ProjectFormats/301/QtProjectV301.cpp
Tests/ProjectFormats/301/QtProjectV301.h
Tests/ProjectFormats/301/QtProjectV301.qrc
Tests/ProjectFormats/301/QtProjectV301.sln
Tests/ProjectFormats/301/QtProjectV301.ui
Tests/ProjectFormats/301/QtProjectV301.vcxproj
Tests/ProjectFormats/301/QtProjectV301.vcxproj.filters
Tests/ProjectFormats/301/main.cpp
Tests/ProjectFormats/302/QtProjectV302.cpp
Tests/ProjectFormats/302/QtProjectV302.h
Tests/ProjectFormats/302/QtProjectV302.qrc
Tests/ProjectFormats/302/QtProjectV302.sln
Tests/ProjectFormats/302/QtProjectV302.ui
Tests/ProjectFormats/302/QtProjectV302.vcxproj
Tests/ProjectFormats/302/QtProjectV302.vcxproj.filters
Tests/ProjectFormats/302/main.cpp
Tests/ProjectFormats/303/QtProjectV303.cpp
Tests/ProjectFormats/303/QtProjectV303.h
Tests/ProjectFormats/303/QtProjectV303.qrc
Tests/ProjectFormats/303/QtProjectV303.sln
Tests/ProjectFormats/303/QtProjectV303.ui
Tests/ProjectFormats/303/QtProjectV303.vcxproj
Tests/ProjectFormats/303/QtProjectV303.vcxproj.filters
Tests/ProjectFormats/303/main.cpp
Tests/ProjectFormats/304/QtProjectV304.cpp
Tests/ProjectFormats/304/QtProjectV304.h
Tests/ProjectFormats/304/QtProjectV304.qrc
Tests/ProjectFormats/304/QtProjectV304.sln
Tests/ProjectFormats/304/QtProjectV304.ui
Tests/ProjectFormats/304/QtProjectV304.vcxproj
Tests/ProjectFormats/304/QtProjectV304.vcxproj.filters
Tests/ProjectFormats/304/main.cpp
Tests/ProjectFormats/ProjectFormats.md
Tests/Test_QtMsBuild.Tasks/Properties/AssemblyInfo.cs
Tests/Test_QtMsBuild.Tasks/TestTaskLoggingHelper.cs
Tests/Test_QtMsBuild.Tasks/Test_Join.cs
Tests/Test_QtMsBuild.Tasks/Test_QtMsBuild.Tasks.csproj
Tests/Test_QtMsBuild.Tasks/Test_QtRunTask.cs
Tests/Test_QtVsTools.Core/Properties/AssemblyInfo.cs
Tests/Test_QtVsTools.Core/Test_LazyFactory.cs
Tests/Test_QtVsTools.Core/Test_QtVsTools.Core.csproj
Tests/Test_QtVsTools.Package/Properties/AssemblyInfo.cs
Tests/Test_QtVsTools.Package/QtVsTestClient.cs
Tests/Test_QtVsTools.Package/Test_QtVersionsPage.cs
Tests/Test_QtVsTools.Package/Test_QtVsTools.Package.csproj
Tests/Test_QtVsTools.PriorityQueue/Properties/AssemblyInfo.cs
Tests/Test_QtVsTools.PriorityQueue/Test_PriorityQueue.cs
Tests/Test_QtVsTools.PriorityQueue/Test_QtVsTools.PriorityQueue.csproj
Tests/Test_QtVsTools.RegExpr/Properties/AssemblyInfo.cs
Tests/Test_QtVsTools.RegExpr/Test_MacroParser.cs
Tests/Test_QtVsTools.RegExpr/Test_QtVsTools.RegExpr.csproj
Tests/Test_QtVsTools.RegExpr/Test_SubTokens.cs
Tests/Test_QtVsTools.RegExpr/Test_XmlIntParser.cs
doc/config/qtvstools-project.qdocconf
doc/config/style/qt5-sidebar.html
doc/images/front-advanced.png
doc/images/front-coding.png
doc/images/front-gs.png
doc/images/front-help.png
doc/images/front-preview.png
doc/images/front-projects.png
doc/images/qtvstools-msbuild-diagram.png
doc/images/qtvstools-options-qt-general.png
doc/images/qtvstools-qt-project-settings.png
doc/images/qtvstools-qt-translation-file-wizard.png
doc/images/qtvstools-qt-widget-class-wizard.png
doc/images/qtvstools-qtquick-app-modules.png
doc/images/qtvstools-quick-addressbook-entries.png
doc/images/qtvstools-quick-addressbook-mainwindow.png
doc/images/qtvstools-quick-addressbook-popup.png
doc/images/qtvstools-remote-debugging.png
doc/qtvstools-online.qdocconf
doc/src/qtvstools.qdoc
doc/tutorial/AddressBook/adddialog.h
doc/tutorial/QuickAddressBook/QuickAddressBook.sln
doc/tutorial/QuickAddressBook/QuickAddressBook.vcxproj
doc/tutorial/QuickAddressBook/QuickAddressBook.vcxproj.filters
doc/tutorial/QuickAddressBook/QuickAddressBookTypes/AddressBookItem.qml
doc/tutorial/QuickAddressBook/QuickAddressBookTypes/NewAddressPopup.qml
doc/tutorial/QuickAddressBook/main.cpp
doc/tutorial/QuickAddressBook/main.qml
doc/tutorial/QuickAddressBook/qml.qrc
doc/tutorial/QuickAddressBook/qmldir
references.props
version.targets
vsconfig/2017.vsconfig
vsconfig/2019.vsconfig
vsconfig/2022.vsconfig
vstools.bat
vstools.sln
Сборка.md |