Merge remote-tracking branch 'origin/6.0'
Change-Id: If6c5ca7bc4b404959ca3250777d6fb818297798d
@@ -34,7 +34,13 @@ if (WIN32 AND TARGET clangTooling)
|
|||||||
llvm::cl::OptionCategory CheckToolCategory("check tool options");
|
llvm::cl::OptionCategory CheckToolCategory("check tool options");
|
||||||
int main(int argc, const char **argv)
|
int main(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
CommonOptionsParser OptionsParser(argc, argv, CheckToolCategory);
|
class Parser : public CommonOptionsParser {
|
||||||
|
public:
|
||||||
|
Parser(int &argc, const char **argv, llvm::cl::OptionCategory &Category) :
|
||||||
|
CommonOptionsParser(argc, argv, Category) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser OptionsParser(argc, argv, CheckToolCategory);
|
||||||
ClangTool Tool(OptionsParser.getCompilations(),
|
ClangTool Tool(OptionsParser.getCompilations(),
|
||||||
OptionsParser.getSourcePathList());
|
OptionsParser.getSourcePathList());
|
||||||
return 0;
|
return 0;
|
||||||
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
@@ -44,38 +44,75 @@
|
|||||||
\uicontrol {Qt Quick 3D} module to your project as instructed in
|
\uicontrol {Qt Quick 3D} module to your project as instructed in
|
||||||
\l {Adding and Removing Modules}.
|
\l {Adding and Removing Modules}.
|
||||||
|
|
||||||
|
\note If you select \uicontrol {Qt 5} as the \uicontrol {Target Qt Version}
|
||||||
|
when \l {Creating Projects}{creating your project}, the available light
|
||||||
|
components and their properties will be slightly different. The properties
|
||||||
|
may also be situated differently in the \uicontrol Properties view.
|
||||||
|
|
||||||
By default, all imported scenes are created with one directional light.
|
By default, all imported scenes are created with one directional light.
|
||||||
You can use the following components to add lights:
|
You can use the following components to add lights:
|
||||||
|
|
||||||
\list
|
\table
|
||||||
|
\header
|
||||||
|
\li Icon
|
||||||
|
\li Name
|
||||||
|
\li Qt 5 Only
|
||||||
|
\li More Information
|
||||||
|
|
||||||
|
\row
|
||||||
|
\li \inlineimage spot.png
|
||||||
|
\li Directional Light
|
||||||
|
\li
|
||||||
\li \l{DirectionalLight}{Light Directional}
|
\li \l{DirectionalLight}{Light Directional}
|
||||||
|
|
||||||
|
\row
|
||||||
|
\li \inlineimage point.png
|
||||||
|
\li Point Light
|
||||||
|
\li
|
||||||
\li \l{PointLight}{Light Point}
|
\li \l{PointLight}{Light Point}
|
||||||
|
|
||||||
|
\row
|
||||||
|
\li \inlineimage spot.png
|
||||||
|
\li Spot Light
|
||||||
|
\li
|
||||||
\li \l{SpotLight}{Light Spot}
|
\li \l{SpotLight}{Light Spot}
|
||||||
|
|
||||||
|
\row
|
||||||
|
\li \inlineimage area.png
|
||||||
|
\li Area Light
|
||||||
|
\li \inlineimage ok.png
|
||||||
\li \l{AreaLight}{Light Area}
|
\li \l{AreaLight}{Light Area}
|
||||||
\endlist
|
\endtable
|
||||||
|
|
||||||
\note Each additional light negatively effects the rendering performance
|
\note Each additional light negatively effects the rendering performance
|
||||||
of your scene. Keep scenes as simple as possible and use lights sparingly.
|
of your scene. Keep scenes as simple as possible and use lights sparingly.
|
||||||
Use a \l{SceneEnvironment}{Scene Environment} component to apply image-based
|
Use a \l{SceneEnvironment}{Scene Environment} component to apply image-based
|
||||||
lighting that can produce soft and subtle lighting.
|
lighting that can produce soft and subtle lighting.
|
||||||
|
|
||||||
You can edit light properties in the \uicontrol Properties view. The
|
To edit light properties, select a light component in \uicontrol Navigator,
|
||||||
\uicontrol Scope property specifies which node, with it's children,
|
or \uicontrol {3D Editor}, and then adjust its properties in the
|
||||||
is illuminated by a light.
|
\uicontrol Properties view or by dragging the yellow light gizmo handles in
|
||||||
|
\uicontrol {3D Editor}.
|
||||||
|
|
||||||
Set the \uicontrol {Color} property to specify the color applied to models
|
To specify an overall multiplier for a light component's effects, adjust the
|
||||||
|
\uicontrol Brightness property. The \uicontrol Scope property specifies which
|
||||||
|
component, with its children, is illuminated by the light. Set the
|
||||||
|
\l{Picking Colors}{Color} property to specify the color applied to models
|
||||||
illuminated by a light. Set the \uicontrol {Ambient color} property to
|
illuminated by a light. Set the \uicontrol {Ambient color} property to
|
||||||
specify the ambient color applied to materials before being illuminated by
|
specify the ambient color applied to materials before being illuminated by
|
||||||
the light.
|
the light.
|
||||||
|
|
||||||
You can animate light properties in the \uicontrol Timeline view.
|
You can animate light properties in the \l Timeline view.
|
||||||
|
|
||||||
\section1 Directional Light
|
\section1 Directional Light
|
||||||
|
|
||||||
A directional light emits light in one direction from a unidentifiable
|
A directional light emits light in one direction from an unidentifiable
|
||||||
source located infinitely far away. This is similar to sunlight.
|
source located infinitely far away. This is similar to sunlight.
|
||||||
|
|
||||||
\image studio-3d-directional-light.png "Models lit by a dirctional light"
|
Use the \uicontrol Brightness handle of the light gizmo (1) to adjust the
|
||||||
|
\uicontrol Brightness property of any of the light components.
|
||||||
|
|
||||||
|
\image studio-3d-directional-light.png "Models lit by a directional light."
|
||||||
|
|
||||||
If the \uicontrol {Casts shadow} property is enabled, shadows are positioned
|
If the \uicontrol {Casts shadow} property is enabled, shadows are positioned
|
||||||
parallel to the light direction. A directional light has infinite range and
|
parallel to the light direction. A directional light has infinite range and
|
||||||
@@ -96,20 +133,17 @@
|
|||||||
|
|
||||||
\section1 Point Light
|
\section1 Point Light
|
||||||
|
|
||||||
A point light can be described as a sphere, emitting light with equal
|
A point light can be described as a sphere that emits light with equal
|
||||||
strength in all directions from the center of the light. This is similar
|
strength in all directions from the center of the light. This is similar
|
||||||
to the way a light bulb emits light.
|
to the way a light bulb emits light.
|
||||||
|
|
||||||
\image studio-3d-point-light.png "Models lit by a point light"
|
\image studio-3d-point-light.png "Models lit by a point light."
|
||||||
|
|
||||||
Lighting is applied outwards from the center of a point light, becoming
|
Lighting is applied outwards from the center of a point light, becoming
|
||||||
increasingly dim away from the center. Moving a point light changes the
|
increasingly dim away from the center. Moving a point light changes the
|
||||||
position from where the light is emitted. Rotating or scaling a point
|
position from where the light is emitted. Rotating or scaling a point
|
||||||
light does not have any effect.
|
light does not have any effect.
|
||||||
|
|
||||||
To specify an overall multiplier for a point light's effects, set the
|
|
||||||
\uicontrol Brightness property.
|
|
||||||
|
|
||||||
To control the fade-off and range of a point light, set the
|
To control the fade-off and range of a point light, set the
|
||||||
\uicontrol {Constant fade}, \uicontrol {Linear fade}, and
|
\uicontrol {Constant fade}, \uicontrol {Linear fade}, and
|
||||||
\uicontrol {Quadratic fade} properties. Constant fade is the constant
|
\uicontrol {Quadratic fade} properties. Constant fade is the constant
|
||||||
@@ -125,7 +159,8 @@
|
|||||||
dims on surfaces that are far away from the light. The value 1.0 means that
|
dims on surfaces that are far away from the light. The value 1.0 means that
|
||||||
the point light fade exactly follows the inverse square law. For example,
|
the point light fade exactly follows the inverse square law. For example,
|
||||||
when the distance to a component doubles, the light intensity decreases to
|
when the distance to a component doubles, the light intensity decreases to
|
||||||
one fourth.
|
one fourth. Adjust the \uicontrol {Quadratic fade} in the Properties view,
|
||||||
|
or by using the light gizmo handle (2).
|
||||||
|
|
||||||
Aside from fade, a point light has the same properties as a directional
|
Aside from fade, a point light has the same properties as a directional
|
||||||
light.
|
light.
|
||||||
@@ -136,7 +171,13 @@
|
|||||||
The light intensity diminishes when approaching the value of the
|
The light intensity diminishes when approaching the value of the
|
||||||
\uicontrol {Cone angle} property. The angle at which the light
|
\uicontrol {Cone angle} property. The angle at which the light
|
||||||
intensity starts to diminish is defined by the
|
intensity starts to diminish is defined by the
|
||||||
\uicontrol {Inner cone angle} property. Both angles are defined in degrees.
|
\uicontrol {Inner cone angle} property. Both angles are defined in degrees
|
||||||
|
in the \uicontrol Properties view. Use the Properties view or the light gizmo
|
||||||
|
handles to adjust the \uicontrol {Cone angle} (3),
|
||||||
|
\uicontrol {Inner cone angle} (4), and \uicontrol {Quadratic fade} (5)
|
||||||
|
properties.
|
||||||
|
|
||||||
|
\image studio-3d-spot-light.png "A model lit by a spot light."
|
||||||
|
|
||||||
Inside the inner cone angle, the spot light behaves similarly to the point
|
Inside the inner cone angle, the spot light behaves similarly to the point
|
||||||
light. There the light intensity diminishes according to inverse-square-law.
|
light. There the light intensity diminishes according to inverse-square-law.
|
||||||
@@ -144,15 +185,17 @@
|
|||||||
\uicontrol {Constant fade}, \uicontrol {Linear fade}, and
|
\uicontrol {Constant fade}, \uicontrol {Linear fade}, and
|
||||||
\uicontrol {Quadratic fade} properties.
|
\uicontrol {Quadratic fade} properties.
|
||||||
|
|
||||||
\image studio-3d-spot-light.png
|
|
||||||
|
|
||||||
\section1 Area Light
|
\section1 Area Light
|
||||||
|
|
||||||
|
\note The \uicontrol {Area Light} component is only available in Qt 5.
|
||||||
|
|
||||||
An area light is similar to the directional light. However, instead of
|
An area light is similar to the directional light. However, instead of
|
||||||
emitting an equally bright light across the whole scene, the area light
|
emitting an equally bright light across the whole scene, the area light
|
||||||
emits directional light from a rectangle shaped component. You can set the
|
emits directional light from a rectangle shaped component. Use the light
|
||||||
\uicontrol Width and \uicontrol Height properties to determine the size
|
gizmo or the \uicontrol Properties view to set the \uicontrol Width (6)
|
||||||
of the area light.
|
and \uicontrol Height (7) properties to determine the size of the area light.
|
||||||
|
|
||||||
|
\image studio-3d-area-light.png "A model lit by two area lights."
|
||||||
|
|
||||||
Aside from the size, an area light has the same properties as a directional
|
Aside from the size, an area light has the same properties as a directional
|
||||||
light.
|
light.
|
||||||
@@ -160,8 +203,6 @@
|
|||||||
The image below shows an example on how to light a component with different
|
The image below shows an example on how to light a component with different
|
||||||
colors using two different area lights.
|
colors using two different area lights.
|
||||||
|
|
||||||
\image studio-3d-area-light.png
|
|
||||||
|
|
||||||
You can rotate, scale, and move area lights.
|
You can rotate, scale, and move area lights.
|
||||||
|
|
||||||
\section1 Shadows
|
\section1 Shadows
|
||||||
|
@@ -41,7 +41,7 @@ Item {
|
|||||||
anchors.topMargin: 1
|
anchors.topMargin: 1
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
color: StudioTheme.Values.themePanelBackground
|
color: mouseRegion.containsMouse ? StudioTheme.Values.themeControlBackgroundHover : StudioTheme.Values.themePanelBackground
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: itemIcon // to be set by model
|
id: itemIcon // to be set by model
|
||||||
|
@@ -73,7 +73,7 @@ itemLibraryModel [
|
|||||||
]
|
]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ScrollView {
|
Item {
|
||||||
id: itemsView
|
id: itemsView
|
||||||
|
|
||||||
property string importToRemove: ""
|
property string importToRemove: ""
|
||||||
@@ -81,6 +81,11 @@ ScrollView {
|
|||||||
property var currentItem: null
|
property var currentItem: null
|
||||||
property var currentCategory: null
|
property var currentCategory: null
|
||||||
property var currentImport: null
|
property var currentImport: null
|
||||||
|
property bool isHorizontalView: false
|
||||||
|
|
||||||
|
// horizontal component lib variables
|
||||||
|
property var selectedCategory: null
|
||||||
|
property var selectedCategoryImport: null
|
||||||
|
|
||||||
// called from C++ to close context menu on focus out
|
// called from C++ to close context menu on focus out
|
||||||
function closeContextMenu()
|
function closeContextMenu()
|
||||||
@@ -91,15 +96,21 @@ ScrollView {
|
|||||||
|
|
||||||
function showImportCategories()
|
function showImportCategories()
|
||||||
{
|
{
|
||||||
currentImport.importCatVisibleState = true
|
if (itemLibraryModel.isAllCategoriesHidden()) {
|
||||||
|
itemsView.currentImport.importCatVisibleState = true
|
||||||
|
if (!itemLibraryModel.getIsAnyCategoryHidden())
|
||||||
|
itemLibraryModel.isAnyCategoryHidden = false
|
||||||
|
|
||||||
|
itemsView.selectedCategory = itemLibraryModel.selectImportFirstVisibleCategory()
|
||||||
|
}
|
||||||
|
|
||||||
|
itemsView.currentImport.importCatVisibleState = true
|
||||||
if (!itemLibraryModel.getIsAnyCategoryHidden())
|
if (!itemLibraryModel.getIsAnyCategoryHidden())
|
||||||
itemLibraryModel.isAnyCategoryHidden = false
|
itemLibraryModel.isAnyCategoryHidden = false
|
||||||
}
|
}
|
||||||
|
|
||||||
onContentHeightChanged: {
|
onWidthChanged: {
|
||||||
var maxPosition = Math.max(contentHeight - height, 0)
|
itemsView.isHorizontalView = itemsView.width > widthLimit
|
||||||
if (contentY > maxPosition)
|
|
||||||
contentY = maxPosition
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
@@ -112,66 +123,68 @@ ScrollView {
|
|||||||
property int cellVerticalMargin: 4
|
property int cellVerticalMargin: 4
|
||||||
|
|
||||||
// the following depend on the actual shape of the item delegate
|
// the following depend on the actual shape of the item delegate
|
||||||
property int cellWidth: textWidth + 2 * cellHorizontalMargin
|
property int cellWidth: styleConstants.textWidth + 2 * styleConstants.cellHorizontalMargin
|
||||||
property int cellHeight: itemLibraryIconHeight + textHeight +
|
property int cellHeight: itemLibraryIconHeight + styleConstants.textHeight +
|
||||||
2 * cellVerticalMargin + cellVerticalSpacing
|
2 * styleConstants.cellVerticalMargin + styleConstants.cellVerticalSpacing
|
||||||
|
|
||||||
StudioControls.Menu {
|
StudioControls.Menu {
|
||||||
id: moduleContextMenu
|
id: moduleContextMenu
|
||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
text: qsTr("Remove Module")
|
text: qsTr("Remove Module")
|
||||||
visible: currentCategory === null
|
visible: itemsView.currentCategory === null
|
||||||
height: visible ? implicitHeight : 0
|
height: visible ? implicitHeight : 0
|
||||||
enabled: importToRemove !== ""
|
enabled: itemsView.importToRemove !== ""
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
showImportCategories()
|
showImportCategories()
|
||||||
rootView.removeImport(importToRemove)
|
rootView.removeImport(itemsView.importToRemove)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.MenuSeparator {
|
StudioControls.MenuSeparator {
|
||||||
visible: currentCategory === null
|
visible: itemsView.currentCategory === null
|
||||||
height: StudioTheme.Values.border
|
height: StudioTheme.Values.border
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
text: qsTr("Expand All")
|
text: qsTr("Expand All")
|
||||||
visible: currentCategory === null
|
visible: itemsView.currentCategory === null
|
||||||
height: visible ? implicitHeight : 0
|
height: visible ? implicitHeight : 0
|
||||||
onTriggered: itemLibraryModel.expandAll()
|
onTriggered: itemLibraryModel.expandAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
text: qsTr("Collapse All")
|
text: qsTr("Collapse All")
|
||||||
visible: currentCategory === null
|
visible: itemsView.currentCategory === null
|
||||||
height: visible ? implicitHeight : 0
|
height: visible ? implicitHeight : 0
|
||||||
onTriggered: itemLibraryModel.collapseAll()
|
onTriggered: itemLibraryModel.collapseAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.MenuSeparator {
|
StudioControls.MenuSeparator {
|
||||||
visible: currentCategory === null
|
visible: itemsView.currentCategory === null
|
||||||
height: StudioTheme.Values.border
|
height: StudioTheme.Values.border
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
text: qsTr("Hide Category")
|
text: qsTr("Hide Category")
|
||||||
visible: currentCategory
|
visible: itemsView.currentCategory
|
||||||
height: visible ? implicitHeight : 0
|
height: visible ? implicitHeight : 0
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
itemLibraryModel.isAnyCategoryHidden = true
|
itemLibraryModel.isAnyCategoryHidden = true
|
||||||
currentCategory.categoryVisible = false
|
itemsView.currentCategory.categoryVisible = false
|
||||||
|
itemsView.currentCategory.categorySelected = false
|
||||||
|
itemsView.selectedCategory = itemLibraryModel.selectImportFirstVisibleCategory()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.MenuSeparator {
|
StudioControls.MenuSeparator {
|
||||||
visible: currentCategory
|
visible: itemsView.currentCategory
|
||||||
height: StudioTheme.Values.border
|
height: StudioTheme.Values.border
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
text: qsTr("Show Module Hidden Categories")
|
text: qsTr("Show Module Hidden Categories")
|
||||||
enabled: currentImport && !currentImport.importCatVisibleState
|
enabled: itemsView.currentImport && !itemsView.currentImport.importCatVisibleState
|
||||||
onTriggered: showImportCategories()
|
onTriggered: showImportCategories()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,6 +192,12 @@ ScrollView {
|
|||||||
text: qsTr("Show All Hidden Categories")
|
text: qsTr("Show All Hidden Categories")
|
||||||
enabled: itemLibraryModel.isAnyCategoryHidden
|
enabled: itemLibraryModel.isAnyCategoryHidden
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
|
if (itemLibraryModel.isAllCategoriesHidden()) {
|
||||||
|
itemLibraryModel.showHiddenCategories()
|
||||||
|
itemsView.selectedCategory = itemLibraryModel.selectImportFirstVisibleCategory()
|
||||||
|
itemLibraryModel.isAnyCategoryHidden = false
|
||||||
|
}
|
||||||
|
|
||||||
itemLibraryModel.isAnyCategoryHidden = false
|
itemLibraryModel.isAnyCategoryHidden = false
|
||||||
itemLibraryModel.showHiddenCategories()
|
itemLibraryModel.showHiddenCategories()
|
||||||
}
|
}
|
||||||
@@ -192,20 +211,39 @@ ScrollView {
|
|||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
id: importMenuItem
|
id: importMenuItem
|
||||||
text: qsTr("Add Module: ") + importToAdd
|
text: qsTr("Add Module: ") + itemsView.importToAdd
|
||||||
enabled: importToAdd !== ""
|
enabled: itemsView.importToAdd !== ""
|
||||||
onTriggered: rootView.addImportForItem(importToAdd)
|
onTriggered: rootView.addImportForItem(itemsView.importToAdd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceComponent: itemsView.isHorizontalView ? horizontalView : verticalView
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: verticalView
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
id: verticalScrollView
|
||||||
|
width: itemsView.width
|
||||||
|
height: itemsView.height
|
||||||
|
onContentHeightChanged: {
|
||||||
|
var maxPosition = Math.max(contentHeight - verticalScrollView.height, 0)
|
||||||
|
if (contentY > maxPosition)
|
||||||
|
contentY = maxPosition
|
||||||
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
spacing: 2
|
spacing: 2
|
||||||
Repeater {
|
Repeater {
|
||||||
model: itemLibraryModel // to be set in Qml context
|
model: itemLibraryModel // to be set in Qml context
|
||||||
delegate: Section {
|
delegate: Section {
|
||||||
width: itemsView.width -
|
width: itemsView.width -
|
||||||
(itemsView.verticalScrollBarVisible ? itemsView.verticalThickness : 0)
|
(verticalScrollView.verticalScrollBarVisible
|
||||||
|
? verticalScrollView.verticalThickness : 0)
|
||||||
caption: importName
|
caption: importName
|
||||||
visible: importVisible
|
visible: importVisible
|
||||||
sectionHeight: 30
|
sectionHeight: 30
|
||||||
@@ -218,15 +256,14 @@ ScrollView {
|
|||||||
expanded: importExpanded
|
expanded: importExpanded
|
||||||
expandOnClick: false
|
expandOnClick: false
|
||||||
useDefaulContextMenu: false
|
useDefaulContextMenu: false
|
||||||
|
|
||||||
onToggleExpand: {
|
onToggleExpand: {
|
||||||
if (categoryModel.rowCount() > 0)
|
if (categoryModel.rowCount() > 0)
|
||||||
importExpanded = !importExpanded
|
importExpanded = !importExpanded
|
||||||
}
|
}
|
||||||
onShowContextMenu: {
|
onShowContextMenu: {
|
||||||
importToRemove = importRemovable ? importUrl : ""
|
itemsView.importToRemove = importRemovable ? importUrl : ""
|
||||||
currentImport = model
|
itemsView.currentImport = model
|
||||||
currentCategory = null
|
itemsView.currentCategory = null
|
||||||
if (!rootView.isSearchActive())
|
if (!rootView.isSearchActive())
|
||||||
moduleContextMenu.popup()
|
moduleContextMenu.popup()
|
||||||
}
|
}
|
||||||
@@ -238,22 +275,24 @@ ScrollView {
|
|||||||
model: categoryModel
|
model: categoryModel
|
||||||
delegate: Section {
|
delegate: Section {
|
||||||
width: itemsView.width -
|
width: itemsView.width -
|
||||||
(itemsView.verticalScrollBarVisible ? itemsView.verticalThickness : 0)
|
(verticalScrollView.verticalScrollBarVisible
|
||||||
|
? verticalScrollView.verticalThickness : 0)
|
||||||
sectionBackgroundColor: "transparent"
|
sectionBackgroundColor: "transparent"
|
||||||
showTopSeparator: index > 0
|
showTopSeparator: index > 0
|
||||||
hideHeader: categoryModel.rowCount() <= 1
|
hideHeader: categoryModel.rowCount() <= 1
|
||||||
leftPadding: 0
|
leftPadding: 0
|
||||||
rightPadding: 0
|
rightPadding: 0
|
||||||
addTopPadding: categoryModel.rowCount() > 1
|
addTopPadding: categoryModel.rowCount() > 1
|
||||||
addBottomPadding: index != categoryModel.rowCount() - 1
|
addBottomPadding: index !== categoryModel.rowCount() - 1
|
||||||
caption: categoryName + " (" + itemModel.rowCount() + ")"
|
caption: categoryName + " (" + itemModel.rowCount() + ")"
|
||||||
visible: categoryVisible
|
visible: categoryVisible
|
||||||
expanded: categoryExpanded
|
expanded: categoryExpanded
|
||||||
expandOnClick: false
|
expandOnClick: false
|
||||||
onToggleExpand: categoryExpanded = !categoryExpanded
|
onToggleExpand: categoryExpanded = !categoryExpanded
|
||||||
|
useDefaulContextMenu: false
|
||||||
onShowContextMenu: {
|
onShowContextMenu: {
|
||||||
currentCategory = model
|
itemsView.currentCategory = model
|
||||||
currentImport = parent.currentImportModel
|
itemsView.currentImport = parent.currentImportModel
|
||||||
if (!rootView.isSearchActive())
|
if (!rootView.isSearchActive())
|
||||||
moduleContextMenu.popup()
|
moduleContextMenu.popup()
|
||||||
}
|
}
|
||||||
@@ -267,6 +306,7 @@ ScrollView {
|
|||||||
leftPadding: 6
|
leftPadding: 6
|
||||||
rightPadding: 6
|
rightPadding: 6
|
||||||
columns: itemGrid.actualWidth / styleConstants.cellWidth
|
columns: itemGrid.actualWidth / styleConstants.cellWidth
|
||||||
|
rowSpacing: 7
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: itemModel
|
model: itemModel
|
||||||
@@ -278,7 +318,7 @@ ScrollView {
|
|||||||
height: styleConstants.cellHeight
|
height: styleConstants.cellHeight
|
||||||
onShowContextMenu: {
|
onShowContextMenu: {
|
||||||
if (!itemUsable) {
|
if (!itemUsable) {
|
||||||
importToAdd = itemRequiredImport
|
itemsView.importToAdd = itemRequiredImport
|
||||||
itemContextMenu.popup()
|
itemContextMenu.popup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -292,3 +332,164 @@ ScrollView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: horizontalView
|
||||||
|
|
||||||
|
Row {
|
||||||
|
padding: 5
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
id: horizontalScrollView
|
||||||
|
width: 270
|
||||||
|
height: itemsView.height
|
||||||
|
onContentHeightChanged: {
|
||||||
|
var maxPosition = Math.max(contentHeight - horizontalScrollView.height, 0)
|
||||||
|
if (contentY > maxPosition)
|
||||||
|
contentY = maxPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: parent.width
|
||||||
|
spacing: 2
|
||||||
|
Repeater {
|
||||||
|
model: itemLibraryModel // to be set in Qml context
|
||||||
|
delegate: Section {
|
||||||
|
width: 265 -
|
||||||
|
(horizontalScrollView.verticalScrollBarVisible
|
||||||
|
? horizontalScrollView.verticalThickness : 0)
|
||||||
|
caption: importName
|
||||||
|
visible: importVisible
|
||||||
|
sectionHeight: 30
|
||||||
|
sectionFontSize: 15
|
||||||
|
showArrow: categoryModel.rowCount() > 0
|
||||||
|
labelColor: importUnimported ? StudioTheme.Values.themeUnimportedModuleColor
|
||||||
|
: StudioTheme.Values.themeTextColor
|
||||||
|
leftPadding: 0
|
||||||
|
rightPadding: 0
|
||||||
|
expanded: importExpanded
|
||||||
|
expandOnClick: false
|
||||||
|
useDefaulContextMenu: false
|
||||||
|
onToggleExpand: {
|
||||||
|
if (categoryModel.rowCount() > 0)
|
||||||
|
importExpanded = !importExpanded
|
||||||
|
}
|
||||||
|
onShowContextMenu: {
|
||||||
|
itemsView.importToRemove = importRemovable ? importUrl : ""
|
||||||
|
itemsView.currentImport = model
|
||||||
|
itemsView.currentCategory = null
|
||||||
|
if (!rootView.isSearchActive())
|
||||||
|
moduleContextMenu.popup()
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 2
|
||||||
|
property var currentImportModel: model // allows accessing the import model from inside the category section
|
||||||
|
Repeater {
|
||||||
|
model: categoryModel
|
||||||
|
delegate: Rectangle {
|
||||||
|
width: 265 -
|
||||||
|
(horizontalScrollView.verticalScrollBarVisible
|
||||||
|
? horizontalScrollView.verticalThickness : 0)
|
||||||
|
height: 25
|
||||||
|
visible: categoryVisible
|
||||||
|
border.width: StudioTheme.Values.border
|
||||||
|
border.color: StudioTheme.Values.themeControlOutline
|
||||||
|
color: categorySelected
|
||||||
|
? StudioTheme.Values.themeControlBackgroundHover
|
||||||
|
: categoryMouseArea.containsMouse ? Qt.darker(StudioTheme.Values.themeControlBackgroundHover, 1.5)
|
||||||
|
: StudioTheme.Values.themeControlBackground
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.fill: parent
|
||||||
|
text: categoryName
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
font.pixelSize: 13
|
||||||
|
font.capitalization: Font.AllUppercase
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: categoryMouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
|
||||||
|
onClicked: (mouse) => {
|
||||||
|
itemLibraryModel.selectImportCategory(parent.parent.currentImportModel.importUrl, model.index)
|
||||||
|
itemsView.selectedCategory = model
|
||||||
|
itemsView.selectedCategoryImport = parent.parent.currentImportModel
|
||||||
|
|
||||||
|
if (mouse.button === Qt.RightButton && !rootView.isSearchActive() && categoryModel.rowCount() !== 1) {
|
||||||
|
itemsView.currentCategory = model
|
||||||
|
itemsView.currentImport = parent.parent.currentImportModel
|
||||||
|
moduleContextMenu.popup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (categorySelected)
|
||||||
|
categorySelected = !categorySelected
|
||||||
|
itemsView.selectedCategory = itemLibraryModel.selectImportFirstVisibleCategory()
|
||||||
|
if (itemsView.selectedCategory === categorySelected)
|
||||||
|
itemsView.selectedCategoryImport = itemsView.selectedCategory.parent.currentImportModel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle { // separator between import/category column and item grid
|
||||||
|
id: separatingLine
|
||||||
|
height: itemsView.height - 10
|
||||||
|
width: 1
|
||||||
|
color: StudioTheme.Values.themeControlOutline
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
id: itemScrollView
|
||||||
|
width: itemsView.width - 275
|
||||||
|
height: itemsView.height
|
||||||
|
onContentHeightChanged: {
|
||||||
|
var maxPosition = Math.max(contentHeight - itemScrollView.height, 0)
|
||||||
|
if (contentY > maxPosition)
|
||||||
|
contentY = maxPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
Grid {
|
||||||
|
id: hItemGrid
|
||||||
|
property real actualWidth: itemsView.width - 294
|
||||||
|
property int flexibleWidth: (hItemGrid.actualWidth / hItemGrid.columns) - styleConstants.cellWidth
|
||||||
|
|
||||||
|
leftPadding: 9
|
||||||
|
rightPadding: 9
|
||||||
|
bottomPadding: 15
|
||||||
|
columns: hItemGrid.actualWidth / styleConstants.cellWidth
|
||||||
|
rowSpacing: 7
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: itemsView.selectedCategory ? itemsView.selectedCategory.itemModel : null
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
visible: itemVisible
|
||||||
|
textColor: itemsView.selectedCategoryImport && itemsView.selectedCategoryImport.importUnimported
|
||||||
|
? StudioTheme.Values.themeUnimportedModuleColor : StudioTheme.Values.themeTextColor
|
||||||
|
width: styleConstants.cellWidth + hItemGrid.flexibleWidth
|
||||||
|
height: styleConstants.cellHeight
|
||||||
|
onShowContextMenu: {
|
||||||
|
if (!itemUsable) {
|
||||||
|
itemsView.importToAdd = itemRequiredImport
|
||||||
|
itemContextMenu.popup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -336,6 +336,12 @@ public:
|
|||||||
Utils::optional<QList<MarkupKind>> documentationFormat() const;
|
Utils::optional<QList<MarkupKind>> documentationFormat() const;
|
||||||
void setDocumentationFormat(const QList<MarkupKind> &documentationFormat);
|
void setDocumentationFormat(const QList<MarkupKind> &documentationFormat);
|
||||||
void clearDocumentationFormat() { remove(documentationFormatKey); }
|
void clearDocumentationFormat() { remove(documentationFormatKey); }
|
||||||
|
|
||||||
|
Utils::optional<bool> activeParameterSupport() const
|
||||||
|
{ return optionalValue<bool>(activeParameterSupportKey); }
|
||||||
|
void setActiveParameterSupport(bool activeParameterSupport)
|
||||||
|
{ insert(activeParameterSupportKey, activeParameterSupport); }
|
||||||
|
void clearActiveParameterSupport() { remove(activeParameterSupportKey); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// The client supports the following `SignatureInformation` specific properties.
|
// The client supports the following `SignatureInformation` specific properties.
|
||||||
|
@@ -29,6 +29,7 @@ namespace LanguageServerProtocol {
|
|||||||
|
|
||||||
constexpr char actionsKey[] = "actions";
|
constexpr char actionsKey[] = "actions";
|
||||||
constexpr char activeParameterKey[] = "activeParameter";
|
constexpr char activeParameterKey[] = "activeParameter";
|
||||||
|
constexpr char activeParameterSupportKey[] = "activeParameterSupport";
|
||||||
constexpr char activeSignatureKey[] = "activeSignature";
|
constexpr char activeSignatureKey[] = "activeSignature";
|
||||||
constexpr char addedKey[] = "added";
|
constexpr char addedKey[] = "added";
|
||||||
constexpr char additionalTextEditsKey[] = "additionalTextEdits";
|
constexpr char additionalTextEditsKey[] = "additionalTextEdits";
|
||||||
|
@@ -145,6 +145,10 @@ public:
|
|||||||
void setParameters(const QList<ParameterInformation> ¶meters)
|
void setParameters(const QList<ParameterInformation> ¶meters)
|
||||||
{ insertArray(parametersKey, parameters); }
|
{ insertArray(parametersKey, parameters); }
|
||||||
void clearParameters() { remove(parametersKey); }
|
void clearParameters() { remove(parametersKey); }
|
||||||
|
|
||||||
|
Utils::optional<int> activeParameter() const { return optionalValue<int>(activeParameterKey); }
|
||||||
|
void setActiveParameter(int activeParameter) { insert(activeParameterKey, activeParameter); }
|
||||||
|
void clearActiveParameter() { remove(activeParameterKey); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1181,7 +1181,7 @@ void StringAspect::setVolatileValue(const QVariant &val)
|
|||||||
switch (d->m_displayStyle) {
|
switch (d->m_displayStyle) {
|
||||||
case PathChooserDisplay:
|
case PathChooserDisplay:
|
||||||
if (d->m_pathChooserDisplay)
|
if (d->m_pathChooserDisplay)
|
||||||
d->m_pathChooserDisplay->setPath(val.toString());
|
d->m_pathChooserDisplay->setFilePath(FilePath::fromVariant(val));
|
||||||
break;
|
break;
|
||||||
case LineEditDisplay:
|
case LineEditDisplay:
|
||||||
if (d->m_lineEditDisplay)
|
if (d->m_lineEditDisplay)
|
||||||
|
@@ -647,8 +647,10 @@ void ProcessArgs::addArgs(QString *args, const QStringList &inArgs)
|
|||||||
bool ProcessArgs::prepareCommand(const CommandLine &cmdLine, QString *outCmd, ProcessArgs *outArgs,
|
bool ProcessArgs::prepareCommand(const CommandLine &cmdLine, QString *outCmd, ProcessArgs *outArgs,
|
||||||
const Environment *env, const FilePath *pwd)
|
const Environment *env, const FilePath *pwd)
|
||||||
{
|
{
|
||||||
const FilePath executable = cmdLine.executable();
|
FilePath executable = cmdLine.executable();
|
||||||
const QString arguments = cmdLine.arguments();
|
const QString arguments = cmdLine.arguments();
|
||||||
|
if (env && executable.isRelativePath())
|
||||||
|
executable = env->searchInPath(executable.toString());
|
||||||
ProcessArgs::SplitError err;
|
ProcessArgs::SplitError err;
|
||||||
*outArgs = ProcessArgs::prepareArgs(arguments, &err, executable.osType(), env, pwd);
|
*outArgs = ProcessArgs::prepareArgs(arguments, &err, executable.osType(), env, pwd);
|
||||||
if (err == ProcessArgs::SplitOk) {
|
if (err == ProcessArgs::SplitOk) {
|
||||||
|
@@ -616,7 +616,7 @@ bool FilePath::isWritableFile() const
|
|||||||
return s_deviceHooks.isWritableFile(*this);
|
return s_deviceHooks.isWritableFile(*this);
|
||||||
}
|
}
|
||||||
const QFileInfo fi{m_data};
|
const QFileInfo fi{m_data};
|
||||||
return fi.exists() && fi.isWritable() && !fi.isDir();
|
return fi.isWritable() && !fi.isDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FilePath::ensureWritableDir() const
|
bool FilePath::ensureWritableDir() const
|
||||||
@@ -626,7 +626,7 @@ bool FilePath::ensureWritableDir() const
|
|||||||
return s_deviceHooks.ensureWritableDir(*this);
|
return s_deviceHooks.ensureWritableDir(*this);
|
||||||
}
|
}
|
||||||
const QFileInfo fi{m_data};
|
const QFileInfo fi{m_data};
|
||||||
if (exists() && fi.isDir() && fi.isWritable())
|
if (fi.isDir() && fi.isWritable())
|
||||||
return true;
|
return true;
|
||||||
return QDir().mkpath(m_data);
|
return QDir().mkpath(m_data);
|
||||||
}
|
}
|
||||||
@@ -652,7 +652,7 @@ bool FilePath::isExecutableFile() const
|
|||||||
return s_deviceHooks.isExecutableFile(*this);
|
return s_deviceHooks.isExecutableFile(*this);
|
||||||
}
|
}
|
||||||
const QFileInfo fi{m_data};
|
const QFileInfo fi{m_data};
|
||||||
return fi.exists() && fi.isExecutable() && !fi.isDir();
|
return fi.isExecutable() && !fi.isDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FilePath::isReadableFile() const
|
bool FilePath::isReadableFile() const
|
||||||
@@ -662,7 +662,7 @@ bool FilePath::isReadableFile() const
|
|||||||
return s_deviceHooks.isReadableFile(*this);
|
return s_deviceHooks.isReadableFile(*this);
|
||||||
}
|
}
|
||||||
const QFileInfo fi{m_data};
|
const QFileInfo fi{m_data};
|
||||||
return fi.exists() && fi.isReadable() && !fi.isDir();
|
return fi.isReadable() && !fi.isDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FilePath::isReadableDir() const
|
bool FilePath::isReadableDir() const
|
||||||
@@ -672,7 +672,7 @@ bool FilePath::isReadableDir() const
|
|||||||
return s_deviceHooks.isReadableDir(*this);
|
return s_deviceHooks.isReadableDir(*this);
|
||||||
}
|
}
|
||||||
const QFileInfo fi{m_data};
|
const QFileInfo fi{m_data};
|
||||||
return fi.exists() && fi.isReadable() && fi.isDir();
|
return fi.isReadable() && fi.isDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FilePath::isFile() const
|
bool FilePath::isFile() const
|
||||||
@@ -682,7 +682,7 @@ bool FilePath::isFile() const
|
|||||||
return s_deviceHooks.isFile(*this);
|
return s_deviceHooks.isFile(*this);
|
||||||
}
|
}
|
||||||
const QFileInfo fi{m_data};
|
const QFileInfo fi{m_data};
|
||||||
return fi.exists() && fi.isFile();
|
return fi.isFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FilePath::isDir() const
|
bool FilePath::isDir() const
|
||||||
@@ -692,7 +692,7 @@ bool FilePath::isDir() const
|
|||||||
return s_deviceHooks.isDir(*this);
|
return s_deviceHooks.isDir(*this);
|
||||||
}
|
}
|
||||||
const QFileInfo fi{m_data};
|
const QFileInfo fi{m_data};
|
||||||
return fi.exists() && fi.isDir();
|
return fi.isDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FilePath::createDir() const
|
bool FilePath::createDir() const
|
||||||
|
@@ -195,6 +195,11 @@ bool ProjectIntroPage::validate()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectIntroPage::fieldsUpdated()
|
||||||
|
{
|
||||||
|
slotChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void ProjectIntroPage::slotChanged()
|
void ProjectIntroPage::slotChanged()
|
||||||
{
|
{
|
||||||
const bool newComplete = validate();
|
const bool newComplete = validate();
|
||||||
@@ -286,6 +291,8 @@ void ProjectIntroPage::displayStatusMessage(InfoLabel::InfoType t, const QString
|
|||||||
{
|
{
|
||||||
d->m_ui.stateLabel->setType(t);
|
d->m_ui.stateLabel->setType(t);
|
||||||
d->m_ui.stateLabel->setText(s);
|
d->m_ui.stateLabel->setText(s);
|
||||||
|
|
||||||
|
emit statusMessageChanged(t, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectIntroPage::hideStatusLabel()
|
void ProjectIntroPage::hideStatusLabel()
|
||||||
|
@@ -66,8 +66,14 @@ public:
|
|||||||
|
|
||||||
bool validateProjectName(const QString &name, QString *errorMessage);
|
bool validateProjectName(const QString &name, QString *errorMessage);
|
||||||
|
|
||||||
|
// Calls slotChanged() - i.e. tell the page that some of its fields have been updated.
|
||||||
|
// This function is useful if you programmatically update the fields of the page (i.e. from
|
||||||
|
// your client code).
|
||||||
|
void fieldsUpdated();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void activated();
|
void activated();
|
||||||
|
void statusMessageChanged(InfoLabel::InfoType type, const QString &message);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setFilePath(const FilePath &path);
|
void setFilePath(const FilePath &path);
|
||||||
|
@@ -88,9 +88,9 @@ QTextCursor selectAt(QTextCursor textCursor, int line, int column, uint length)
|
|||||||
if (column < 1)
|
if (column < 1)
|
||||||
column = 1;
|
column = 1;
|
||||||
|
|
||||||
const int anchorPosition = positionInText(textCursor.document(), line, column + length);
|
const int anchorPosition = positionInText(textCursor.document(), line, column);
|
||||||
textCursor.setPosition(anchorPosition);
|
textCursor.setPosition(anchorPosition);
|
||||||
textCursor.setPosition(anchorPosition - length, QTextCursor::KeepAnchor);
|
textCursor.setPosition(anchorPosition + int(length), QTextCursor::KeepAnchor);
|
||||||
|
|
||||||
return textCursor;
|
return textCursor;
|
||||||
}
|
}
|
||||||
|
@@ -23,12 +23,13 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "androidqmlpreviewworker.h"
|
||||||
|
|
||||||
#include "androidavdmanager.h"
|
#include "androidavdmanager.h"
|
||||||
#include "androiddevice.h"
|
#include "androiddevice.h"
|
||||||
#include "androiddeviceinfo.h"
|
#include "androiddeviceinfo.h"
|
||||||
#include "androidglobal.h"
|
#include "androidglobal.h"
|
||||||
#include "androidmanager.h"
|
#include "androidmanager.h"
|
||||||
#include "androidqmlpreviewworker.h"
|
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
@@ -44,10 +45,11 @@
|
|||||||
#include <qtsupport/baseqtversion.h>
|
#include <qtsupport/baseqtversion.h>
|
||||||
#include <qtsupport/qtkitinformation.h>
|
#include <qtsupport/qtkitinformation.h>
|
||||||
|
|
||||||
|
#include <utils/runextensions.h>
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QDeadlineTimer>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QTemporaryDir>
|
|
||||||
#include <QImageReader>
|
|
||||||
#include <QtConcurrent>
|
|
||||||
|
|
||||||
namespace Android {
|
namespace Android {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -80,173 +82,143 @@ ApkInfo::ApkInfo() :
|
|||||||
|
|
||||||
Q_GLOBAL_STATIC(ApkInfo, apkInfo)
|
Q_GLOBAL_STATIC(ApkInfo, apkInfo)
|
||||||
|
|
||||||
const char packageSuffix[] = ".qmlrc";
|
static const char packageSuffix[] = ".qmlrc";
|
||||||
|
|
||||||
static inline bool isMainThread()
|
FilePath AndroidQmlPreviewWorker::designViewerApkPath(const QString &abi) const
|
||||||
{
|
{
|
||||||
return QCoreApplication::instance()->thread() == QThread::currentThread();
|
if (abi.isEmpty())
|
||||||
}
|
|
||||||
|
|
||||||
static FilePath viewerApkPath(const QString &avdAbi)
|
|
||||||
{
|
|
||||||
if (avdAbi.isEmpty())
|
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
if (apkInfo()->abis.contains(avdAbi))
|
if (apkInfo()->abis.contains(abi)) {
|
||||||
return Core::ICore::resourcePath(QString("android/qtdesignviewer/designviewer_%1.apk").
|
return Core::ICore::resourcePath(QString("android/qtdesignviewer/designviewer_%1.apk")
|
||||||
arg(avdAbi));
|
.arg(abi));
|
||||||
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static SdkToolResult runAdbCommandAsyncAndWait(const QString &dev, const QStringList &arguments)
|
SdkToolResult AndroidQmlPreviewWorker::runAdbCommand(const QStringList &arguments) const
|
||||||
{
|
{
|
||||||
QStringList args;
|
QStringList args;
|
||||||
if (!dev.isEmpty())
|
if (!m_serialNumber.isEmpty())
|
||||||
args << AndroidDeviceInfo::adbSelector(dev);
|
args << AndroidDeviceInfo::adbSelector(m_serialNumber);
|
||||||
args << arguments;
|
|
||||||
QFuture<SdkToolResult> asyncResult = QtConcurrent::run([args] {
|
|
||||||
return AndroidManager::runAdbCommand(args);});
|
|
||||||
|
|
||||||
while (asyncResult.isRunning()) {
|
|
||||||
QCoreApplication::instance()->processEvents(QEventLoop::AllEvents, 100);
|
|
||||||
}
|
|
||||||
return asyncResult.result();
|
|
||||||
}
|
|
||||||
|
|
||||||
static SdkToolResult runAdbCommand(const QString &dev, const QStringList &arguments)
|
|
||||||
{
|
|
||||||
if (isMainThread())
|
|
||||||
return runAdbCommandAsyncAndWait(dev, arguments);
|
|
||||||
QStringList args;
|
|
||||||
if (!dev.isEmpty())
|
|
||||||
args << AndroidDeviceInfo::adbSelector(dev);
|
|
||||||
args << arguments;
|
args << arguments;
|
||||||
return AndroidManager::runAdbCommand(args);
|
return AndroidManager::runAdbCommand(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SdkToolResult runAdbShellCommand(const QString &dev, const QStringList &arguments)
|
SdkToolResult AndroidQmlPreviewWorker::runAdbShellCommand(const QStringList &arguments) const
|
||||||
{
|
{
|
||||||
const QStringList shellCmd{"shell"};
|
return runAdbCommand(QStringList() << "shell" << arguments);
|
||||||
return runAdbCommand(dev, shellCmd + arguments);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString startAvd(const AndroidAvdManager &avd, const QString &name)
|
int AndroidQmlPreviewWorker::pidofPreview() const
|
||||||
{
|
|
||||||
QFuture<QString> asyncRes = QtConcurrent::run([avd, name] {
|
|
||||||
return avd.startAvd(name);
|
|
||||||
});
|
|
||||||
while (asyncRes.isRunning())
|
|
||||||
QCoreApplication::instance()->processEvents(QEventLoop::AllEvents, 100);
|
|
||||||
return asyncRes.result();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pidofPreview(const QString &dev)
|
|
||||||
{
|
{
|
||||||
const QStringList command{"pidof", apkInfo()->appId};
|
const QStringList command{"pidof", apkInfo()->appId};
|
||||||
const SdkToolResult res = runAdbShellCommand(dev, command);
|
const SdkToolResult res = runAdbShellCommand(command);
|
||||||
return res.success() ? res.stdOut().toInt() : -1;
|
return res.success() ? res.stdOut().toInt() : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isPreviewRunning(const QString &dev, int lastKnownPid = -1)
|
bool AndroidQmlPreviewWorker::isPreviewRunning(int lastKnownPid) const
|
||||||
{
|
{
|
||||||
const int pid = pidofPreview(dev);
|
const int pid = pidofPreview();
|
||||||
return (lastKnownPid > 1) ? lastKnownPid == pid : pid > 1;
|
return (lastKnownPid > 1) ? lastKnownPid == pid : pid > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidQmlPreviewWorker::AndroidQmlPreviewWorker(ProjectExplorer::RunControl *runControl)
|
void AndroidQmlPreviewWorker::startPidWatcher()
|
||||||
: ProjectExplorer::RunWorker(runControl)
|
|
||||||
, m_rc(runControl)
|
|
||||||
, m_config(AndroidConfigurations::currentConfig())
|
|
||||||
{
|
{
|
||||||
}
|
m_pidFutureWatcher.setFuture(Utils::runAsync([this]() {
|
||||||
|
// wait for started
|
||||||
QStringList filterAppLog(const QStringList& oldList, const QStringList& newList)
|
const int sleepTimeMs = 2000;
|
||||||
{
|
QDeadlineTimer deadline(20000);
|
||||||
QStringList list = Utils::filtered(newList,
|
while (!m_pidFutureWatcher.isCanceled() && !deadline.hasExpired()) {
|
||||||
[](const auto & arg){return arg.contains(apkInfo()->name);});
|
|
||||||
for (const auto &oldEntry : oldList) {
|
|
||||||
list.removeAll(oldEntry);
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AndroidQmlPreviewWorker::start()
|
|
||||||
{
|
|
||||||
UploadInfo transfer;
|
|
||||||
const bool res = ensureAvdIsRunning()
|
|
||||||
&& checkAndInstallPreviewApp()
|
|
||||||
&& prepareUpload(transfer)
|
|
||||||
&& uploadFiles(transfer)
|
|
||||||
&& runPreviewApp(transfer);
|
|
||||||
|
|
||||||
if (!res) {
|
|
||||||
reportFailure();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
reportStarted();
|
|
||||||
//Thread to monitor preview life
|
|
||||||
QtConcurrent::run([this]() {
|
|
||||||
QElapsedTimer timer;
|
|
||||||
timer.start();
|
|
||||||
while (runControl() && runControl()->isRunning()) {
|
|
||||||
if (m_viewerPid == -1) {
|
if (m_viewerPid == -1) {
|
||||||
m_viewerPid = pidofPreview(m_devInfo.serialNumber);
|
m_viewerPid = pidofPreview();
|
||||||
if (m_viewerPid > 0)
|
if (m_viewerPid > 0) {
|
||||||
QMetaObject::invokeMethod(this, &AndroidQmlPreviewWorker::startLogcat);
|
emit previewPidChanged();
|
||||||
} else if (timer.elapsed() > 2000) {
|
break;
|
||||||
//Get the application output
|
}
|
||||||
if (!isPreviewRunning(m_devInfo.serialNumber, m_viewerPid))
|
}
|
||||||
QMetaObject::invokeMethod(this, &AndroidQmlPreviewWorker::stop);
|
QThread::msleep(sleepTimeMs);
|
||||||
|
}
|
||||||
|
|
||||||
timer.restart();
|
while (!m_pidFutureWatcher.isCanceled()) {
|
||||||
|
if (!isPreviewRunning(m_viewerPid)) {
|
||||||
|
stop();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
QThread::msleep(100);
|
QThread::msleep(sleepTimeMs);
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidQmlPreviewWorker::startLogcat()
|
void AndroidQmlPreviewWorker::startLogcat()
|
||||||
{
|
{
|
||||||
QtConcurrent::run([this]() {
|
QString args = QString("logcat --pid=%1").arg(m_viewerPid);
|
||||||
QElapsedTimer timer;
|
if (!m_logcatStartTimeStamp.isEmpty())
|
||||||
timer.start();
|
args += QString(" -T '%1'").arg(m_logcatStartTimeStamp);
|
||||||
int initialPid = m_viewerPid; // to check if our initial process is still alive
|
Utils::CommandLine cmd(AndroidConfigurations::currentConfig().adbToolPath());
|
||||||
QStringList logLines;
|
cmd.setArguments(args);
|
||||||
auto appendLogLinesCall = [&logLines, this](){ appendLogLines(logLines); };
|
m_logcatProcess.setCommand(cmd);
|
||||||
auto runCondition = [this, initialPid](){ return (runControl() && runControl()->isRunning())
|
m_logcatProcess.setUseCtrlCStub(true);
|
||||||
&& initialPid == m_viewerPid;};
|
m_logcatProcess.start();
|
||||||
QString timeFilter;
|
}
|
||||||
while (runCondition()) {
|
|
||||||
if (timer.elapsed() > 2000) {
|
void AndroidQmlPreviewWorker::filterLogcatAndAppendMessage(const QString &stdOut)
|
||||||
//Get the application output
|
{
|
||||||
QStringList logcatCmd = {"logcat", QString("--pid=%1").arg(initialPid), "-t"};
|
for (const QString &line : stdOut.split('\n')) {
|
||||||
if (!timeFilter.isEmpty())
|
QStringList splittedLine = line.split(QLatin1String("%1: ").arg(apkInfo()->name));
|
||||||
logcatCmd.append(QString("%1").arg(timeFilter));
|
if (splittedLine.count() == 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const QString outLine = splittedLine.last();
|
||||||
|
const QString firstPart = splittedLine.first();
|
||||||
|
if (firstPart.contains(" I ") || firstPart.contains(" D "))
|
||||||
|
appendMessage(outLine, NormalMessageFormat);
|
||||||
else
|
else
|
||||||
logcatCmd.append(QString("1000")); //show last 1000 lines (but for the 1st time)
|
appendMessage(outLine, ErrorMessageFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const SdkToolResult logcatResult = runAdbCommand(m_devInfo.serialNumber, logcatCmd);
|
AndroidQmlPreviewWorker::AndroidQmlPreviewWorker(ProjectExplorer::RunControl *runControl)
|
||||||
if (runCondition()) {
|
: ProjectExplorer::RunWorker(runControl),
|
||||||
const QStringList output = logcatResult.stdOut().split('\n');
|
m_rc(runControl),
|
||||||
const QStringList filtered = filterAppLog(logLines, output);
|
m_androidConfig(AndroidConfigurations::currentConfig())
|
||||||
|
{
|
||||||
|
connect(this, &RunWorker::started, this, &AndroidQmlPreviewWorker::startPidWatcher);
|
||||||
|
connect(this, &RunWorker::stopped, &m_pidFutureWatcher, &QFutureWatcher<void>::cancel);
|
||||||
|
connect(this, &AndroidQmlPreviewWorker::previewPidChanged,
|
||||||
|
this, &AndroidQmlPreviewWorker::startLogcat);
|
||||||
|
|
||||||
if (!filtered.isEmpty()){
|
connect(this, &RunWorker::stopped, &m_logcatProcess, &Utils::QtcProcess::stopProcess);
|
||||||
const QString lastLine = filtered.last();
|
m_logcatProcess.setStdOutCallback([this](const QString &stdOut) {
|
||||||
timeFilter = lastLine.left(lastLine.indexOf(" ", lastLine.indexOf(" ") + 1));
|
filterLogcatAndAppendMessage(stdOut);
|
||||||
QMetaObject::invokeMethod(this, appendLogLinesCall);
|
|
||||||
logLines = filtered;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
timer.restart();
|
|
||||||
}
|
|
||||||
QThread::msleep(100);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AndroidQmlPreviewWorker::~AndroidQmlPreviewWorker()
|
||||||
|
{
|
||||||
|
m_pidFutureWatcher.cancel();
|
||||||
|
m_pidFutureWatcher.waitForFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidQmlPreviewWorker::start()
|
||||||
|
{
|
||||||
|
const SdkToolResult dateResult = runAdbCommand({"shell", "date", "+%s"});
|
||||||
|
if (dateResult.success()) {
|
||||||
|
m_logcatStartTimeStamp = QDateTime::fromSecsSinceEpoch(dateResult.stdOut().toInt())
|
||||||
|
.toString("MM-dd hh:mm:ss.mmm");
|
||||||
|
}
|
||||||
|
const bool previewStarted = ensureAvdIsRunning()
|
||||||
|
&& checkAndInstallPreviewApp()
|
||||||
|
&& uploadPreviewArtefacts()
|
||||||
|
&& preparePreviewArtefacts()
|
||||||
|
&& startPreviewApp();
|
||||||
|
|
||||||
|
previewStarted ? reportStarted() : reportStopped();
|
||||||
|
}
|
||||||
|
|
||||||
void AndroidQmlPreviewWorker::stop()
|
void AndroidQmlPreviewWorker::stop()
|
||||||
{
|
{
|
||||||
if (!isPreviewRunning(m_devInfo.serialNumber, m_viewerPid) || stopPreviewApp())
|
if (!isPreviewRunning(m_viewerPid) || stopPreviewApp())
|
||||||
appendMessage(tr("%1 has been stopped.").arg(apkInfo()->name), NormalMessageFormat);
|
appendMessage(tr("%1 has been stopped.").arg(apkInfo()->name), NormalMessageFormat);
|
||||||
m_viewerPid = -1;
|
m_viewerPid = -1;
|
||||||
reportStopped();
|
reportStopped();
|
||||||
@@ -254,28 +226,35 @@ void AndroidQmlPreviewWorker::stop()
|
|||||||
|
|
||||||
bool AndroidQmlPreviewWorker::ensureAvdIsRunning()
|
bool AndroidQmlPreviewWorker::ensureAvdIsRunning()
|
||||||
{
|
{
|
||||||
AndroidAvdManager avdMan(m_config);
|
AndroidAvdManager avdMananager(m_androidConfig);
|
||||||
QString devSN = AndroidManager::deviceSerialNumber(m_rc->target());
|
QString devSN = AndroidManager::deviceSerialNumber(m_rc->target());
|
||||||
|
|
||||||
if (devSN.isEmpty())
|
if (devSN.isEmpty())
|
||||||
devSN = m_devInfo.serialNumber;
|
devSN = m_serialNumber;
|
||||||
|
|
||||||
if (!avdMan.isAvdBooted(devSN)) {
|
if (!avdMananager.isAvdBooted(devSN)) {
|
||||||
m_devInfo = {};
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
const IDevice *dev = DeviceKitAspect::device(m_rc->target()->kit()).data();
|
const IDevice *dev = DeviceKitAspect::device(m_rc->target()->kit()).data();
|
||||||
|
if (!dev) {
|
||||||
|
appendMessage(tr("Selected device is invalid."), ErrorMessageFormat);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (dev->deviceState() == IDevice::DeviceDisconnected) {
|
||||||
|
appendMessage(tr("Selected device is disconnected."), ErrorMessageFormat);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
AndroidDeviceInfo devInfoLocal = AndroidDevice::androidDeviceInfoFromIDevice(dev);
|
AndroidDeviceInfo devInfoLocal = AndroidDevice::androidDeviceInfoFromIDevice(dev);
|
||||||
|
|
||||||
if (devInfoLocal.isValid()) {
|
if (devInfoLocal.isValid()) {
|
||||||
if (devInfoLocal.type == AndroidDeviceInfo::Emulator) {
|
if (dev->machineType() == IDevice::Emulator) {
|
||||||
appendMessage(tr("Launching AVD."), NormalMessageFormat);
|
appendMessage(tr("Launching AVD."), NormalMessageFormat);
|
||||||
devInfoLocal.serialNumber = startAvd(avdMan, devInfoLocal.avdname);
|
devInfoLocal.serialNumber = avdMananager.startAvd(devInfoLocal.avdname);
|
||||||
}
|
}
|
||||||
if (devInfoLocal.serialNumber.isEmpty()) {
|
if (devInfoLocal.serialNumber.isEmpty()) {
|
||||||
appendMessage(tr("Could not run AVD."), ErrorMessageFormat);
|
appendMessage(tr("Could not start AVD."), ErrorMessageFormat);
|
||||||
} else {
|
} else {
|
||||||
m_devInfo = devInfoLocal;
|
m_serialNumber = devInfoLocal.serialNumber;
|
||||||
m_avdAbis = m_config.getAbis(m_config.adbToolPath(), m_devInfo.serialNumber);
|
m_avdAbis = m_androidConfig.getAbis(m_androidConfig.adbToolPath(), m_serialNumber);
|
||||||
}
|
}
|
||||||
return !devInfoLocal.serialNumber.isEmpty();
|
return !devInfoLocal.serialNumber.isEmpty();
|
||||||
} else {
|
} else {
|
||||||
@@ -283,7 +262,7 @@ bool AndroidQmlPreviewWorker::ensureAvdIsRunning()
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_avdAbis = m_config.getAbis(m_config.adbToolPath(), m_devInfo.serialNumber);
|
m_avdAbis = m_androidConfig.getAbis(m_androidConfig.adbToolPath(), m_serialNumber);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,7 +270,7 @@ bool AndroidQmlPreviewWorker::checkAndInstallPreviewApp()
|
|||||||
{
|
{
|
||||||
const QStringList command {"pm", "list", "packages", apkInfo()->appId};
|
const QStringList command {"pm", "list", "packages", apkInfo()->appId};
|
||||||
appendMessage(tr("Checking if %1 app is installed.").arg(apkInfo()->name), NormalMessageFormat);
|
appendMessage(tr("Checking if %1 app is installed.").arg(apkInfo()->name), NormalMessageFormat);
|
||||||
const SdkToolResult res = runAdbShellCommand(m_devInfo.serialNumber, command);
|
const SdkToolResult res = runAdbShellCommand(command);
|
||||||
if (!res.success()) {
|
if (!res.success()) {
|
||||||
appendMessage(res.stdErr(), ErrorMessageFormat);
|
appendMessage(res.stdErr(), ErrorMessageFormat);
|
||||||
return false;
|
return false;
|
||||||
@@ -303,7 +282,7 @@ bool AndroidQmlPreviewWorker::checkAndInstallPreviewApp()
|
|||||||
ErrorMessageFormat);
|
ErrorMessageFormat);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const FilePath apkPath = viewerApkPath(m_avdAbis.first());
|
const FilePath apkPath = designViewerApkPath(m_avdAbis.first());
|
||||||
if (!apkPath.exists()) {
|
if (!apkPath.exists()) {
|
||||||
appendMessage(tr("Cannot install %1 app for %2 architecture. "
|
appendMessage(tr("Cannot install %1 app for %2 architecture. "
|
||||||
"The appropriate APK was not found in resources folders.").
|
"The appropriate APK was not found in resources folders.").
|
||||||
@@ -313,32 +292,29 @@ bool AndroidQmlPreviewWorker::checkAndInstallPreviewApp()
|
|||||||
|
|
||||||
appendMessage(tr("Installing %1 APK.").arg(apkInfo()->name), NormalMessageFormat);
|
appendMessage(tr("Installing %1 APK.").arg(apkInfo()->name), NormalMessageFormat);
|
||||||
|
|
||||||
|
const SdkToolResult res = runAdbCommand({"install", apkPath.toString()});
|
||||||
const SdkToolResult res = runAdbCommand(m_devInfo.serialNumber, {"install",
|
if (!res.success())
|
||||||
apkPath.toString()});
|
|
||||||
if (!res.success()) {
|
|
||||||
appendMessage(res.stdErr(), StdErrFormat);
|
appendMessage(res.stdErr(), StdErrFormat);
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidQmlPreviewWorker::prepareUpload(UploadInfo &transfer)
|
return res.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AndroidQmlPreviewWorker::preparePreviewArtefacts()
|
||||||
{
|
{
|
||||||
if (m_rc->project()->id() == QmlProjectManager::Constants::QML_PROJECT_ID) {
|
if (m_rc->project()->id() == QmlProjectManager::Constants::QML_PROJECT_ID) {
|
||||||
const auto bs = m_rc->target()->buildSystem();
|
const auto bs = m_rc->target()->buildSystem();
|
||||||
if (bs) {
|
if (bs) {
|
||||||
transfer.uploadPackage = FilePath::fromString(
|
m_uploadInfo.uploadPackage = FilePath::fromString(
|
||||||
bs->additionalData(QmlProjectManager::Constants::mainFilePath).toString());
|
bs->additionalData(QmlProjectManager::Constants::mainFilePath).toString());
|
||||||
transfer.projectFolder = bs->projectDirectory();
|
m_uploadInfo.projectFolder = bs->projectDirectory();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const FilePaths allFiles = m_rc->project()->files(m_rc->project()->SourceFiles);
|
const FilePaths allFiles = m_rc->project()->files(m_rc->project()->SourceFiles);
|
||||||
const FilePaths filesToExport = Utils::filtered(allFiles,[](const FilePath &path) {
|
const FilePaths filesToExport = Utils::filtered(allFiles,[](const FilePath &path) {
|
||||||
return path.suffix() == "qmlproject";});
|
return path.suffix() == "qmlproject";
|
||||||
|
});
|
||||||
|
|
||||||
if (filesToExport.size() > 1) {
|
if (filesToExport.size() > 1) {
|
||||||
appendMessage(tr("Too many .qmlproject files in your project. Open directly the "
|
appendMessage(tr("Too many .qmlproject files in your project. Open directly the "
|
||||||
@@ -348,10 +324,9 @@ bool AndroidQmlPreviewWorker::prepareUpload(UploadInfo &transfer)
|
|||||||
appendMessage(tr("No .qmlproject file found among project files."), ErrorMessageFormat);
|
appendMessage(tr("No .qmlproject file found among project files."), ErrorMessageFormat);
|
||||||
} else {
|
} else {
|
||||||
const FilePath qmlprojectFile = filesToExport.first();
|
const FilePath qmlprojectFile = filesToExport.first();
|
||||||
transfer.uploadPackage = transfer.
|
m_uploadInfo.uploadPackage = m_uploadInfo.projectFolder.resolvePath(
|
||||||
projectFolder.
|
qmlprojectFile.fileName());
|
||||||
resolvePath(qmlprojectFile.fileName());
|
m_uploadInfo.projectFolder = qmlprojectFile.parentDir();
|
||||||
transfer.projectFolder = qmlprojectFile.parentDir();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -366,16 +341,15 @@ FilePath AndroidQmlPreviewWorker::createQmlrcFile(const FilePath &workFolder,
|
|||||||
const FilePath rccBinary = qtVersion->rccFilePath();
|
const FilePath rccBinary = qtVersion->rccFilePath();
|
||||||
QtcProcess rccProcess;
|
QtcProcess rccProcess;
|
||||||
FilePath qrcPath = FilePath::fromString(basename) + ".qrc4viewer";
|
FilePath qrcPath = FilePath::fromString(basename) + ".qrc4viewer";
|
||||||
const FilePath qmlrcPath = FilePath::fromString(QDir::tempPath() + "/" + basename +
|
const FilePath qmlrcPath = FilePath::fromString(QDir::tempPath()) / basename + packageSuffix;
|
||||||
packageSuffix);
|
|
||||||
|
|
||||||
rccProcess.setWorkingDirectory(workFolder);
|
rccProcess.setWorkingDirectory(workFolder);
|
||||||
|
|
||||||
const QStringList arguments[2] = {{"--project", "--output", qrcPath.fileName()},
|
const QStringList arguments[2] = {{"--project", "--output", qrcPath.fileName()},
|
||||||
{"--binary", "--output", qmlrcPath.path(),
|
{"--binary", "--output", qmlrcPath.path(),
|
||||||
qrcPath.fileName()}};
|
qrcPath.fileName()}};
|
||||||
for (const auto &arguments : arguments) {
|
for (const QStringList &args : arguments) {
|
||||||
rccProcess.setCommand({rccBinary, arguments});
|
rccProcess.setCommand({rccBinary, args});
|
||||||
rccProcess.start();
|
rccProcess.start();
|
||||||
if (!rccProcess.waitForStarted()) {
|
if (!rccProcess.waitForStarted()) {
|
||||||
appendMessage(tr("Could not create file for %1 \"%2\"").
|
appendMessage(tr("Could not create file for %1 \"%2\"").
|
||||||
@@ -420,72 +394,55 @@ FilePath AndroidQmlPreviewWorker::createQmlrcFile(const FilePath &workFolder,
|
|||||||
return qmlrcPath;
|
return qmlrcPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidQmlPreviewWorker::uploadFiles(const UploadInfo &transfer)
|
bool AndroidQmlPreviewWorker::uploadPreviewArtefacts()
|
||||||
{
|
{
|
||||||
appendMessage(tr("Uploading files."), NormalMessageFormat);
|
appendMessage(tr("Uploading files."), NormalMessageFormat);
|
||||||
|
const FilePath qresPath = createQmlrcFile(m_uploadInfo.projectFolder,
|
||||||
const FilePath qresPath = createQmlrcFile(FilePath::fromString(transfer.projectFolder.path()),
|
m_uploadInfo.uploadPackage.baseName());
|
||||||
transfer.uploadPackage.baseName());
|
|
||||||
if (!qresPath.exists())
|
if (!qresPath.exists())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
runAdbShellCommand(m_devInfo.serialNumber, {"mkdir", "-p", apkInfo()->uploadDir});
|
runAdbShellCommand({"mkdir", "-p", apkInfo()->uploadDir});
|
||||||
|
const SdkToolResult res = runAdbCommand({"push", qresPath.resolvePath(QString()).toString(),
|
||||||
const SdkToolResult res = runAdbCommand(m_devInfo.serialNumber,
|
|
||||||
{"push", qresPath.resolvePath(QString()).toString(),
|
|
||||||
apkInfo()->uploadDir});
|
apkInfo()->uploadDir});
|
||||||
if (!res.success()) {
|
if (!res.success()) {
|
||||||
appendMessage(res.stdOut(), ErrorMessageFormat);
|
appendMessage(res.stdOut(), ErrorMessageFormat);
|
||||||
if (res.stdOut().contains("Permission denied"))
|
if (res.stdOut().contains("Permission denied")) {
|
||||||
appendMessage("'Permission denied' error detected. Try restarting your device "
|
appendMessage("'Permission denied' error detected. Try restarting your device "
|
||||||
"and then running the preview.", NormalMessageFormat);
|
"and then running the preview.", NormalMessageFormat);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
qresPath.removeFile();
|
qresPath.removeFile();
|
||||||
return res.success();
|
return res.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidQmlPreviewWorker::runPreviewApp(const UploadInfo &transfer)
|
bool AndroidQmlPreviewWorker::startPreviewApp()
|
||||||
{
|
{
|
||||||
stopPreviewApp();
|
stopPreviewApp();
|
||||||
appendMessage(tr("Starting %1.").arg(apkInfo()->name), NormalMessageFormat);
|
appendMessage(tr("Starting %1.").arg(apkInfo()->name), NormalMessageFormat);
|
||||||
const QDir destDir(apkInfo()->uploadDir);
|
const QDir destDir(apkInfo()->uploadDir);
|
||||||
|
const QString qmlrcPath = destDir.filePath(m_uploadInfo.uploadPackage.baseName()
|
||||||
|
+ packageSuffix);
|
||||||
const QStringList command{"am", "start",
|
const QStringList command{"am", "start",
|
||||||
"-n", apkInfo()->activityId,
|
"-n", apkInfo()->activityId,
|
||||||
"-e", "extraappparams",
|
"-e", "extraappparams", QLatin1String(qmlrcPath.toUtf8().toBase64())};
|
||||||
QString::fromLatin1(
|
const SdkToolResult result = runAdbShellCommand(command);
|
||||||
destDir.filePath(transfer.uploadPackage.baseName() + packageSuffix).
|
if (result.success())
|
||||||
toUtf8().
|
|
||||||
toBase64())};
|
|
||||||
const SdkToolResult res = runAdbShellCommand(m_devInfo.serialNumber, command);
|
|
||||||
if (!res.success()) {
|
|
||||||
appendMessage(res.stdErr(), ErrorMessageFormat);
|
|
||||||
return res.success();
|
|
||||||
}
|
|
||||||
appendMessage(tr("%1 is running.").arg(apkInfo()->name), NormalMessageFormat);
|
appendMessage(tr("%1 is running.").arg(apkInfo()->name), NormalMessageFormat);
|
||||||
m_viewerPid = pidofPreview(m_devInfo.serialNumber);
|
else
|
||||||
return true;
|
appendMessage(result.stdErr(), ErrorMessageFormat);
|
||||||
|
|
||||||
|
return result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidQmlPreviewWorker::stopPreviewApp()
|
bool AndroidQmlPreviewWorker::stopPreviewApp()
|
||||||
{
|
{
|
||||||
const QStringList command{"am", "force-stop", apkInfo()->appId};
|
const QStringList command{"am", "force-stop", apkInfo()->appId};
|
||||||
const SdkToolResult res = runAdbShellCommand(m_devInfo.serialNumber, command);
|
const SdkToolResult res = runAdbShellCommand(command);
|
||||||
if (!res.success()) {
|
if (!res.success())
|
||||||
appendMessage(res.stdErr(), ErrorMessageFormat);
|
appendMessage(res.stdErr(), ErrorMessageFormat);
|
||||||
return res.success();
|
return res.success();
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AndroidQmlPreviewWorker::appendLogLines(const QStringList & lines)
|
|
||||||
{
|
|
||||||
for (const QString& line : lines) {
|
|
||||||
const int charsToSkip = apkInfo()->name.length() + 2; // strlen(": ") == 2
|
|
||||||
const QString formatted = line.mid(line.indexOf(apkInfo()->name) + charsToSkip);
|
|
||||||
// TODO: See AndroidRunnerWorker::logcatProcess() - filtering for logs to decide format.
|
|
||||||
appendMessage(formatted, StdOutFormat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Android
|
} // namespace Android
|
||||||
|
@@ -25,9 +25,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "androidconfigurations.h"
|
#include "androidconfigurations.h"
|
||||||
|
|
||||||
#include <projectexplorer/runcontrol.h>
|
#include <projectexplorer/runcontrol.h>
|
||||||
#include <utils/environment.h>
|
#include <utils/environment.h>
|
||||||
|
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
|
||||||
namespace Android {
|
namespace Android {
|
||||||
class SdkToolResult;
|
class SdkToolResult;
|
||||||
|
|
||||||
@@ -45,6 +48,10 @@ class AndroidQmlPreviewWorker : public ProjectExplorer::RunWorker
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
AndroidQmlPreviewWorker(ProjectExplorer::RunControl *runControl);
|
AndroidQmlPreviewWorker(ProjectExplorer::RunControl *runControl);
|
||||||
|
~AndroidQmlPreviewWorker();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void previewPidChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void start() override;
|
void start() override;
|
||||||
@@ -52,22 +59,33 @@ private:
|
|||||||
|
|
||||||
bool ensureAvdIsRunning();
|
bool ensureAvdIsRunning();
|
||||||
bool checkAndInstallPreviewApp();
|
bool checkAndInstallPreviewApp();
|
||||||
bool prepareUpload(UploadInfo &transfer);
|
bool preparePreviewArtefacts();
|
||||||
bool uploadFiles(const UploadInfo &transfer);
|
bool uploadPreviewArtefacts();
|
||||||
|
|
||||||
bool runPreviewApp(const UploadInfo &transfer);
|
SdkToolResult runAdbCommand(const QStringList &arguments) const;
|
||||||
|
SdkToolResult runAdbShellCommand(const QStringList &arguments) const;
|
||||||
|
int pidofPreview() const;
|
||||||
|
bool isPreviewRunning(int lastKnownPid = -1) const;
|
||||||
|
|
||||||
|
void startPidWatcher();
|
||||||
|
void startLogcat();
|
||||||
|
void filterLogcatAndAppendMessage(const QString &stdOut);
|
||||||
|
|
||||||
|
bool startPreviewApp();
|
||||||
bool stopPreviewApp();
|
bool stopPreviewApp();
|
||||||
|
|
||||||
void startLogcat();
|
Utils::FilePath designViewerApkPath(const QString &abi) const;
|
||||||
void appendLogLines(const QStringList &lines);
|
|
||||||
|
|
||||||
Utils::FilePath createQmlrcFile(const Utils::FilePath &workFolder, const QString &basename);
|
Utils::FilePath createQmlrcFile(const Utils::FilePath &workFolder, const QString &basename);
|
||||||
|
|
||||||
ProjectExplorer::RunControl *m_rc = nullptr;
|
ProjectExplorer::RunControl *m_rc = nullptr;
|
||||||
AndroidConfig m_config;
|
AndroidConfig m_androidConfig;
|
||||||
AndroidDeviceInfo m_devInfo;
|
QString m_serialNumber;
|
||||||
QStringList m_avdAbis;
|
QStringList m_avdAbis;
|
||||||
int m_viewerPid = -1;
|
int m_viewerPid = -1;
|
||||||
|
QFutureWatcher<void> m_pidFutureWatcher;
|
||||||
|
Utils::QtcProcess m_logcatProcess;
|
||||||
|
QString m_logcatStartTimeStamp;
|
||||||
|
UploadInfo m_uploadInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -123,7 +123,7 @@ void DeviceSelectorDetailsPanel::refresh()
|
|||||||
m_memoryView->refresh();
|
m_memoryView->refresh();
|
||||||
m_algorithmView->refresh();
|
m_algorithmView->refresh();
|
||||||
m_algorithmView->setAlgorithm(m_selection.algorithmIndex);
|
m_algorithmView->setAlgorithm(m_selection.algorithmIndex);
|
||||||
m_peripheralDescriptionFileChooser->setPath(m_selection.svd);
|
m_peripheralDescriptionFileChooser->setFilePath(Utils::FilePath::fromString(m_selection.svd));
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeviceSelector
|
// DeviceSelector
|
||||||
|
@@ -2616,7 +2616,9 @@ static void semanticHighlighter(QFutureInterface<HighlightingResult> &future,
|
|||||||
} else if (token.type == "type") {
|
} else if (token.type == "type") {
|
||||||
styles.mainStyle = C_TYPE;
|
styles.mainStyle = C_TYPE;
|
||||||
} else if (token.type == "typeParameter") {
|
} else if (token.type == "typeParameter") {
|
||||||
styles.mainStyle = C_TYPE;
|
// clangd reports both type and non-type template parameters as type parameters,
|
||||||
|
// but the latter can be distinguished by the readonly modifier.
|
||||||
|
styles.mainStyle = token.modifiers.contains("readonly") ? C_PARAMETER : C_TYPE;
|
||||||
}
|
}
|
||||||
if (token.modifiers.contains("declaration"))
|
if (token.modifiers.contains("declaration"))
|
||||||
styles.mixinStyles.push_back(C_DECLARATION);
|
styles.mixinStyles.push_back(C_DECLARATION);
|
||||||
|
@@ -506,9 +506,6 @@ void ClangdTestLocalReferences::test()
|
|||||||
client()->findLocalUsages(doc, cursor, std::move(handler));
|
client()->findLocalUsages(doc, cursor, std::move(handler));
|
||||||
timer.start(10000);
|
timer.start(10000);
|
||||||
loop.exec();
|
loop.exec();
|
||||||
QEXPECT_FAIL("cursor not on identifier", "clangd bug: go to definition does not return", Abort);
|
|
||||||
QEXPECT_FAIL("template parameter member access",
|
|
||||||
"clangd bug: go to definition does not return", Abort);
|
|
||||||
QVERIFY(timer.isActive());
|
QVERIFY(timer.isActive());
|
||||||
timer.stop();
|
timer.stop();
|
||||||
|
|
||||||
@@ -909,7 +906,7 @@ void ClangdTestHighlighting::test_data()
|
|||||||
QTest::newRow("template parameter default argument") << 265 << 41 << 265 << 44
|
QTest::newRow("template parameter default argument") << 265 << 41 << 265 << 44
|
||||||
<< QList<int>{C_TYPE} << 0;
|
<< QList<int>{C_TYPE} << 0;
|
||||||
QTest::newRow("template non-type parameter") << 265 << 50 << 265 << 74
|
QTest::newRow("template non-type parameter") << 265 << 50 << 265 << 74
|
||||||
<< QList<int>{C_LOCAL, C_DECLARATION} << 0;
|
<< QList<int>{C_PARAMETER, C_DECLARATION} << 0;
|
||||||
QTest::newRow("template non-type parameter default argument") << 265 << 77 << 265 << 78
|
QTest::newRow("template non-type parameter default argument") << 265 << 77 << 265 << 78
|
||||||
<< QList<int>{C_NUMBER} << 0;
|
<< QList<int>{C_NUMBER} << 0;
|
||||||
QTest::newRow("template template parameter") << 265 << 103 << 265 << 128
|
QTest::newRow("template template parameter") << 265 << 103 << 265 << 128
|
||||||
@@ -935,7 +932,7 @@ void ClangdTestHighlighting::test_data()
|
|||||||
QTest::newRow("local var declaration of template parameter type") << 268 << 27 << 268 << 57
|
QTest::newRow("local var declaration of template parameter type") << 268 << 27 << 268 << 57
|
||||||
<< QList<int>{C_LOCAL, C_DECLARATION} << 0;
|
<< QList<int>{C_LOCAL, C_DECLARATION} << 0;
|
||||||
QTest::newRow("reference to non-type template parameter") << 269 << 46 << 269 << 70
|
QTest::newRow("reference to non-type template parameter") << 269 << 46 << 269 << 70
|
||||||
<< QList<int>{C_LOCAL} << 0;
|
<< QList<int>{C_PARAMETER} << 0;
|
||||||
QTest::newRow("local var declaration initialized with non-type template parameter")
|
QTest::newRow("local var declaration initialized with non-type template parameter")
|
||||||
<< 269 << 10 << 269 << 43
|
<< 269 << 10 << 269 << 43
|
||||||
<< QList<int>{C_LOCAL, C_DECLARATION} << 0;
|
<< QList<int>{C_LOCAL, C_DECLARATION} << 0;
|
||||||
@@ -1331,12 +1328,6 @@ void ClangdTestHighlighting::test()
|
|||||||
QEXPECT_FAIL("non-final virtual function call via pointer",
|
QEXPECT_FAIL("non-final virtual function call via pointer",
|
||||||
"clangd < 14 does not send virtual modifier", Continue);
|
"clangd < 14 does not send virtual modifier", Continue);
|
||||||
}
|
}
|
||||||
QEXPECT_FAIL("template non-type parameter",
|
|
||||||
"FIXME: clangd reports non-type template parameters at \"typeParameter\"",
|
|
||||||
Continue);
|
|
||||||
QEXPECT_FAIL("reference to non-type template parameter",
|
|
||||||
"FIXME: clangd reports non-type template parameters at \"typeParameter\"",
|
|
||||||
Continue);
|
|
||||||
QEXPECT_FAIL("non-const reference via member function call as output argument (function)",
|
QEXPECT_FAIL("non-const reference via member function call as output argument (function)",
|
||||||
"Without punctuation and comment tokens from clangd, it's not possible "
|
"Without punctuation and comment tokens from clangd, it's not possible "
|
||||||
"to highlight entire expressions. But do we really want this? What about nested "
|
"to highlight entire expressions. But do we really want this? What about nested "
|
||||||
@@ -1627,7 +1618,7 @@ void ClangdTestCompletion::testFunctionHintsFiltered()
|
|||||||
QVERIFY(proposal);
|
QVERIFY(proposal);
|
||||||
QCOMPARE(proposal->size(), 2);
|
QCOMPARE(proposal->size(), 2);
|
||||||
QVERIFY(hasItem(proposal, "func(const S &s, <b>int j</b>) -> void"));
|
QVERIFY(hasItem(proposal, "func(const S &s, <b>int j</b>) -> void"));
|
||||||
QEXPECT_FAIL("", "FIXME: LanguageClient handles active parameter only in active signature", Abort);
|
QEXPECT_FAIL("", "QTCREATORBUG-26346", Abort);
|
||||||
QVERIFY(hasItem(proposal, "func(const S &s, <b>int j</b>, int k) -> void"));
|
QVERIFY(hasItem(proposal, "func(const S &s, <b>int j</b>, int k) -> void"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1640,7 +1631,7 @@ void ClangdTestCompletion::testFunctionHintConstructor()
|
|||||||
QVERIFY(!hasItem(proposal, "globalVariable"));
|
QVERIFY(!hasItem(proposal, "globalVariable"));
|
||||||
QVERIFY(!hasItem(proposal, " class"));
|
QVERIFY(!hasItem(proposal, " class"));
|
||||||
QVERIFY(hasItem(proposal, "Foo(<b>int</b>)"));
|
QVERIFY(hasItem(proposal, "Foo(<b>int</b>)"));
|
||||||
QEXPECT_FAIL("", "FIXME: LanguageClient handles active parameter only in active signature", Abort);
|
QEXPECT_FAIL("", "QTCREATORBUG-26346", Abort);
|
||||||
QVERIFY(hasItem(proposal, "Foo(<b>int</b>, double)"));
|
QVERIFY(hasItem(proposal, "Foo(<b>int</b>, double)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1669,8 +1660,7 @@ void ClangdTestCompletion::testCompletePrivateFunctionDefinition()
|
|||||||
getProposal("privateFuncDefCompletion.cpp", proposal);
|
getProposal("privateFuncDefCompletion.cpp", proposal);
|
||||||
|
|
||||||
QVERIFY(proposal);
|
QVERIFY(proposal);
|
||||||
QEXPECT_FAIL("", "FIXME: clangd needs to differentiate "
|
QEXPECT_FAIL("", "https://github.com/clangd/clangd/issues/880", Abort);
|
||||||
"between function call and function definiton", Abort);
|
|
||||||
QCOMPARE(proposal->size(), 1);
|
QCOMPARE(proposal->size(), 1);
|
||||||
QVERIFY(hasItem(proposal, " theFunc()"));
|
QVERIFY(hasItem(proposal, " theFunc()"));
|
||||||
}
|
}
|
||||||
|
@@ -67,7 +67,7 @@ SettingsPageWidget::SettingsPageWidget()
|
|||||||
|
|
||||||
const ClearCaseSettings &s = ClearCasePlugin::settings();
|
const ClearCaseSettings &s = ClearCasePlugin::settings();
|
||||||
|
|
||||||
m_ui.commandPathChooser->setPath(s.ccCommand);
|
m_ui.commandPathChooser->setFilePath(FilePath::fromString(s.ccCommand));
|
||||||
m_ui.timeOutSpinBox->setValue(s.timeOutS);
|
m_ui.timeOutSpinBox->setValue(s.timeOutS);
|
||||||
m_ui.autoCheckOutCheckBox->setChecked(s.autoCheckOut);
|
m_ui.autoCheckOutCheckBox->setChecked(s.autoCheckOut);
|
||||||
m_ui.noCommentCheckBox->setChecked(s.noComment);
|
m_ui.noCommentCheckBox->setChecked(s.noComment);
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#include "cmakeprojectnodes.h"
|
#include "cmakeprojectnodes.h"
|
||||||
#include "cmakeprojectplugin.h"
|
#include "cmakeprojectplugin.h"
|
||||||
#include "cmakespecificsettings.h"
|
#include "cmakespecificsettings.h"
|
||||||
|
#include "projecttreehelper.h"
|
||||||
#include "utils/algorithm.h"
|
#include "utils/algorithm.h"
|
||||||
|
|
||||||
#include <android/androidconstants.h>
|
#include <android/androidconstants.h>
|
||||||
@@ -158,8 +159,7 @@ CMakeBuildSystem::CMakeBuildSystem(CMakeBuildConfiguration *bc)
|
|||||||
|
|
||||||
m_treeScanner.setFilter([this](const MimeType &mimeType, const FilePath &fn) {
|
m_treeScanner.setFilter([this](const MimeType &mimeType, const FilePath &fn) {
|
||||||
// Mime checks requires more resources, so keep it last in check list
|
// Mime checks requires more resources, so keep it last in check list
|
||||||
auto isIgnored = fn.toString().startsWith(projectFilePath().toString() + ".user")
|
auto isIgnored = TreeScanner::isWellKnownBinary(mimeType, fn);
|
||||||
|| TreeScanner::isWellKnownBinary(mimeType, fn);
|
|
||||||
|
|
||||||
// Cache mime check result for speed up
|
// Cache mime check result for speed up
|
||||||
if (!isIgnored) {
|
if (!isIgnored) {
|
||||||
@@ -213,7 +213,6 @@ CMakeBuildSystem::~CMakeBuildSystem()
|
|||||||
|
|
||||||
delete m_cppCodeModelUpdater;
|
delete m_cppCodeModelUpdater;
|
||||||
qDeleteAll(m_extraCompilers);
|
qDeleteAll(m_extraCompilers);
|
||||||
qDeleteAll(m_allFiles.allFiles);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::triggerParsing()
|
void CMakeBuildSystem::triggerParsing()
|
||||||
@@ -244,28 +243,11 @@ void CMakeBuildSystem::triggerParsing()
|
|||||||
|
|
||||||
qCDebug(cmakeBuildSystemLog) << "ParseGuard acquired.";
|
qCDebug(cmakeBuildSystemLog) << "ParseGuard acquired.";
|
||||||
|
|
||||||
if (m_allFiles.allFiles.isEmpty()) {
|
|
||||||
qCDebug(cmakeBuildSystemLog)
|
|
||||||
<< "No treescanner information available, forcing treescanner run.";
|
|
||||||
updateReparseParameters(REPARSE_SCAN);
|
|
||||||
}
|
|
||||||
|
|
||||||
int reparseParameters = takeReparseParameters();
|
int reparseParameters = takeReparseParameters();
|
||||||
|
|
||||||
m_waitingForScan = (reparseParameters & REPARSE_SCAN) != 0;
|
|
||||||
m_waitingForParse = true;
|
m_waitingForParse = true;
|
||||||
m_combinedScanAndParseResult = true;
|
m_combinedScanAndParseResult = true;
|
||||||
|
|
||||||
if (m_waitingForScan) {
|
|
||||||
qCDebug(cmakeBuildSystemLog) << "Starting TreeScanner";
|
|
||||||
QTC_CHECK(m_treeScanner.isFinished());
|
|
||||||
if (m_treeScanner.asyncScanForFiles(projectDirectory()))
|
|
||||||
Core::ProgressManager::addTask(m_treeScanner.future(),
|
|
||||||
tr("Scan \"%1\" project tree")
|
|
||||||
.arg(project()->displayName()),
|
|
||||||
"CMake.Scan.Tree");
|
|
||||||
}
|
|
||||||
|
|
||||||
QTC_ASSERT(m_parameters.isValid(), return );
|
QTC_ASSERT(m_parameters.isValid(), return );
|
||||||
|
|
||||||
TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
|
TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
|
||||||
@@ -365,8 +347,6 @@ QString CMakeBuildSystem::reparseParametersString(int reparseFlags)
|
|||||||
result += " FORCE_CMAKE_RUN";
|
result += " FORCE_CMAKE_RUN";
|
||||||
if (reparseFlags & REPARSE_FORCE_INITIAL_CONFIGURATION)
|
if (reparseFlags & REPARSE_FORCE_INITIAL_CONFIGURATION)
|
||||||
result += " FORCE_CONFIG";
|
result += " FORCE_CONFIG";
|
||||||
if (reparseFlags & REPARSE_SCAN)
|
|
||||||
result += " SCAN";
|
|
||||||
}
|
}
|
||||||
return result.trimmed();
|
return result.trimmed();
|
||||||
}
|
}
|
||||||
@@ -442,7 +422,7 @@ void CMakeBuildSystem::runCMakeAndScanProjectTree()
|
|||||||
BuildDirParameters parameters(cmakeBuildConfiguration());
|
BuildDirParameters parameters(cmakeBuildConfiguration());
|
||||||
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to \"Rescan Project\" command";
|
qCDebug(cmakeBuildSystemLog) << "Requesting parse due to \"Rescan Project\" command";
|
||||||
setParametersAndRequestParse(parameters,
|
setParametersAndRequestParse(parameters,
|
||||||
REPARSE_FORCE_CMAKE_RUN | REPARSE_SCAN | REPARSE_URGENT);
|
REPARSE_FORCE_CMAKE_RUN | REPARSE_URGENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::runCMakeWithExtraArguments()
|
void CMakeBuildSystem::runCMakeWithExtraArguments()
|
||||||
@@ -461,18 +441,6 @@ void CMakeBuildSystem::buildCMakeTarget(const QString &buildTarget)
|
|||||||
cmakeBuildConfiguration()->buildTarget(buildTarget);
|
cmakeBuildConfiguration()->buildTarget(buildTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::handleTreeScanningFinished()
|
|
||||||
{
|
|
||||||
QTC_CHECK(m_waitingForScan);
|
|
||||||
|
|
||||||
qDeleteAll(m_allFiles.allFiles);
|
|
||||||
m_allFiles = m_treeScanner.release();
|
|
||||||
|
|
||||||
m_waitingForScan = false;
|
|
||||||
|
|
||||||
combineScanAndParse(m_reader.lastCMakeExitCode() != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CMakeBuildSystem::persistCMakeState()
|
bool CMakeBuildSystem::persistCMakeState()
|
||||||
{
|
{
|
||||||
BuildDirParameters parameters(cmakeBuildConfiguration());
|
BuildDirParameters parameters(cmakeBuildConfiguration());
|
||||||
@@ -524,17 +492,10 @@ void CMakeBuildSystem::clearCMakeCache()
|
|||||||
path.removeRecursively();
|
path.removeRecursively();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<CMakeProjectNode> CMakeBuildSystem::generateProjectTree(
|
|
||||||
const TreeScanner::Result &allFiles, bool failedToParse)
|
|
||||||
{
|
|
||||||
auto root = m_reader.generateProjectTree(allFiles, failedToParse);
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMakeBuildSystem::combineScanAndParse(bool restoredFromBackup)
|
void CMakeBuildSystem::combineScanAndParse(bool restoredFromBackup)
|
||||||
{
|
{
|
||||||
if (cmakeBuildConfiguration()->isActive()) {
|
if (cmakeBuildConfiguration()->isActive()) {
|
||||||
if (m_waitingForParse || m_waitingForScan)
|
if (m_waitingForParse)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_combinedScanAndParseResult) {
|
if (m_combinedScanAndParseResult) {
|
||||||
@@ -548,6 +509,15 @@ void CMakeBuildSystem::combineScanAndParse(bool restoredFromBackup)
|
|||||||
"<p>The backup of the previous configuration has been restored.</p>"
|
"<p>The backup of the previous configuration has been restored.</p>"
|
||||||
"<p>Have a look at the Issues pane or in the \"Projects > Build\" settings "
|
"<p>Have a look at the Issues pane or in the \"Projects > Build\" settings "
|
||||||
"for more information about the failure.</p"));
|
"for more information about the failure.</p"));
|
||||||
|
|
||||||
|
m_reader.resetData();
|
||||||
|
|
||||||
|
m_currentGuard = {};
|
||||||
|
m_testNames.clear();
|
||||||
|
|
||||||
|
emitBuildSystemUpdated();
|
||||||
|
|
||||||
|
runCTest();
|
||||||
} else {
|
} else {
|
||||||
updateFallbackProjectData();
|
updateFallbackProjectData();
|
||||||
|
|
||||||
@@ -558,15 +528,6 @@ void CMakeBuildSystem::combineScanAndParse(bool restoredFromBackup)
|
|||||||
"for more information about the failure.</p"));
|
"for more information about the failure.</p"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_reader.resetData();
|
|
||||||
|
|
||||||
m_currentGuard = {};
|
|
||||||
m_testNames.clear();
|
|
||||||
|
|
||||||
emitBuildSystemUpdated();
|
|
||||||
|
|
||||||
runCTest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::checkAndReportError(QString &errorMessage)
|
void CMakeBuildSystem::checkAndReportError(QString &errorMessage)
|
||||||
@@ -614,7 +575,7 @@ void CMakeBuildSystem::updateProjectData()
|
|||||||
|
|
||||||
Project *p = project();
|
Project *p = project();
|
||||||
{
|
{
|
||||||
auto newRoot = generateProjectTree(m_allFiles, false);
|
auto newRoot = m_reader.rootProjectNode();
|
||||||
if (newRoot) {
|
if (newRoot) {
|
||||||
setRootProjectNode(std::move(newRoot));
|
setRootProjectNode(std::move(newRoot));
|
||||||
|
|
||||||
@@ -707,16 +668,51 @@ void CMakeBuildSystem::updateProjectData()
|
|||||||
qCDebug(cmakeBuildSystemLog) << "All CMake project data up to date.";
|
qCDebug(cmakeBuildSystemLog) << "All CMake project data up to date.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMakeBuildSystem::handleTreeScanningFinished()
|
||||||
|
{
|
||||||
|
TreeScanner::Result result = m_treeScanner.release();
|
||||||
|
m_allFiles = result.folderNode;
|
||||||
|
qDeleteAll(result.allFiles);
|
||||||
|
|
||||||
|
updateFileSystemNodes();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMakeBuildSystem::updateFileSystemNodes()
|
||||||
|
{
|
||||||
|
auto newRoot = std::make_unique<CMakeProjectNode>(m_parameters.sourceDirectory);
|
||||||
|
newRoot->setDisplayName(m_parameters.sourceDirectory.fileName());
|
||||||
|
|
||||||
|
if (!m_reader.topCmakeFile().isEmpty()) {
|
||||||
|
auto node = std::make_unique<FileNode>(m_reader.topCmakeFile(), FileType::Project);
|
||||||
|
node->setIsGenerated(false);
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<FileNode>> fileNodes;
|
||||||
|
fileNodes.emplace_back(std::move(node));
|
||||||
|
|
||||||
|
addCMakeLists(newRoot.get(), std::move(fileNodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
addFileSystemNodes(newRoot.get(), m_allFiles);
|
||||||
|
setRootProjectNode(std::move(newRoot));
|
||||||
|
|
||||||
|
m_reader.resetData();
|
||||||
|
|
||||||
|
m_currentGuard = {};
|
||||||
|
emitBuildSystemUpdated();
|
||||||
|
|
||||||
|
qCDebug(cmakeBuildSystemLog) << "All fallback CMake project data up to date.";
|
||||||
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::updateFallbackProjectData()
|
void CMakeBuildSystem::updateFallbackProjectData()
|
||||||
{
|
{
|
||||||
qCDebug(cmakeBuildSystemLog) << "Updating fallback CMake project data";
|
qCDebug(cmakeBuildSystemLog) << "Updating fallback CMake project data";
|
||||||
|
qCDebug(cmakeBuildSystemLog) << "Starting TreeScanner";
|
||||||
QTC_ASSERT(m_treeScanner.isFinished() && !m_reader.isParsing(), return );
|
QTC_CHECK(m_treeScanner.isFinished());
|
||||||
|
if (m_treeScanner.asyncScanForFiles(projectDirectory()))
|
||||||
auto newRoot = generateProjectTree(m_allFiles, true);
|
Core::ProgressManager::addTask(m_treeScanner.future(),
|
||||||
setRootProjectNode(std::move(newRoot));
|
tr("Scan \"%1\" project tree")
|
||||||
|
.arg(project()->displayName()),
|
||||||
qCDebug(cmakeBuildSystemLog) << "All fallback CMake project data up to date.";
|
"CMake.Scan.Tree");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::updateCMakeConfiguration(QString &errorMessage)
|
void CMakeBuildSystem::updateCMakeConfiguration(QString &errorMessage)
|
||||||
@@ -899,7 +895,7 @@ void CMakeBuildSystem::becameDirty()
|
|||||||
if (isParsing())
|
if (isParsing())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()), REPARSE_SCAN);
|
setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()), REPARSE_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::updateReparseParameters(const int parameters)
|
void CMakeBuildSystem::updateReparseParameters(const int parameters)
|
||||||
|
@@ -37,7 +37,10 @@
|
|||||||
#include <utils/temporarydirectory.h>
|
#include <utils/temporarydirectory.h>
|
||||||
|
|
||||||
namespace CppEditor { class CppProjectUpdater; }
|
namespace CppEditor { class CppProjectUpdater; }
|
||||||
namespace ProjectExplorer { class ExtraCompiler; }
|
namespace ProjectExplorer {
|
||||||
|
class ExtraCompiler;
|
||||||
|
class FolderNode;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CMakeProjectManager {
|
namespace CMakeProjectManager {
|
||||||
|
|
||||||
@@ -113,8 +116,7 @@ private:
|
|||||||
REPARSE_FORCE_INITIAL_CONFIGURATION
|
REPARSE_FORCE_INITIAL_CONFIGURATION
|
||||||
= (1 << 1), // Force initial configuration arguments to cmake
|
= (1 << 1), // Force initial configuration arguments to cmake
|
||||||
REPARSE_FORCE_EXTRA_CONFIGURATION = (1 << 2), // Force extra configuration arguments to cmake
|
REPARSE_FORCE_EXTRA_CONFIGURATION = (1 << 2), // Force extra configuration arguments to cmake
|
||||||
REPARSE_SCAN = (1 << 3), // Run filesystem scan
|
REPARSE_URGENT = (1 << 3), // Do not delay the parser run by 1s
|
||||||
REPARSE_URGENT = (1 << 4), // Do not delay the parser run by 1s
|
|
||||||
};
|
};
|
||||||
QString reparseParametersString(int reparseFlags);
|
QString reparseParametersString(int reparseFlags);
|
||||||
void setParametersAndRequestParse(const BuildDirParameters ¶meters,
|
void setParametersAndRequestParse(const BuildDirParameters ¶meters,
|
||||||
@@ -132,9 +134,6 @@ private:
|
|||||||
|
|
||||||
// Combining Treescanner and Parser states:
|
// Combining Treescanner and Parser states:
|
||||||
void combineScanAndParse(bool restoredFromBackup);
|
void combineScanAndParse(bool restoredFromBackup);
|
||||||
|
|
||||||
std::unique_ptr<CMakeProjectNode> generateProjectTree(
|
|
||||||
const ProjectExplorer::TreeScanner::Result &allFiles, bool failedToParse);
|
|
||||||
void checkAndReportError(QString &errorMessage);
|
void checkAndReportError(QString &errorMessage);
|
||||||
|
|
||||||
void updateCMakeConfiguration(QString &errorMessage);
|
void updateCMakeConfiguration(QString &errorMessage);
|
||||||
@@ -146,6 +145,8 @@ private:
|
|||||||
const QList<QByteArray> &moduleMappings);
|
const QList<QByteArray> &moduleMappings);
|
||||||
void updateInitialCMakeExpandableVars();
|
void updateInitialCMakeExpandableVars();
|
||||||
|
|
||||||
|
void updateFileSystemNodes();
|
||||||
|
|
||||||
void handleParsingSucceeded(bool restoredFromBackup);
|
void handleParsingSucceeded(bool restoredFromBackup);
|
||||||
void handleParsingFailed(const QString &msg);
|
void handleParsingFailed(const QString &msg);
|
||||||
|
|
||||||
@@ -161,10 +162,9 @@ private:
|
|||||||
void runCTest();
|
void runCTest();
|
||||||
|
|
||||||
ProjectExplorer::TreeScanner m_treeScanner;
|
ProjectExplorer::TreeScanner m_treeScanner;
|
||||||
ProjectExplorer::TreeScanner::Result m_allFiles;
|
std::shared_ptr<ProjectExplorer::FolderNode> m_allFiles;
|
||||||
QHash<QString, bool> m_mimeBinaryCache;
|
QHash<QString, bool> m_mimeBinaryCache;
|
||||||
|
|
||||||
bool m_waitingForScan = false;
|
|
||||||
bool m_waitingForParse = false;
|
bool m_waitingForParse = false;
|
||||||
bool m_combinedScanAndParseResult = false;
|
bool m_combinedScanAndParseResult = false;
|
||||||
|
|
||||||
|
@@ -721,31 +721,5 @@ FileApiQtcData extractData(FileApiData &input,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileApiQtcData generateFallbackData(const FilePath &topCmakeFile,
|
|
||||||
const FilePath &sourceDirectory,
|
|
||||||
const FilePath &buildDirectory,
|
|
||||||
QString errorMessage)
|
|
||||||
{
|
|
||||||
Q_UNUSED(buildDirectory)
|
|
||||||
|
|
||||||
FileApiQtcData result;
|
|
||||||
|
|
||||||
result.rootProjectNode.reset(new CMakeProjectNode{sourceDirectory});
|
|
||||||
result.rootProjectNode->setDisplayName(sourceDirectory.fileName());
|
|
||||||
result.errorMessage = errorMessage;
|
|
||||||
|
|
||||||
if (!topCmakeFile.isEmpty()) {
|
|
||||||
auto node = std::make_unique<FileNode>(topCmakeFile, FileType::Project);
|
|
||||||
node->setIsGenerated(false);
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<FileNode>> fileNodes;
|
|
||||||
fileNodes.emplace_back(std::move(node));
|
|
||||||
|
|
||||||
addCMakeLists(result.rootProjectNode.get(), std::move(fileNodes));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace CMakeProjectManager
|
} // namespace CMakeProjectManager
|
||||||
|
@@ -75,10 +75,6 @@ public:
|
|||||||
FileApiQtcData extractData(FileApiData &data,
|
FileApiQtcData extractData(FileApiData &data,
|
||||||
const Utils::FilePath &sourceDirectory,
|
const Utils::FilePath &sourceDirectory,
|
||||||
const Utils::FilePath &buildDirectory);
|
const Utils::FilePath &buildDirectory);
|
||||||
FileApiQtcData generateFallbackData(const Utils::FilePath &topCmakeFile,
|
|
||||||
const Utils::FilePath &sourceDirectory,
|
|
||||||
const Utils::FilePath &buildDirectory,
|
|
||||||
QString errorMessage);
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace CMakeProjectManager
|
} // namespace CMakeProjectManager
|
||||||
|
@@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
#include "fileapidataextractor.h"
|
#include "fileapidataextractor.h"
|
||||||
#include "fileapiparser.h"
|
#include "fileapiparser.h"
|
||||||
#include "projecttreehelper.h"
|
|
||||||
|
|
||||||
#include <coreplugin/messagemanager.h>
|
#include <coreplugin/messagemanager.h>
|
||||||
|
|
||||||
@@ -214,15 +213,6 @@ bool FileApiReader::usesAllCapsTargets() const
|
|||||||
return m_usesAllCapsTargets;
|
return m_usesAllCapsTargets;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<CMakeProjectNode> FileApiReader::generateProjectTree(
|
|
||||||
const ProjectExplorer::TreeScanner::Result &allFiles, bool failedToParse)
|
|
||||||
{
|
|
||||||
if (failedToParse)
|
|
||||||
addFileSystemNodes(m_rootProjectNode.get(), allFiles.folderNode);
|
|
||||||
|
|
||||||
return std::exchange(m_rootProjectNode, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
RawProjectParts FileApiReader::createRawProjectParts(QString &errorMessage)
|
RawProjectParts FileApiReader::createRawProjectParts(QString &errorMessage)
|
||||||
{
|
{
|
||||||
Q_UNUSED(errorMessage)
|
Q_UNUSED(errorMessage)
|
||||||
@@ -250,37 +240,29 @@ void FileApiReader::endState(const FilePath &replyFilePath, bool restoredFromBac
|
|||||||
|
|
||||||
const FilePath sourceDirectory = m_parameters.sourceDirectory;
|
const FilePath sourceDirectory = m_parameters.sourceDirectory;
|
||||||
const FilePath buildDirectory = m_parameters.buildDirectory;
|
const FilePath buildDirectory = m_parameters.buildDirectory;
|
||||||
const FilePath topCmakeFile = m_cmakeFiles.size() == 1 ? (*m_cmakeFiles.begin()).path : FilePath{};
|
|
||||||
const QString cmakeBuildType = m_parameters.cmakeBuildType == "Build" ? "" : m_parameters.cmakeBuildType;
|
const QString cmakeBuildType = m_parameters.cmakeBuildType == "Build" ? "" : m_parameters.cmakeBuildType;
|
||||||
|
|
||||||
QTC_CHECK(!replyFilePath.needsDevice());
|
QTC_CHECK(!replyFilePath.needsDevice());
|
||||||
m_lastReplyTimestamp = replyFilePath.lastModified();
|
m_lastReplyTimestamp = replyFilePath.lastModified();
|
||||||
|
|
||||||
m_future = runAsync(ProjectExplorerPlugin::sharedThreadPool(),
|
m_future = runAsync(ProjectExplorerPlugin::sharedThreadPool(),
|
||||||
[replyFilePath, sourceDirectory, buildDirectory, topCmakeFile, cmakeBuildType](
|
[replyFilePath, sourceDirectory, buildDirectory, cmakeBuildType](
|
||||||
QFutureInterface<std::shared_ptr<FileApiQtcData>> &fi) {
|
QFutureInterface<std::shared_ptr<FileApiQtcData>> &fi) {
|
||||||
auto result = std::make_shared<FileApiQtcData>();
|
auto result = std::make_shared<FileApiQtcData>();
|
||||||
FileApiData data = FileApiParser::parseData(fi,
|
FileApiData data = FileApiParser::parseData(fi,
|
||||||
replyFilePath,
|
replyFilePath,
|
||||||
cmakeBuildType,
|
cmakeBuildType,
|
||||||
result->errorMessage);
|
result->errorMessage);
|
||||||
if (!result->errorMessage.isEmpty()) {
|
if (result->errorMessage.isEmpty())
|
||||||
*result = generateFallbackData(topCmakeFile,
|
|
||||||
sourceDirectory,
|
|
||||||
buildDirectory,
|
|
||||||
result->errorMessage);
|
|
||||||
} else {
|
|
||||||
*result = extractData(data, sourceDirectory, buildDirectory);
|
*result = extractData(data, sourceDirectory, buildDirectory);
|
||||||
}
|
else
|
||||||
if (!result->errorMessage.isEmpty()) {
|
|
||||||
qWarning() << result->errorMessage;
|
qWarning() << result->errorMessage;
|
||||||
}
|
|
||||||
|
|
||||||
fi.reportResult(result);
|
fi.reportResult(result);
|
||||||
});
|
});
|
||||||
onResultReady(m_future.value(),
|
onResultReady(m_future.value(),
|
||||||
this,
|
this,
|
||||||
[this, topCmakeFile, sourceDirectory, buildDirectory, restoredFromBackup](
|
[this, sourceDirectory, buildDirectory, restoredFromBackup](
|
||||||
const std::shared_ptr<FileApiQtcData> &value) {
|
const std::shared_ptr<FileApiQtcData> &value) {
|
||||||
m_isParsing = false;
|
m_isParsing = false;
|
||||||
m_cache = std::move(value->cache);
|
m_cache = std::move(value->cache);
|
||||||
@@ -348,6 +330,16 @@ void FileApiReader::writeConfigurationIntoBuildDirectory(const QStringList &conf
|
|||||||
QTC_CHECK(settingsFile.writeFileContents(contents));
|
QTC_CHECK(settingsFile.writeFileContents(contents));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<CMakeProjectNode> FileApiReader::rootProjectNode()
|
||||||
|
{
|
||||||
|
return std::exchange(m_rootProjectNode, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePath FileApiReader::topCmakeFile() const
|
||||||
|
{
|
||||||
|
return m_cmakeFiles.size() == 1 ? (*m_cmakeFiles.begin()).path : FilePath{};
|
||||||
|
}
|
||||||
|
|
||||||
int FileApiReader::lastCMakeExitCode() const
|
int FileApiReader::lastCMakeExitCode() const
|
||||||
{
|
{
|
||||||
return m_lastCMakeExitCode;
|
return m_lastCMakeExitCode;
|
||||||
|
@@ -71,8 +71,6 @@ public:
|
|||||||
QList<CMakeBuildTarget> takeBuildTargets(QString &errorMessage);
|
QList<CMakeBuildTarget> takeBuildTargets(QString &errorMessage);
|
||||||
CMakeConfig takeParsedConfiguration(QString &errorMessage);
|
CMakeConfig takeParsedConfiguration(QString &errorMessage);
|
||||||
QString ctestPath() const;
|
QString ctestPath() const;
|
||||||
std::unique_ptr<CMakeProjectNode> generateProjectTree(
|
|
||||||
const ProjectExplorer::TreeScanner::Result &allFiles, bool failedToParse);
|
|
||||||
ProjectExplorer::RawProjectParts createRawProjectParts(QString &errorMessage);
|
ProjectExplorer::RawProjectParts createRawProjectParts(QString &errorMessage);
|
||||||
|
|
||||||
bool isMultiConfig() const;
|
bool isMultiConfig() const;
|
||||||
@@ -80,6 +78,10 @@ public:
|
|||||||
|
|
||||||
int lastCMakeExitCode() const;
|
int lastCMakeExitCode() const;
|
||||||
|
|
||||||
|
std::unique_ptr<CMakeProjectNode> rootProjectNode();
|
||||||
|
|
||||||
|
Utils::FilePath topCmakeFile() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void configurationStarted() const;
|
void configurationStarted() const;
|
||||||
void dataAvailable(bool restoredFromBackup) const;
|
void dataAvailable(bool restoredFromBackup) const;
|
||||||
|
@@ -243,9 +243,15 @@ void CppLocalRenaming::forgetRenamingSelection()
|
|||||||
m_renameSelectionIndex = -1;
|
m_renameSelectionIndex = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CppLocalRenaming::isWithinSelection(const QTextEdit::ExtraSelection &selection, int position)
|
||||||
|
{
|
||||||
|
return selection.cursor.selectionStart() <= position
|
||||||
|
&& position <= selection.cursor.selectionEnd();
|
||||||
|
}
|
||||||
|
|
||||||
bool CppLocalRenaming::isWithinRenameSelection(int position)
|
bool CppLocalRenaming::isWithinRenameSelection(int position)
|
||||||
{
|
{
|
||||||
return renameSelectionBegin() <= position && position <= renameSelectionEnd();
|
return isWithinSelection(renameSelection(), position);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CppLocalRenaming::isSameSelection(int cursorPosition) const
|
bool CppLocalRenaming::isSameSelection(int cursorPosition) const
|
||||||
@@ -254,14 +260,14 @@ bool CppLocalRenaming::isSameSelection(int cursorPosition) const
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
const QTextEdit::ExtraSelection &sel = m_selections[m_renameSelectionIndex];
|
const QTextEdit::ExtraSelection &sel = m_selections[m_renameSelectionIndex];
|
||||||
return (sel.cursor.position() <= cursorPosition && cursorPosition <= sel.cursor.anchor());
|
return isWithinSelection(sel, cursorPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CppLocalRenaming::findRenameSelection(int cursorPosition)
|
bool CppLocalRenaming::findRenameSelection(int cursorPosition)
|
||||||
{
|
{
|
||||||
for (int i = 0, total = m_selections.size(); i < total; ++i) {
|
for (int i = 0, total = m_selections.size(); i < total; ++i) {
|
||||||
const QTextEdit::ExtraSelection &sel = m_selections.at(i);
|
const QTextEdit::ExtraSelection &sel = m_selections.at(i);
|
||||||
if (sel.cursor.position() <= cursorPosition && cursorPosition <= sel.cursor.anchor()) {
|
if (isWithinSelection(sel, cursorPosition)) {
|
||||||
m_renameSelectionIndex = i;
|
m_renameSelectionIndex = i;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -72,11 +72,12 @@ private:
|
|||||||
// The "rename selection" is the local use selection on which the user started the renaming
|
// The "rename selection" is the local use selection on which the user started the renaming
|
||||||
bool findRenameSelection(int cursorPosition);
|
bool findRenameSelection(int cursorPosition);
|
||||||
void forgetRenamingSelection();
|
void forgetRenamingSelection();
|
||||||
|
static bool isWithinSelection(const QTextEdit::ExtraSelection &selection, int position);
|
||||||
bool isWithinRenameSelection(int position);
|
bool isWithinRenameSelection(int position);
|
||||||
|
|
||||||
QTextEdit::ExtraSelection &renameSelection();
|
QTextEdit::ExtraSelection &renameSelection();
|
||||||
int renameSelectionBegin() { return renameSelection().cursor.position(); }
|
int renameSelectionBegin() { return renameSelection().cursor.selectionStart(); }
|
||||||
int renameSelectionEnd() { return renameSelection().cursor.anchor(); }
|
int renameSelectionEnd() { return renameSelection().cursor.selectionEnd(); }
|
||||||
|
|
||||||
void updateRenamingSelectionCursor(const QTextCursor &cursor);
|
void updateRenamingSelectionCursor(const QTextCursor &cursor);
|
||||||
void updateRenamingSelectionFormat(const QTextCharFormat &format);
|
void updateRenamingSelectionFormat(const QTextCharFormat &format);
|
||||||
|
@@ -308,7 +308,8 @@ DebuggerKitAspect::ConfigurationErrors DebuggerKitAspect::configurationErrors(co
|
|||||||
|
|
||||||
ConfigurationErrors result = NoConfigurationError;
|
ConfigurationErrors result = NoConfigurationError;
|
||||||
const FilePath debugger = item->command();
|
const FilePath debugger = item->command();
|
||||||
if (!debugger.exists() || debugger.isDir())
|
const bool found = debugger.exists() && !debugger.isDir();
|
||||||
|
if (!found)
|
||||||
result |= DebuggerNotFound;
|
result |= DebuggerNotFound;
|
||||||
else if (!debugger.isExecutableFile())
|
else if (!debugger.isExecutableFile())
|
||||||
result |= DebuggerNotExecutable;
|
result |= DebuggerNotExecutable;
|
||||||
@@ -321,7 +322,7 @@ DebuggerKitAspect::ConfigurationErrors DebuggerKitAspect::configurationErrors(co
|
|||||||
result |= DebuggerDoesNotMatch;
|
result |= DebuggerDoesNotMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!debugger.exists() || debugger.isDir()) {
|
if (!found) {
|
||||||
if (item->engineType() == NoEngineType)
|
if (item->engineType() == NoEngineType)
|
||||||
return NoDebugger;
|
return NoDebugger;
|
||||||
|
|
||||||
|
@@ -897,7 +897,10 @@ void DockerDevicePrivate::startContainer()
|
|||||||
|
|
||||||
void DockerDevicePrivate::tryCreateLocalFileAccess()
|
void DockerDevicePrivate::tryCreateLocalFileAccess()
|
||||||
{
|
{
|
||||||
if (!m_container.isEmpty() || DockerPlugin::isDaemonRunning().value_or(true) == false)
|
if (!m_container.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (DockerPlugin::isDaemonRunning().value_or(true) == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!m_shell)
|
if (!m_shell)
|
||||||
|
@@ -87,6 +87,7 @@
|
|||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
#include <QTimer>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
@@ -477,8 +478,11 @@ void GitPluginPrivate::onApplySettings()
|
|||||||
bool gitFoundOk;
|
bool gitFoundOk;
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
m_settings.gitExecutable(&gitFoundOk, &errorMessage);
|
m_settings.gitExecutable(&gitFoundOk, &errorMessage);
|
||||||
if (!gitFoundOk)
|
if (!gitFoundOk) {
|
||||||
|
QTimer::singleShot(0, this, [this, errorMessage] {
|
||||||
Core::AsynchronousMessageBox::warning(tr("Git Settings"), errorMessage);
|
Core::AsynchronousMessageBox::warning(tr("Git Settings"), errorMessage);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GitPluginPrivate::cleanCommitMessageFile()
|
void GitPluginPrivate::cleanCommitMessageFile()
|
||||||
|
@@ -248,6 +248,7 @@ static ClientCapabilities generateClientCapabilities()
|
|||||||
signatureHelp.setDynamicRegistration(true);
|
signatureHelp.setDynamicRegistration(true);
|
||||||
TextDocumentClientCapabilities::SignatureHelpCapabilities::SignatureInformationCapabilities info;
|
TextDocumentClientCapabilities::SignatureHelpCapabilities::SignatureInformationCapabilities info;
|
||||||
info.setDocumentationFormat({MarkupKind::markdown, MarkupKind::plaintext});
|
info.setDocumentationFormat({MarkupKind::markdown, MarkupKind::plaintext});
|
||||||
|
info.setActiveParameterSupport(true);
|
||||||
signatureHelp.setSignatureInformation(info);
|
signatureHelp.setSignatureInformation(info);
|
||||||
documentCapabilities.setSignatureHelp(signatureHelp);
|
documentCapabilities.setSignatureHelp(signatureHelp);
|
||||||
|
|
||||||
|
@@ -61,11 +61,12 @@ QString FunctionHintProposalModel::text(int index) const
|
|||||||
if (index < 0 || m_sigis.signatures().size() <= index)
|
if (index < 0 || m_sigis.signatures().size() <= index)
|
||||||
return {};
|
return {};
|
||||||
const SignatureInformation signature = m_sigis.signatures().at(index);
|
const SignatureInformation signature = m_sigis.signatures().at(index);
|
||||||
|
int parametersIndex = signature.activeParameter().value_or(-1);
|
||||||
|
if (parametersIndex < 0) {
|
||||||
|
if (index == m_sigis.activeSignature().value_or(-1))
|
||||||
|
parametersIndex = m_sigis.activeParameter().value_or(-1);
|
||||||
|
}
|
||||||
QString label = signature.label();
|
QString label = signature.label();
|
||||||
if (index != m_sigis.activeSignature().value_or(-1))
|
|
||||||
return label;
|
|
||||||
|
|
||||||
const int parametersIndex = m_sigis.activeParameter().value_or(-1);
|
|
||||||
if (parametersIndex < 0)
|
if (parametersIndex < 0)
|
||||||
return label;
|
return label;
|
||||||
|
|
||||||
|
@@ -78,14 +78,18 @@ static void handleGotoDefinitionResponse(const GotoDefinitionRequest::Response &
|
|||||||
{
|
{
|
||||||
if (Utils::optional<GotoResult> _result = response.result()) {
|
if (Utils::optional<GotoResult> _result = response.result()) {
|
||||||
const GotoResult result = _result.value();
|
const GotoResult result = _result.value();
|
||||||
if (Utils::holds_alternative<std::nullptr_t>(result))
|
if (Utils::holds_alternative<std::nullptr_t>(result)) {
|
||||||
return;
|
callback({});
|
||||||
if (auto ploc = Utils::get_if<Location>(&result)) {
|
} else if (auto ploc = Utils::get_if<Location>(&result)) {
|
||||||
callback(linkUnderCursor.value_or(ploc->toLink()));
|
callback(linkUnderCursor.value_or(ploc->toLink()));
|
||||||
} else if (auto plloc = Utils::get_if<QList<Location>>(&result)) {
|
} else if (auto plloc = Utils::get_if<QList<Location>>(&result)) {
|
||||||
if (!plloc->isEmpty())
|
if (!plloc->isEmpty())
|
||||||
callback(linkUnderCursor.value_or(plloc->value(0).toLink()));
|
callback(linkUnderCursor.value_or(plloc->value(0).toLink()));
|
||||||
|
else
|
||||||
|
callback({});
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
callback({});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -62,7 +62,9 @@ void DocumentLocatorFilter::updateCurrentClient()
|
|||||||
disconnect(m_resetSymbolsConnection);
|
disconnect(m_resetSymbolsConnection);
|
||||||
|
|
||||||
TextEditor::TextDocument *document = TextEditor::TextDocument::currentTextDocument();
|
TextEditor::TextDocument *document = TextEditor::TextDocument::currentTextDocument();
|
||||||
if (Client *client = LanguageClientManager::clientForDocument(document)) {
|
if (Client *client = LanguageClientManager::clientForDocument(document);
|
||||||
|
client && client->locatorsEnabled()) {
|
||||||
|
setEnabled(true);
|
||||||
if (m_symbolCache != client->documentSymbolCache()) {
|
if (m_symbolCache != client->documentSymbolCache()) {
|
||||||
disconnect(m_updateSymbolsConnection);
|
disconnect(m_updateSymbolsConnection);
|
||||||
m_symbolCache = client->documentSymbolCache();
|
m_symbolCache = client->documentSymbolCache();
|
||||||
@@ -76,6 +78,7 @@ void DocumentLocatorFilter::updateCurrentClient()
|
|||||||
disconnect(m_updateSymbolsConnection);
|
disconnect(m_updateSymbolsConnection);
|
||||||
m_symbolCache.clear();
|
m_symbolCache.clear();
|
||||||
m_currentUri.clear();
|
m_currentUri.clear();
|
||||||
|
setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -956,6 +956,15 @@ void CheckBoxField::setup(JsonFieldPage *page, const QString &name)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckBoxField::setChecked(bool value)
|
||||||
|
{
|
||||||
|
auto w = qobject_cast<QCheckBox *>(widget());
|
||||||
|
QTC_ASSERT(w, return);
|
||||||
|
|
||||||
|
w->setChecked(value);
|
||||||
|
w->clicked(value);
|
||||||
|
}
|
||||||
|
|
||||||
bool CheckBoxField::validate(MacroExpander *expander, QString *message)
|
bool CheckBoxField::validate(MacroExpander *expander, QString *message)
|
||||||
{
|
{
|
||||||
if (!JsonFieldPage::Field::validate(expander, message))
|
if (!JsonFieldPage::Field::validate(expander, message))
|
||||||
|
@@ -230,11 +230,13 @@ private:
|
|||||||
Utils::PathChooser::Kind m_kind = Utils::PathChooser::ExistingDirectory;
|
Utils::PathChooser::Kind m_kind = Utils::PathChooser::ExistingDirectory;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CheckBoxField : public JsonFieldPage::Field
|
class PROJECTEXPLORER_EXPORT CheckBoxField : public JsonFieldPage::Field
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool suppressName() const override { return true; }
|
bool suppressName() const override { return true; }
|
||||||
|
|
||||||
|
void setChecked(bool);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool parseData(const QVariant &data, QString *errorMessage) override;
|
bool parseData(const QVariant &data, QString *errorMessage) override;
|
||||||
|
|
||||||
|
@@ -257,12 +257,14 @@ QList<Core::IWizardFactory *> JsonWizardFactory::createWizardFactories()
|
|||||||
.arg(currentFile.fileName())
|
.arg(currentFile.fileName())
|
||||||
.arg(line).arg(column)
|
.arg(line).arg(column)
|
||||||
.arg(error.errorString()));
|
.arg(error.errorString()));
|
||||||
|
qWarning() << "Failed to parse wizard: " << currentFile.fileName();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!json.isObject()) {
|
if (!json.isObject()) {
|
||||||
verboseLog.append(tr("* Did not find a JSON object in \"%1\".\n")
|
verboseLog.append(tr("* Did not find a JSON object in \"%1\".\n")
|
||||||
.arg(currentFile.fileName()));
|
.arg(currentFile.fileName()));
|
||||||
|
qWarning() << "Failed to parse wizard: " << currentFile.fileName();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,6 +282,7 @@ QList<Core::IWizardFactory *> JsonWizardFactory::createWizardFactories()
|
|||||||
JsonWizardFactory *factory = createWizardFactory(data, currentDir, &errorMessage);
|
JsonWizardFactory *factory = createWizardFactory(data, currentDir, &errorMessage);
|
||||||
if (!factory) {
|
if (!factory) {
|
||||||
verboseLog.append(tr("* Failed to create: %1\n").arg(errorMessage));
|
verboseLog.append(tr("* Failed to create: %1\n").arg(errorMessage));
|
||||||
|
qWarning() << "Failed to create wizard: " << currentFile.fileName();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -51,8 +51,6 @@
|
|||||||
|
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QDir>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QFontMetrics>
|
#include <QFontMetrics>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
@@ -133,18 +131,16 @@ Tasks SysRootKitAspect::validate(const Kit *k) const
|
|||||||
if (dir.isEmpty())
|
if (dir.isEmpty())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (dir.toString().startsWith("target:") || dir.toString().startsWith("remote:"))
|
if (dir.startsWith("target:") || dir.startsWith("remote:"))
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
const QFileInfo fi = dir.toFileInfo();
|
if (!dir.exists()) {
|
||||||
|
|
||||||
if (!fi.exists()) {
|
|
||||||
result << BuildSystemTask(Task::Warning,
|
result << BuildSystemTask(Task::Warning,
|
||||||
tr("Sys Root \"%1\" does not exist in the file system.").arg(dir.toUserOutput()));
|
tr("Sys Root \"%1\" does not exist in the file system.").arg(dir.toUserOutput()));
|
||||||
} else if (!fi.isDir()) {
|
} else if (!dir.isDir()) {
|
||||||
result << BuildSystemTask(Task::Warning,
|
result << BuildSystemTask(Task::Warning,
|
||||||
tr("Sys Root \"%1\" is not a directory.").arg(dir.toUserOutput()));
|
tr("Sys Root \"%1\" is not a directory.").arg(dir.toUserOutput()));
|
||||||
} else if (QDir(dir.toString()).entryList(QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty()) {
|
} else if (dir.dirEntries(QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty()) {
|
||||||
result << BuildSystemTask(Task::Warning,
|
result << BuildSystemTask(Task::Warning,
|
||||||
tr("Sys Root \"%1\" is empty.").arg(dir.toUserOutput()));
|
tr("Sys Root \"%1\" is empty.").arg(dir.toUserOutput()));
|
||||||
}
|
}
|
||||||
@@ -626,11 +622,10 @@ QList<ToolChain *> ToolChainKitAspect::toolChains(const Kit *k)
|
|||||||
|
|
||||||
const QVariantMap value = k->value(ToolChainKitAspect::id()).toMap();
|
const QVariantMap value = k->value(ToolChainKitAspect::id()).toMap();
|
||||||
const QList<ToolChain *> tcList
|
const QList<ToolChain *> tcList
|
||||||
= Utils::transform<QList>(ToolChainManager::allLanguages(),
|
= transform<QList>(ToolChainManager::allLanguages(), [&value](Id l) {
|
||||||
[&value](Utils::Id l) -> ToolChain * {
|
|
||||||
return ToolChainManager::findToolChain(value.value(l.toString()).toByteArray());
|
return ToolChainManager::findToolChain(value.value(l.toString()).toByteArray());
|
||||||
});
|
});
|
||||||
return Utils::filtered(tcList, [](ToolChain *tc) { return tc; });
|
return filtered(tcList, [](ToolChain *tc) { return tc; });
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolChainKitAspect::setToolChain(Kit *k, ToolChain *tc)
|
void ToolChainKitAspect::setToolChain(Kit *k, ToolChain *tc)
|
||||||
@@ -664,7 +659,7 @@ void ToolChainKitAspect::setAllToolChainsToMatch(Kit *k, ToolChain *tc)
|
|||||||
QVariantMap result = k->value(ToolChainKitAspect::id()).toMap();
|
QVariantMap result = k->value(ToolChainKitAspect::id()).toMap();
|
||||||
result.insert(tc->language().toString(), tc->id());
|
result.insert(tc->language().toString(), tc->id());
|
||||||
|
|
||||||
for (Utils::Id l : ToolChainManager::allLanguages()) {
|
for (const Id l : ToolChainManager::allLanguages()) {
|
||||||
if (l == tc->language())
|
if (l == tc->language())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -692,7 +687,7 @@ void ToolChainKitAspect::setAllToolChainsToMatch(Kit *k, ToolChain *tc)
|
|||||||
k->setValue(id(), result);
|
k->setValue(id(), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolChainKitAspect::clearToolChain(Kit *k, Utils::Id language)
|
void ToolChainKitAspect::clearToolChain(Kit *k, Id language)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(language.isValid(), return);
|
QTC_ASSERT(language.isValid(), return);
|
||||||
QTC_ASSERT(k, return);
|
QTC_ASSERT(k, return);
|
||||||
@@ -710,7 +705,7 @@ Abi ToolChainKitAspect::targetAbi(const Kit *k)
|
|||||||
QHash<Abi, int> abiCount;
|
QHash<Abi, int> abiCount;
|
||||||
foreach (ToolChain *tc, tcList) {
|
foreach (ToolChain *tc, tcList) {
|
||||||
Abi ta = tc->targetAbi();
|
Abi ta = tc->targetAbi();
|
||||||
if (tc->language() == Utils::Id(Constants::CXX_LANGUAGE_ID))
|
if (tc->language() == Id(Constants::CXX_LANGUAGE_ID))
|
||||||
cxxAbi = tc->targetAbi();
|
cxxAbi = tc->targetAbi();
|
||||||
abiCount[ta] = (abiCount.contains(ta) ? abiCount[ta] + 1 : 1);
|
abiCount[ta] = (abiCount.contains(ta) ? abiCount[ta] + 1 : 1);
|
||||||
}
|
}
|
||||||
@@ -799,7 +794,7 @@ private:
|
|||||||
|
|
||||||
void refresh() override
|
void refresh() override
|
||||||
{
|
{
|
||||||
Utils::Id devType = DeviceTypeKitAspect::deviceTypeId(m_kit);
|
Id devType = DeviceTypeKitAspect::deviceTypeId(m_kit);
|
||||||
if (!devType.isValid())
|
if (!devType.isValid())
|
||||||
m_comboBox->setCurrentIndex(-1);
|
m_comboBox->setCurrentIndex(-1);
|
||||||
for (int i = 0; i < m_comboBox->count(); ++i) {
|
for (int i = 0; i < m_comboBox->count(); ++i) {
|
||||||
@@ -812,7 +807,7 @@ private:
|
|||||||
|
|
||||||
void currentTypeChanged(int idx)
|
void currentTypeChanged(int idx)
|
||||||
{
|
{
|
||||||
Utils::Id type = idx < 0 ? Utils::Id() : Utils::Id::fromSetting(m_comboBox->itemData(idx));
|
Id type = idx < 0 ? Id() : Id::fromSetting(m_comboBox->itemData(idx));
|
||||||
DeviceTypeKitAspect::setDeviceTypeId(m_kit, type);
|
DeviceTypeKitAspect::setDeviceTypeId(m_kit, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -851,7 +846,7 @@ KitAspectWidget *DeviceTypeKitAspect::createConfigWidget(Kit *k) const
|
|||||||
KitAspect::ItemList DeviceTypeKitAspect::toUserOutput(const Kit *k) const
|
KitAspect::ItemList DeviceTypeKitAspect::toUserOutput(const Kit *k) const
|
||||||
{
|
{
|
||||||
QTC_ASSERT(k, return {});
|
QTC_ASSERT(k, return {});
|
||||||
Utils::Id type = deviceTypeId(k);
|
Id type = deviceTypeId(k);
|
||||||
QString typeDisplayName = tr("Unknown device type");
|
QString typeDisplayName = tr("Unknown device type");
|
||||||
if (type.isValid()) {
|
if (type.isValid()) {
|
||||||
if (IDeviceFactory *factory = IDeviceFactory::find(type))
|
if (IDeviceFactory *factory = IDeviceFactory::find(type))
|
||||||
@@ -860,33 +855,33 @@ KitAspect::ItemList DeviceTypeKitAspect::toUserOutput(const Kit *k) const
|
|||||||
return {{tr("Device type"), typeDisplayName}};
|
return {{tr("Device type"), typeDisplayName}};
|
||||||
}
|
}
|
||||||
|
|
||||||
const Utils::Id DeviceTypeKitAspect::id()
|
const Id DeviceTypeKitAspect::id()
|
||||||
{
|
{
|
||||||
return "PE.Profile.DeviceType";
|
return "PE.Profile.DeviceType";
|
||||||
}
|
}
|
||||||
|
|
||||||
const Utils::Id DeviceTypeKitAspect::deviceTypeId(const Kit *k)
|
const Id DeviceTypeKitAspect::deviceTypeId(const Kit *k)
|
||||||
{
|
{
|
||||||
return k ? Utils::Id::fromSetting(k->value(DeviceTypeKitAspect::id())) : Utils::Id();
|
return k ? Id::fromSetting(k->value(DeviceTypeKitAspect::id())) : Id();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceTypeKitAspect::setDeviceTypeId(Kit *k, Utils::Id type)
|
void DeviceTypeKitAspect::setDeviceTypeId(Kit *k, Id type)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(k, return);
|
QTC_ASSERT(k, return);
|
||||||
k->setValue(DeviceTypeKitAspect::id(), type.toSetting());
|
k->setValue(DeviceTypeKitAspect::id(), type.toSetting());
|
||||||
}
|
}
|
||||||
|
|
||||||
QSet<Utils::Id> DeviceTypeKitAspect::supportedPlatforms(const Kit *k) const
|
QSet<Id> DeviceTypeKitAspect::supportedPlatforms(const Kit *k) const
|
||||||
{
|
{
|
||||||
return {deviceTypeId(k)};
|
return {deviceTypeId(k)};
|
||||||
}
|
}
|
||||||
|
|
||||||
QSet<Utils::Id> DeviceTypeKitAspect::availableFeatures(const Kit *k) const
|
QSet<Id> DeviceTypeKitAspect::availableFeatures(const Kit *k) const
|
||||||
{
|
{
|
||||||
Utils::Id id = DeviceTypeKitAspect::deviceTypeId(k);
|
Id id = DeviceTypeKitAspect::deviceTypeId(k);
|
||||||
if (id.isValid())
|
if (id.isValid())
|
||||||
return {id.withPrefix("DeviceType.")};
|
return {id.withPrefix("DeviceType.")};
|
||||||
return QSet<Utils::Id>();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@@ -1225,7 +1220,7 @@ private:
|
|||||||
QComboBox *m_comboBox;
|
QComboBox *m_comboBox;
|
||||||
QWidget *m_manageButton;
|
QWidget *m_manageButton;
|
||||||
DeviceManagerModel *m_model;
|
DeviceManagerModel *m_model;
|
||||||
Utils::Id m_selectedId;
|
Id m_selectedId;
|
||||||
};
|
};
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|
||||||
|
@@ -34,6 +34,9 @@
|
|||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
|
||||||
|
using namespace Core;
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -49,8 +52,8 @@ public:
|
|||||||
ProjectExplorerSettings settings() const;
|
ProjectExplorerSettings settings() const;
|
||||||
void setSettings(const ProjectExplorerSettings &s);
|
void setSettings(const ProjectExplorerSettings &s);
|
||||||
|
|
||||||
QString projectsDirectory() const;
|
FilePath projectsDirectory() const;
|
||||||
void setProjectsDirectory(const QString &pd);
|
void setProjectsDirectory(const FilePath &pd);
|
||||||
|
|
||||||
bool useProjectsDirectory();
|
bool useProjectsDirectory();
|
||||||
void setUseProjectsDirectory(bool v);
|
void setUseProjectsDirectory(bool v);
|
||||||
@@ -68,7 +71,7 @@ ProjectExplorerSettingsWidget::ProjectExplorerSettingsWidget(QWidget *parent) :
|
|||||||
QWidget(parent)
|
QWidget(parent)
|
||||||
{
|
{
|
||||||
m_ui.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
setJomVisible(Utils::HostOsInfo::isWindowsHost());
|
setJomVisible(HostOsInfo::isWindowsHost());
|
||||||
m_ui.stopBeforeBuildComboBox->addItem(tr("None"), int(StopBeforeBuild::None));
|
m_ui.stopBeforeBuildComboBox->addItem(tr("None"), int(StopBeforeBuild::None));
|
||||||
m_ui.stopBeforeBuildComboBox->addItem(tr("All"), int(StopBeforeBuild::All));
|
m_ui.stopBeforeBuildComboBox->addItem(tr("All"), int(StopBeforeBuild::All));
|
||||||
m_ui.stopBeforeBuildComboBox->addItem(tr("Same Project"), int(StopBeforeBuild::SameProject));
|
m_ui.stopBeforeBuildComboBox->addItem(tr("Same Project"), int(StopBeforeBuild::SameProject));
|
||||||
@@ -135,14 +138,14 @@ void ProjectExplorerSettingsWidget::setSettings(const ProjectExplorerSettings &
|
|||||||
m_ui.lowBuildPriorityCheckBox->setChecked(m_settings.lowBuildPriority);
|
m_ui.lowBuildPriorityCheckBox->setChecked(m_settings.lowBuildPriority);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ProjectExplorerSettingsWidget::projectsDirectory() const
|
FilePath ProjectExplorerSettingsWidget::projectsDirectory() const
|
||||||
{
|
{
|
||||||
return m_ui.projectsDirectoryPathChooser->filePath().toString();
|
return m_ui.projectsDirectoryPathChooser->filePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProjectExplorerSettingsWidget::setProjectsDirectory(const QString &pd)
|
void ProjectExplorerSettingsWidget::setProjectsDirectory(const FilePath &pd)
|
||||||
{
|
{
|
||||||
m_ui.projectsDirectoryPathChooser->setPath(pd);
|
m_ui.projectsDirectoryPathChooser->setFilePath(pd);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProjectExplorerSettingsWidget::useProjectsDirectory()
|
bool ProjectExplorerSettingsWidget::useProjectsDirectory()
|
||||||
@@ -179,8 +182,8 @@ QWidget *ProjectExplorerSettingsPage::widget()
|
|||||||
if (!m_widget) {
|
if (!m_widget) {
|
||||||
m_widget = new ProjectExplorerSettingsWidget;
|
m_widget = new ProjectExplorerSettingsWidget;
|
||||||
m_widget->setSettings(ProjectExplorerPlugin::projectExplorerSettings());
|
m_widget->setSettings(ProjectExplorerPlugin::projectExplorerSettings());
|
||||||
m_widget->setProjectsDirectory(Core::DocumentManager::projectsDirectory().toString());
|
m_widget->setProjectsDirectory(DocumentManager::projectsDirectory());
|
||||||
m_widget->setUseProjectsDirectory(Core::DocumentManager::useProjectsDirectory());
|
m_widget->setUseProjectsDirectory(DocumentManager::useProjectsDirectory());
|
||||||
}
|
}
|
||||||
return m_widget;
|
return m_widget;
|
||||||
}
|
}
|
||||||
@@ -189,9 +192,8 @@ void ProjectExplorerSettingsPage::apply()
|
|||||||
{
|
{
|
||||||
if (m_widget) {
|
if (m_widget) {
|
||||||
ProjectExplorerPlugin::setProjectExplorerSettings(m_widget->settings());
|
ProjectExplorerPlugin::setProjectExplorerSettings(m_widget->settings());
|
||||||
Core::DocumentManager::setProjectsDirectory(
|
DocumentManager::setProjectsDirectory(m_widget->projectsDirectory());
|
||||||
Utils::FilePath::fromString(m_widget->projectsDirectory()));
|
DocumentManager::setUseProjectsDirectory(m_widget->useProjectsDirectory());
|
||||||
Core::DocumentManager::setUseProjectsDirectory(m_widget->useProjectsDirectory());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -320,14 +320,14 @@ public:
|
|||||||
QFontMetrics fm(option.widget->font());
|
QFontMetrics fm(option.widget->font());
|
||||||
for (const QString &project : projects) {
|
for (const QString &project : projects) {
|
||||||
// Project name.
|
// Project name.
|
||||||
QFileInfo fi(project);
|
FilePath projectPath = FilePath::fromString(project);
|
||||||
QString completeBase = fi.completeBaseName();
|
QString completeBase = projectPath.completeBaseName();
|
||||||
painter->setPen(textColor);
|
painter->setPen(textColor);
|
||||||
painter->drawText(x1, yy, completeBase);
|
painter->drawText(x1, yy, completeBase);
|
||||||
yy += 18;
|
yy += 18;
|
||||||
|
|
||||||
// Project path.
|
// Project path.
|
||||||
QString pathWithTilde = Utils::withTildeHomePath(QDir::toNativeSeparators(project));
|
QString pathWithTilde = Utils::withTildeHomePath(projectPath.toUserOutput());
|
||||||
painter->setPen(foregroundColor1);
|
painter->setPen(foregroundColor1);
|
||||||
painter->drawText(x1, yy, fm.elidedText(pathWithTilde, Qt::ElideMiddle, rc.width() - 40));
|
painter->drawText(x1, yy, fm.elidedText(pathWithTilde, Qt::ElideMiddle, rc.width() - 40));
|
||||||
yy += 22;
|
yy += 22;
|
||||||
@@ -454,7 +454,7 @@ public:
|
|||||||
painter->drawPixmap(x + 11, y + 6, projectIcon);
|
painter->drawPixmap(x + 11, y + 6, projectIcon);
|
||||||
|
|
||||||
QString projectName = idx.data(Qt::DisplayRole).toString();
|
QString projectName = idx.data(Qt::DisplayRole).toString();
|
||||||
QString projectPath = idx.data(ProjectModel::FilePathRole).toString();
|
FilePath projectPath = FilePath::fromVariant(idx.data(ProjectModel::FilePathRole));
|
||||||
|
|
||||||
painter->setPen(themeColor(Theme::Welcome_ForegroundSecondaryColor));
|
painter->setPen(themeColor(Theme::Welcome_ForegroundSecondaryColor));
|
||||||
painter->setFont(sizedFont(10, option.widget));
|
painter->setFont(sizedFont(10, option.widget));
|
||||||
@@ -468,7 +468,7 @@ public:
|
|||||||
|
|
||||||
painter->setPen(themeColor(Theme::Welcome_ForegroundPrimaryColor));
|
painter->setPen(themeColor(Theme::Welcome_ForegroundPrimaryColor));
|
||||||
painter->setFont(sizedFont(13, option.widget));
|
painter->setFont(sizedFont(13, option.widget));
|
||||||
QString pathWithTilde = Utils::withTildeHomePath(QDir::toNativeSeparators(projectPath));
|
QString pathWithTilde = Utils::withTildeHomePath(projectPath.toUserOutput());
|
||||||
painter->drawText(x + 36, secondBase, pathWithTilde);
|
painter->drawText(x + 36, secondBase, pathWithTilde);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -38,8 +38,8 @@
|
|||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
using namespace QmakeProjectManager;
|
namespace QmakeProjectManager {
|
||||||
using namespace QmakeProjectManager::Internal;
|
namespace Internal {
|
||||||
|
|
||||||
const char qt_file_dialog_filter_reg_exp[] =
|
const char qt_file_dialog_filter_reg_exp[] =
|
||||||
"^(.*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$";
|
"^(.*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$";
|
||||||
@@ -79,8 +79,8 @@ static bool validateLibraryPath(const Utils::FilePath &filePath,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddLibraryWizard::AddLibraryWizard(const QString &fileName, QWidget *parent) :
|
AddLibraryWizard::AddLibraryWizard(const Utils::FilePath &proFile, QWidget *parent) :
|
||||||
Utils::Wizard(parent), m_proFile(fileName)
|
Utils::Wizard(parent), m_proFile(proFile)
|
||||||
{
|
{
|
||||||
setWindowTitle(tr("Add Library"));
|
setWindowTitle(tr("Add Library"));
|
||||||
m_libraryTypePage = new LibraryTypePage(this);
|
m_libraryTypePage = new LibraryTypePage(this);
|
||||||
@@ -93,7 +93,7 @@ AddLibraryWizard::AddLibraryWizard(const QString &fileName, QWidget *parent) :
|
|||||||
|
|
||||||
AddLibraryWizard::~AddLibraryWizard() = default;
|
AddLibraryWizard::~AddLibraryWizard() = default;
|
||||||
|
|
||||||
QString AddLibraryWizard::proFile() const
|
Utils::FilePath AddLibraryWizard::proFile() const
|
||||||
{
|
{
|
||||||
return m_proFile;
|
return m_proFile;
|
||||||
}
|
}
|
||||||
@@ -294,10 +294,9 @@ SummaryPage::SummaryPage(AddLibraryWizard *parent)
|
|||||||
void SummaryPage::initializePage()
|
void SummaryPage::initializePage()
|
||||||
{
|
{
|
||||||
m_snippet = m_libraryWizard->snippet();
|
m_snippet = m_libraryWizard->snippet();
|
||||||
QFileInfo fi(m_libraryWizard->proFile());
|
|
||||||
m_summaryLabel->setText(
|
m_summaryLabel->setText(
|
||||||
tr("The following snippet will be added to the<br><b>%1</b> file:")
|
tr("The following snippet will be added to the<br><b>%1</b> file:")
|
||||||
.arg(fi.fileName()));
|
.arg(m_libraryWizard->proFile().fileName()));
|
||||||
QString richSnippet;
|
QString richSnippet;
|
||||||
{
|
{
|
||||||
QTextStream str(&richSnippet);
|
QTextStream str(&richSnippet);
|
||||||
@@ -316,3 +315,6 @@ QString SummaryPage::snippet() const
|
|||||||
{
|
{
|
||||||
return m_snippet;
|
return m_snippet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // Internal
|
||||||
|
} // QmakeProjectManager
|
||||||
|
@@ -76,20 +76,18 @@ public:
|
|||||||
|
|
||||||
Q_DECLARE_FLAGS(Platforms, Platform)
|
Q_DECLARE_FLAGS(Platforms, Platform)
|
||||||
|
|
||||||
explicit AddLibraryWizard(const QString &fileName, QWidget *parent = nullptr);
|
explicit AddLibraryWizard(const Utils::FilePath &proFile, QWidget *parent = nullptr);
|
||||||
~AddLibraryWizard() override;
|
~AddLibraryWizard() override;
|
||||||
|
|
||||||
LibraryKind libraryKind() const;
|
LibraryKind libraryKind() const;
|
||||||
QString proFile() const;
|
Utils::FilePath proFile() const;
|
||||||
QString snippet() const;
|
QString snippet() const;
|
||||||
|
|
||||||
signals:
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LibraryTypePage *m_libraryTypePage = nullptr;
|
LibraryTypePage *m_libraryTypePage = nullptr;
|
||||||
DetailsPage *m_detailsPage = nullptr;
|
DetailsPage *m_detailsPage = nullptr;
|
||||||
SummaryPage *m_summaryPage = nullptr;
|
SummaryPage *m_summaryPage = nullptr;
|
||||||
QString m_proFile;
|
Utils::FilePath m_proFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LibraryTypePage : public QWizardPage
|
class LibraryTypePage : public QWizardPage
|
||||||
|
@@ -40,22 +40,24 @@
|
|||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
using namespace QmakeProjectManager;
|
using namespace Utils;
|
||||||
using namespace QmakeProjectManager::Internal;
|
|
||||||
|
namespace QmakeProjectManager {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
static void fillLibraryPlatformTypes(QComboBox *comboBox)
|
static void fillLibraryPlatformTypes(QComboBox *comboBox)
|
||||||
{
|
{
|
||||||
comboBox->clear();
|
comboBox->clear();
|
||||||
comboBox->addItem("Windows (*.lib lib*.a)", int(Utils::OsTypeWindows));
|
comboBox->addItem("Windows (*.lib lib*.a)", int(OsTypeWindows));
|
||||||
comboBox->addItem("Linux (lib*.so lib*.a)", int(Utils::OsTypeLinux));
|
comboBox->addItem("Linux (lib*.so lib*.a)", int(OsTypeLinux));
|
||||||
comboBox->addItem("macOS (*.dylib *.a *.framework)", int(Utils::OsTypeMac));
|
comboBox->addItem("macOS (*.dylib *.a *.framework)", int(OsTypeMac));
|
||||||
const int currentIndex = comboBox->findData(int(Utils::HostOsInfo::hostOs()));
|
const int currentIndex = comboBox->findData(int(HostOsInfo::hostOs()));
|
||||||
comboBox->setCurrentIndex(std::max(0, currentIndex));
|
comboBox->setCurrentIndex(std::max(0, currentIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
LibraryDetailsController::LibraryDetailsController(
|
LibraryDetailsController::LibraryDetailsController(
|
||||||
Ui::LibraryDetailsWidget *libraryDetails,
|
Ui::LibraryDetailsWidget *libraryDetails,
|
||||||
const QString &proFile, QObject *parent) :
|
const FilePath &proFile, QObject *parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_proFile(proFile),
|
m_proFile(proFile),
|
||||||
m_libraryDetailsWidget(libraryDetails)
|
m_libraryDetailsWidget(libraryDetails)
|
||||||
@@ -65,12 +67,12 @@ LibraryDetailsController::LibraryDetailsController(
|
|||||||
setLinkageGroupVisible(true);
|
setLinkageGroupVisible(true);
|
||||||
setMacLibraryGroupVisible(true);
|
setMacLibraryGroupVisible(true);
|
||||||
setPackageLineEditVisible(false);
|
setPackageLineEditVisible(false);
|
||||||
const bool isMacOs = libraryPlatformType() == Utils::OsTypeMac;
|
const bool isMacOs = libraryPlatformType() == OsTypeMac;
|
||||||
const bool isWindows = libraryPlatformType() == Utils::OsTypeWindows;
|
const bool isWindows = libraryPlatformType() == OsTypeWindows;
|
||||||
setMacLibraryRadiosVisible(!isMacOs);
|
setMacLibraryRadiosVisible(!isMacOs);
|
||||||
setLinkageRadiosVisible(isWindows);
|
setLinkageRadiosVisible(isWindows);
|
||||||
|
|
||||||
connect(m_libraryDetailsWidget->includePathChooser, &Utils::PathChooser::rawPathChanged,
|
connect(m_libraryDetailsWidget->includePathChooser, &PathChooser::rawPathChanged,
|
||||||
this, &LibraryDetailsController::slotIncludePathChanged);
|
this, &LibraryDetailsController::slotIncludePathChanged);
|
||||||
connect(m_libraryDetailsWidget->frameworkRadio, &QAbstractButton::clicked,
|
connect(m_libraryDetailsWidget->frameworkRadio, &QAbstractButton::clicked,
|
||||||
this, &LibraryDetailsController::slotMacLibraryTypeChanged);
|
this, &LibraryDetailsController::slotMacLibraryTypeChanged);
|
||||||
@@ -108,9 +110,9 @@ AddLibraryWizard::MacLibraryType LibraryDetailsController::macLibraryType() cons
|
|||||||
return m_macLibraryType;
|
return m_macLibraryType;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::OsType LibraryDetailsController::libraryPlatformType() const
|
OsType LibraryDetailsController::libraryPlatformType() const
|
||||||
{
|
{
|
||||||
return Utils::OsType(m_libraryDetailsWidget->libraryTypeComboBox->currentData().value<int>());
|
return OsType(m_libraryDetailsWidget->libraryTypeComboBox->currentData().value<int>());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString LibraryDetailsController::libraryPlatformFilter() const
|
QString LibraryDetailsController::libraryPlatformFilter() const
|
||||||
@@ -198,7 +200,7 @@ void LibraryDetailsController::updateGui()
|
|||||||
// UGLY HACK END
|
// UGLY HACK END
|
||||||
}
|
}
|
||||||
|
|
||||||
QString LibraryDetailsController::proFile() const
|
FilePath LibraryDetailsController::proFile() const
|
||||||
{
|
{
|
||||||
return m_proFile;
|
return m_proFile;
|
||||||
}
|
}
|
||||||
@@ -397,7 +399,7 @@ static QString smartQuote(const QString &aString)
|
|||||||
{
|
{
|
||||||
// The OS type is not important in that case, but use always the same
|
// The OS type is not important in that case, but use always the same
|
||||||
// in order not to generate different quoting depending on host platform
|
// in order not to generate different quoting depending on host platform
|
||||||
return Utils::ProcessArgs::quoteArg(aString, Utils::OsTypeLinux);
|
return ProcessArgs::quoteArg(aString, OsTypeLinux);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString appendSeparator(const QString &aString)
|
static QString appendSeparator(const QString &aString)
|
||||||
@@ -622,15 +624,15 @@ static QString generatePreTargetDepsSnippet(AddLibraryWizard::Platforms platform
|
|||||||
|
|
||||||
NonInternalLibraryDetailsController::NonInternalLibraryDetailsController(
|
NonInternalLibraryDetailsController::NonInternalLibraryDetailsController(
|
||||||
Ui::LibraryDetailsWidget *libraryDetails,
|
Ui::LibraryDetailsWidget *libraryDetails,
|
||||||
const QString &proFile, QObject *parent) :
|
const FilePath &proFile, QObject *parent) :
|
||||||
LibraryDetailsController(libraryDetails, proFile, parent)
|
LibraryDetailsController(libraryDetails, proFile, parent)
|
||||||
{
|
{
|
||||||
setLibraryComboBoxVisible(false);
|
setLibraryComboBoxVisible(false);
|
||||||
setLibraryPathChooserVisible(true);
|
setLibraryPathChooserVisible(true);
|
||||||
|
|
||||||
connect(libraryDetailsWidget()->libraryPathChooser, &Utils::PathChooser::validChanged,
|
connect(libraryDetailsWidget()->libraryPathChooser, &PathChooser::validChanged,
|
||||||
this, &LibraryDetailsController::completeChanged);
|
this, &LibraryDetailsController::completeChanged);
|
||||||
connect(libraryDetailsWidget()->libraryPathChooser, &Utils::PathChooser::rawPathChanged,
|
connect(libraryDetailsWidget()->libraryPathChooser, &PathChooser::rawPathChanged,
|
||||||
this, &NonInternalLibraryDetailsController::slotLibraryPathChanged);
|
this, &NonInternalLibraryDetailsController::slotLibraryPathChanged);
|
||||||
connect(libraryDetailsWidget()->removeSuffixCheckBox, &QAbstractButton::toggled,
|
connect(libraryDetailsWidget()->removeSuffixCheckBox, &QAbstractButton::toggled,
|
||||||
this, &NonInternalLibraryDetailsController::slotRemoveSuffixChanged);
|
this, &NonInternalLibraryDetailsController::slotRemoveSuffixChanged);
|
||||||
@@ -646,7 +648,7 @@ NonInternalLibraryDetailsController::NonInternalLibraryDetailsController(
|
|||||||
AddLibraryWizard::LinkageType NonInternalLibraryDetailsController::suggestedLinkageType() const
|
AddLibraryWizard::LinkageType NonInternalLibraryDetailsController::suggestedLinkageType() const
|
||||||
{
|
{
|
||||||
AddLibraryWizard::LinkageType type = AddLibraryWizard::NoLinkage;
|
AddLibraryWizard::LinkageType type = AddLibraryWizard::NoLinkage;
|
||||||
if (libraryPlatformType() != Utils::OsTypeWindows) {
|
if (libraryPlatformType() != OsTypeWindows) {
|
||||||
if (libraryDetailsWidget()->libraryPathChooser->isValid()) {
|
if (libraryDetailsWidget()->libraryPathChooser->isValid()) {
|
||||||
QFileInfo fi(libraryDetailsWidget()->libraryPathChooser->filePath().toString());
|
QFileInfo fi(libraryDetailsWidget()->libraryPathChooser->filePath().toString());
|
||||||
if (fi.suffix() == QLatin1String("a"))
|
if (fi.suffix() == QLatin1String("a"))
|
||||||
@@ -661,7 +663,7 @@ AddLibraryWizard::LinkageType NonInternalLibraryDetailsController::suggestedLink
|
|||||||
AddLibraryWizard::MacLibraryType NonInternalLibraryDetailsController::suggestedMacLibraryType() const
|
AddLibraryWizard::MacLibraryType NonInternalLibraryDetailsController::suggestedMacLibraryType() const
|
||||||
{
|
{
|
||||||
AddLibraryWizard::MacLibraryType type = AddLibraryWizard::NoLibraryType;
|
AddLibraryWizard::MacLibraryType type = AddLibraryWizard::NoLibraryType;
|
||||||
if (libraryPlatformType() == Utils::OsTypeMac) {
|
if (libraryPlatformType() == OsTypeMac) {
|
||||||
if (libraryDetailsWidget()->libraryPathChooser->isValid()) {
|
if (libraryDetailsWidget()->libraryPathChooser->isValid()) {
|
||||||
QFileInfo fi(libraryDetailsWidget()->libraryPathChooser->filePath().toString());
|
QFileInfo fi(libraryDetailsWidget()->libraryPathChooser->filePath().toString());
|
||||||
if (fi.suffix() == QLatin1String("framework"))
|
if (fi.suffix() == QLatin1String("framework"))
|
||||||
@@ -695,7 +697,7 @@ QString NonInternalLibraryDetailsController::suggestedIncludePath() const
|
|||||||
void NonInternalLibraryDetailsController::updateWindowsOptionsEnablement()
|
void NonInternalLibraryDetailsController::updateWindowsOptionsEnablement()
|
||||||
{
|
{
|
||||||
bool ena = platforms() & (AddLibraryWizard::WindowsMinGWPlatform | AddLibraryWizard::WindowsMSVCPlatform);
|
bool ena = platforms() & (AddLibraryWizard::WindowsMinGWPlatform | AddLibraryWizard::WindowsMSVCPlatform);
|
||||||
if (libraryPlatformType() == Utils::OsTypeWindows) {
|
if (libraryPlatformType() == OsTypeWindows) {
|
||||||
libraryDetailsWidget()->addSuffixCheckBox->setEnabled(ena);
|
libraryDetailsWidget()->addSuffixCheckBox->setEnabled(ena);
|
||||||
ena = true;
|
ena = true;
|
||||||
}
|
}
|
||||||
@@ -732,10 +734,10 @@ void NonInternalLibraryDetailsController::slotRemoveSuffixChanged(bool ena)
|
|||||||
void NonInternalLibraryDetailsController::handleLibraryTypeChange()
|
void NonInternalLibraryDetailsController::handleLibraryTypeChange()
|
||||||
{
|
{
|
||||||
libraryDetailsWidget()->libraryPathChooser->setPromptDialogFilter(libraryPlatformFilter());
|
libraryDetailsWidget()->libraryPathChooser->setPromptDialogFilter(libraryPlatformFilter());
|
||||||
const bool isMacOs = libraryPlatformType() == Utils::OsTypeMac;
|
const bool isMacOs = libraryPlatformType() == OsTypeMac;
|
||||||
const bool isWindows = libraryPlatformType() == Utils::OsTypeWindows;
|
const bool isWindows = libraryPlatformType() == OsTypeWindows;
|
||||||
libraryDetailsWidget()->libraryPathChooser->setExpectedKind(isMacOs ? Utils::PathChooser::Any
|
libraryDetailsWidget()->libraryPathChooser->setExpectedKind(isMacOs ? PathChooser::Any
|
||||||
: Utils::PathChooser::File);
|
: PathChooser::File);
|
||||||
setMacLibraryRadiosVisible(!isMacOs);
|
setMacLibraryRadiosVisible(!isMacOs);
|
||||||
setLinkageRadiosVisible(isWindows);
|
setLinkageRadiosVisible(isWindows);
|
||||||
setRemoveSuffixVisible(isWindows);
|
setRemoveSuffixVisible(isWindows);
|
||||||
@@ -752,7 +754,7 @@ void NonInternalLibraryDetailsController::slotLibraryTypeChanged()
|
|||||||
|
|
||||||
void NonInternalLibraryDetailsController::handleLibraryPathChange()
|
void NonInternalLibraryDetailsController::handleLibraryPathChange()
|
||||||
{
|
{
|
||||||
if (libraryPlatformType() == Utils::OsTypeWindows) {
|
if (libraryPlatformType() == OsTypeWindows) {
|
||||||
bool subfoldersEnabled = true;
|
bool subfoldersEnabled = true;
|
||||||
bool removeSuffixEnabled = true;
|
bool removeSuffixEnabled = true;
|
||||||
if (libraryDetailsWidget()->libraryPathChooser->isValid()) {
|
if (libraryDetailsWidget()->libraryPathChooser->isValid()) {
|
||||||
@@ -797,13 +799,13 @@ QString NonInternalLibraryDetailsController::snippet() const
|
|||||||
QString libName;
|
QString libName;
|
||||||
const bool removeSuffix = isWindowsGroupVisible()
|
const bool removeSuffix = isWindowsGroupVisible()
|
||||||
&& libraryDetailsWidget()->removeSuffixCheckBox->isChecked();
|
&& libraryDetailsWidget()->removeSuffixCheckBox->isChecked();
|
||||||
if (libraryPlatformType() == Utils::OsTypeWindows) {
|
if (libraryPlatformType() == OsTypeWindows) {
|
||||||
libName = fi.completeBaseName();
|
libName = fi.completeBaseName();
|
||||||
if (removeSuffix && !libName.isEmpty()) // remove last letter which needs to be "d"
|
if (removeSuffix && !libName.isEmpty()) // remove last letter which needs to be "d"
|
||||||
libName = libName.left(libName.size() - 1);
|
libName = libName.left(libName.size() - 1);
|
||||||
if (fi.completeSuffix() == QLatin1String("a")) // the mingw lib case
|
if (fi.completeSuffix() == QLatin1String("a")) // the mingw lib case
|
||||||
libName = libName.mid(3); // cut the "lib" prefix
|
libName = libName.mid(3); // cut the "lib" prefix
|
||||||
} else if (libraryPlatformType() == Utils::OsTypeMac) {
|
} else if (libraryPlatformType() == OsTypeMac) {
|
||||||
if (macLibraryType() == AddLibraryWizard::FrameworkType)
|
if (macLibraryType() == AddLibraryWizard::FrameworkType)
|
||||||
libName = fi.completeBaseName();
|
libName = fi.completeBaseName();
|
||||||
else
|
else
|
||||||
@@ -817,7 +819,7 @@ QString NonInternalLibraryDetailsController::snippet() const
|
|||||||
if (isWindowsGroupVisible()) {
|
if (isWindowsGroupVisible()) {
|
||||||
// when we are on Win but we don't generate the code for Win
|
// when we are on Win but we don't generate the code for Win
|
||||||
// we still need to remove "debug" or "release" subfolder
|
// we still need to remove "debug" or "release" subfolder
|
||||||
const bool useSubfoldersCondition = (libraryPlatformType() == Utils::OsTypeWindows)
|
const bool useSubfoldersCondition = (libraryPlatformType() == OsTypeWindows)
|
||||||
? true : platforms() & (AddLibraryWizard::WindowsMinGWPlatform
|
? true : platforms() & (AddLibraryWizard::WindowsMinGWPlatform
|
||||||
| AddLibraryWizard::WindowsMSVCPlatform);
|
| AddLibraryWizard::WindowsMSVCPlatform);
|
||||||
if (useSubfoldersCondition)
|
if (useSubfoldersCondition)
|
||||||
@@ -829,10 +831,10 @@ QString NonInternalLibraryDetailsController::snippet() const
|
|||||||
QString targetRelativePath;
|
QString targetRelativePath;
|
||||||
QString includeRelativePath;
|
QString includeRelativePath;
|
||||||
if (isIncludePathVisible()) { // generate also the path to lib
|
if (isIncludePathVisible()) { // generate also the path to lib
|
||||||
QFileInfo pfi(proFile());
|
QFileInfo pfi = proFile().toFileInfo();
|
||||||
QDir pdir = pfi.absoluteDir();
|
QDir pdir = pfi.absoluteDir();
|
||||||
QString absoluteLibraryPath = fi.absolutePath();
|
QString absoluteLibraryPath = fi.absolutePath();
|
||||||
if (libraryPlatformType() == Utils::OsTypeWindows && useSubfolders) { // drop last subfolder which needs to be "debug" or "release"
|
if (libraryPlatformType() == OsTypeWindows && useSubfolders) { // drop last subfolder which needs to be "debug" or "release"
|
||||||
QFileInfo libfi(absoluteLibraryPath);
|
QFileInfo libfi(absoluteLibraryPath);
|
||||||
absoluteLibraryPath = libfi.absolutePath();
|
absoluteLibraryPath = libfi.absolutePath();
|
||||||
}
|
}
|
||||||
@@ -862,7 +864,7 @@ QString NonInternalLibraryDetailsController::snippet() const
|
|||||||
|
|
||||||
PackageLibraryDetailsController::PackageLibraryDetailsController(
|
PackageLibraryDetailsController::PackageLibraryDetailsController(
|
||||||
Ui::LibraryDetailsWidget *libraryDetails,
|
Ui::LibraryDetailsWidget *libraryDetails,
|
||||||
const QString &proFile, QObject *parent)
|
const FilePath &proFile, QObject *parent)
|
||||||
: NonInternalLibraryDetailsController(libraryDetails, proFile, parent)
|
: NonInternalLibraryDetailsController(libraryDetails, proFile, parent)
|
||||||
{
|
{
|
||||||
setPlatformsVisible(false);
|
setPlatformsVisible(false);
|
||||||
@@ -897,11 +899,11 @@ QString PackageLibraryDetailsController::snippet() const
|
|||||||
|
|
||||||
bool PackageLibraryDetailsController::isLinkPackageGenerated() const
|
bool PackageLibraryDetailsController::isLinkPackageGenerated() const
|
||||||
{
|
{
|
||||||
const Project *project = SessionManager::projectForFile(Utils::FilePath::fromString(proFile()));
|
const Project *project = SessionManager::projectForFile(proFile());
|
||||||
if (!project)
|
if (!project)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const ProjectNode *projectNode = project->findNodeForBuildKey(proFile());
|
const ProjectNode *projectNode = project->findNodeForBuildKey(proFile().toString());
|
||||||
if (!projectNode)
|
if (!projectNode)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -921,7 +923,7 @@ bool PackageLibraryDetailsController::isLinkPackageGenerated() const
|
|||||||
|
|
||||||
SystemLibraryDetailsController::SystemLibraryDetailsController(
|
SystemLibraryDetailsController::SystemLibraryDetailsController(
|
||||||
Ui::LibraryDetailsWidget *libraryDetails,
|
Ui::LibraryDetailsWidget *libraryDetails,
|
||||||
const QString &proFile, QObject *parent)
|
const FilePath &proFile, QObject *parent)
|
||||||
: NonInternalLibraryDetailsController(libraryDetails, proFile, parent)
|
: NonInternalLibraryDetailsController(libraryDetails, proFile, parent)
|
||||||
{
|
{
|
||||||
setIncludePathVisible(false);
|
setIncludePathVisible(false);
|
||||||
@@ -934,7 +936,7 @@ SystemLibraryDetailsController::SystemLibraryDetailsController(
|
|||||||
|
|
||||||
ExternalLibraryDetailsController::ExternalLibraryDetailsController(
|
ExternalLibraryDetailsController::ExternalLibraryDetailsController(
|
||||||
Ui::LibraryDetailsWidget *libraryDetails,
|
Ui::LibraryDetailsWidget *libraryDetails,
|
||||||
const QString &proFile, QObject *parent)
|
const FilePath &proFile, QObject *parent)
|
||||||
: NonInternalLibraryDetailsController(libraryDetails, proFile, parent)
|
: NonInternalLibraryDetailsController(libraryDetails, proFile, parent)
|
||||||
{
|
{
|
||||||
setIncludePathVisible(true);
|
setIncludePathVisible(true);
|
||||||
@@ -949,7 +951,7 @@ void ExternalLibraryDetailsController::updateWindowsOptionsEnablement()
|
|||||||
|
|
||||||
bool subfoldersEnabled = true;
|
bool subfoldersEnabled = true;
|
||||||
bool removeSuffixEnabled = true;
|
bool removeSuffixEnabled = true;
|
||||||
if (libraryPlatformType() == Utils::OsTypeWindows
|
if (libraryPlatformType() == OsTypeWindows
|
||||||
&& libraryDetailsWidget()->libraryPathChooser->isValid()) {
|
&& libraryDetailsWidget()->libraryPathChooser->isValid()) {
|
||||||
QFileInfo fi(libraryDetailsWidget()->libraryPathChooser->filePath().toString());
|
QFileInfo fi(libraryDetailsWidget()->libraryPathChooser->filePath().toString());
|
||||||
QFileInfo dfi(fi.absolutePath());
|
QFileInfo dfi(fi.absolutePath());
|
||||||
@@ -968,9 +970,8 @@ void ExternalLibraryDetailsController::updateWindowsOptionsEnablement()
|
|||||||
|
|
||||||
/////////////
|
/////////////
|
||||||
|
|
||||||
InternalLibraryDetailsController::InternalLibraryDetailsController(
|
InternalLibraryDetailsController::InternalLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails,
|
||||||
Ui::LibraryDetailsWidget *libraryDetails,
|
const FilePath &proFile, QObject *parent)
|
||||||
const QString &proFile, QObject *parent)
|
|
||||||
: LibraryDetailsController(libraryDetails, proFile, parent)
|
: LibraryDetailsController(libraryDetails, proFile, parent)
|
||||||
{
|
{
|
||||||
setLinkageRadiosVisible(false);
|
setLinkageRadiosVisible(false);
|
||||||
@@ -980,7 +981,7 @@ InternalLibraryDetailsController::InternalLibraryDetailsController(
|
|||||||
setWindowsGroupVisible(true);
|
setWindowsGroupVisible(true);
|
||||||
setRemoveSuffixVisible(false);
|
setRemoveSuffixVisible(false);
|
||||||
|
|
||||||
if (Utils::HostOsInfo::isWindowsHost())
|
if (HostOsInfo::isWindowsHost())
|
||||||
libraryDetailsWidget()->useSubfoldersCheckBox->setEnabled(true);
|
libraryDetailsWidget()->useSubfoldersCheckBox->setEnabled(true);
|
||||||
|
|
||||||
connect(libraryDetailsWidget()->libraryComboBox,
|
connect(libraryDetailsWidget()->libraryComboBox,
|
||||||
@@ -1034,7 +1035,7 @@ QString InternalLibraryDetailsController::suggestedIncludePath() const
|
|||||||
|
|
||||||
void InternalLibraryDetailsController::updateWindowsOptionsEnablement()
|
void InternalLibraryDetailsController::updateWindowsOptionsEnablement()
|
||||||
{
|
{
|
||||||
if (Utils::HostOsInfo::isWindowsHost())
|
if (HostOsInfo::isWindowsHost())
|
||||||
libraryDetailsWidget()->addSuffixCheckBox->setEnabled(true);
|
libraryDetailsWidget()->addSuffixCheckBox->setEnabled(true);
|
||||||
libraryDetailsWidget()->winGroupBox->setEnabled(platforms()
|
libraryDetailsWidget()->winGroupBox->setEnabled(platforms()
|
||||||
& (AddLibraryWizard::WindowsMinGWPlatform | AddLibraryWizard::WindowsMSVCPlatform));
|
& (AddLibraryWizard::WindowsMinGWPlatform | AddLibraryWizard::WindowsMSVCPlatform));
|
||||||
@@ -1047,7 +1048,7 @@ void InternalLibraryDetailsController::updateProFile()
|
|||||||
libraryDetailsWidget()->libraryComboBox->clear();
|
libraryDetailsWidget()->libraryComboBox->clear();
|
||||||
|
|
||||||
const QmakeProject *project
|
const QmakeProject *project
|
||||||
= dynamic_cast<QmakeProject *>(SessionManager::projectForFile(Utils::FilePath::fromString(proFile())));
|
= dynamic_cast<QmakeProject *>(SessionManager::projectForFile(proFile()));
|
||||||
if (!project)
|
if (!project)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1091,7 +1092,7 @@ void InternalLibraryDetailsController::slotCurrentLibraryChanged()
|
|||||||
currentIndex, Qt::ToolTipRole).toString());
|
currentIndex, Qt::ToolTipRole).toString());
|
||||||
QmakeProFile *proFile = m_proFiles.at(currentIndex);
|
QmakeProFile *proFile = m_proFiles.at(currentIndex);
|
||||||
const QStringList configVar = proFile->variableValue(Variable::Config);
|
const QStringList configVar = proFile->variableValue(Variable::Config);
|
||||||
if (Utils::HostOsInfo::isWindowsHost()) {
|
if (HostOsInfo::isWindowsHost()) {
|
||||||
bool useSubfolders = false;
|
bool useSubfolders = false;
|
||||||
if (configVar.contains(QLatin1String("debug_and_release"))
|
if (configVar.contains(QLatin1String("debug_and_release"))
|
||||||
&& configVar.contains(QLatin1String("debug_and_release_target")))
|
&& configVar.contains(QLatin1String("debug_and_release_target")))
|
||||||
@@ -1130,10 +1131,10 @@ QString InternalLibraryDetailsController::snippet() const
|
|||||||
|
|
||||||
// relative path for the project for which we insert the snippet,
|
// relative path for the project for which we insert the snippet,
|
||||||
// it's relative to the root project
|
// it's relative to the root project
|
||||||
const QString proRelavitePath = rootDir.relativeFilePath(proFile());
|
const QString proRelavitePath = rootDir.relativeFilePath(proFile().toString());
|
||||||
|
|
||||||
// project for which we insert the snippet
|
// project for which we insert the snippet
|
||||||
const Project *project = SessionManager::projectForFile(Utils::FilePath::fromString(proFile()));
|
const Project *project = SessionManager::projectForFile(proFile());
|
||||||
|
|
||||||
// the build directory of the active build configuration
|
// the build directory of the active build configuration
|
||||||
QDir rootBuildDir = rootDir; // If the project is unconfigured use the project dir
|
QDir rootBuildDir = rootDir; // If the project is unconfigured use the project dir
|
||||||
@@ -1147,7 +1148,7 @@ QString InternalLibraryDetailsController::snippet() const
|
|||||||
QDir projectBuildDir(pfi.absolutePath());
|
QDir projectBuildDir(pfi.absolutePath());
|
||||||
|
|
||||||
// current project node from combobox
|
// current project node from combobox
|
||||||
QFileInfo fi(proFile());
|
QFileInfo fi = proFile().toFileInfo();
|
||||||
QDir projectSrcDir(fi.absolutePath());
|
QDir projectSrcDir(fi.absolutePath());
|
||||||
|
|
||||||
// project node which we want to link against
|
// project node which we want to link against
|
||||||
@@ -1175,3 +1176,6 @@ QString InternalLibraryDetailsController::snippet() const
|
|||||||
useSubfolders, addSuffix);
|
useSubfolders, addSuffix);
|
||||||
return snippetMessage;
|
return snippetMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // Internal
|
||||||
|
} // QmakeProjectManager
|
||||||
|
@@ -38,7 +38,7 @@ class LibraryDetailsController : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit LibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails,
|
explicit LibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails,
|
||||||
const QString &proFile,
|
const Utils::FilePath &proFile,
|
||||||
QObject *parent = nullptr);
|
QObject *parent = nullptr);
|
||||||
virtual bool isComplete() const = 0;
|
virtual bool isComplete() const = 0;
|
||||||
virtual QString snippet() const = 0;
|
virtual QString snippet() const = 0;
|
||||||
@@ -54,7 +54,7 @@ protected:
|
|||||||
AddLibraryWizard::MacLibraryType macLibraryType() const;
|
AddLibraryWizard::MacLibraryType macLibraryType() const;
|
||||||
Utils::OsType libraryPlatformType() const;
|
Utils::OsType libraryPlatformType() const;
|
||||||
QString libraryPlatformFilter() const;
|
QString libraryPlatformFilter() const;
|
||||||
QString proFile() const;
|
Utils::FilePath proFile() const;
|
||||||
bool isIncludePathChanged() const;
|
bool isIncludePathChanged() const;
|
||||||
bool guiSignalsIgnored() const;
|
bool guiSignalsIgnored() const;
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ private:
|
|||||||
AddLibraryWizard::LinkageType m_linkageType = AddLibraryWizard::NoLinkage;
|
AddLibraryWizard::LinkageType m_linkageType = AddLibraryWizard::NoLinkage;
|
||||||
AddLibraryWizard::MacLibraryType m_macLibraryType = AddLibraryWizard::NoLibraryType;
|
AddLibraryWizard::MacLibraryType m_macLibraryType = AddLibraryWizard::NoLibraryType;
|
||||||
|
|
||||||
QString m_proFile;
|
Utils::FilePath m_proFile;
|
||||||
|
|
||||||
bool m_ignoreGuiSignals = false;
|
bool m_ignoreGuiSignals = false;
|
||||||
bool m_includePathChanged = false;
|
bool m_includePathChanged = false;
|
||||||
@@ -118,7 +118,7 @@ class NonInternalLibraryDetailsController : public LibraryDetailsController
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit NonInternalLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails,
|
explicit NonInternalLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails,
|
||||||
const QString &proFile,
|
const Utils::FilePath &proFile,
|
||||||
QObject *parent = nullptr);
|
QObject *parent = nullptr);
|
||||||
bool isComplete() const override;
|
bool isComplete() const override;
|
||||||
QString snippet() const override;
|
QString snippet() const override;
|
||||||
@@ -143,7 +143,7 @@ class PackageLibraryDetailsController : public NonInternalLibraryDetailsControll
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit PackageLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails,
|
explicit PackageLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails,
|
||||||
const QString &proFile,
|
const Utils::FilePath &proFile,
|
||||||
QObject *parent = nullptr);
|
QObject *parent = nullptr);
|
||||||
bool isComplete() const override;
|
bool isComplete() const override;
|
||||||
QString snippet() const override;
|
QString snippet() const override;
|
||||||
@@ -160,7 +160,7 @@ class SystemLibraryDetailsController : public NonInternalLibraryDetailsControlle
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit SystemLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails,
|
explicit SystemLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails,
|
||||||
const QString &proFile,
|
const Utils::FilePath &proFile,
|
||||||
QObject *parent = nullptr);
|
QObject *parent = nullptr);
|
||||||
protected:
|
protected:
|
||||||
void updateWindowsOptionsEnablement() override final {
|
void updateWindowsOptionsEnablement() override final {
|
||||||
@@ -173,7 +173,7 @@ class ExternalLibraryDetailsController : public NonInternalLibraryDetailsControl
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ExternalLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails,
|
explicit ExternalLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails,
|
||||||
const QString &proFile,
|
const Utils::FilePath &proFile,
|
||||||
QObject *parent = nullptr);
|
QObject *parent = nullptr);
|
||||||
protected:
|
protected:
|
||||||
void updateWindowsOptionsEnablement() override final;
|
void updateWindowsOptionsEnablement() override final;
|
||||||
@@ -184,7 +184,7 @@ class InternalLibraryDetailsController : public LibraryDetailsController
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit InternalLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails,
|
explicit InternalLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails,
|
||||||
const QString &proFile,
|
const Utils::FilePath &proFile,
|
||||||
QObject *parent = nullptr);
|
QObject *parent = nullptr);
|
||||||
bool isComplete() const override;
|
bool isComplete() const override;
|
||||||
QString snippet() const override;
|
QString snippet() const override;
|
||||||
|
@@ -73,6 +73,7 @@
|
|||||||
using namespace Core;
|
using namespace Core;
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
using namespace TextEditor;
|
using namespace TextEditor;
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace QmakeProjectManager {
|
namespace QmakeProjectManager {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -90,7 +91,7 @@ public:
|
|||||||
void buildStateChanged(Project *pro);
|
void buildStateChanged(Project *pro);
|
||||||
void updateBuildFileAction();
|
void updateBuildFileAction();
|
||||||
void disableBuildFileMenus();
|
void disableBuildFileMenus();
|
||||||
void enableBuildFileMenus(const Utils::FilePath &file);
|
void enableBuildFileMenus(const FilePath &file);
|
||||||
|
|
||||||
Core::Context projectContext;
|
Core::Context projectContext;
|
||||||
|
|
||||||
@@ -114,15 +115,15 @@ public:
|
|||||||
|
|
||||||
QAction *m_runQMakeAction = nullptr;
|
QAction *m_runQMakeAction = nullptr;
|
||||||
QAction *m_runQMakeActionContextMenu = nullptr;
|
QAction *m_runQMakeActionContextMenu = nullptr;
|
||||||
Utils::ParameterAction *m_buildSubProjectContextMenu = nullptr;
|
ParameterAction *m_buildSubProjectContextMenu = nullptr;
|
||||||
QAction *m_subProjectRebuildSeparator = nullptr;
|
QAction *m_subProjectRebuildSeparator = nullptr;
|
||||||
QAction *m_rebuildSubProjectContextMenu = nullptr;
|
QAction *m_rebuildSubProjectContextMenu = nullptr;
|
||||||
QAction *m_cleanSubProjectContextMenu = nullptr;
|
QAction *m_cleanSubProjectContextMenu = nullptr;
|
||||||
QAction *m_buildFileContextMenu = nullptr;
|
QAction *m_buildFileContextMenu = nullptr;
|
||||||
Utils::ParameterAction *m_buildSubProjectAction = nullptr;
|
ParameterAction *m_buildSubProjectAction = nullptr;
|
||||||
QAction *m_rebuildSubProjectAction = nullptr;
|
QAction *m_rebuildSubProjectAction = nullptr;
|
||||||
QAction *m_cleanSubProjectAction = nullptr;
|
QAction *m_cleanSubProjectAction = nullptr;
|
||||||
Utils::ParameterAction *m_buildFileAction = nullptr;
|
ParameterAction *m_buildFileAction = nullptr;
|
||||||
QAction *m_addLibraryAction = nullptr;
|
QAction *m_addLibraryAction = nullptr;
|
||||||
QAction *m_addLibraryActionContextMenu = nullptr;
|
QAction *m_addLibraryActionContextMenu = nullptr;
|
||||||
|
|
||||||
@@ -140,7 +141,7 @@ public:
|
|||||||
void buildFile();
|
void buildFile();
|
||||||
|
|
||||||
void handleSubDirContextMenu(QmakeBuildSystem::Action action, bool isFileBuild);
|
void handleSubDirContextMenu(QmakeBuildSystem::Action action, bool isFileBuild);
|
||||||
void addLibraryImpl(const QString &fileName, TextEditor::BaseTextEditor *editor);
|
void addLibraryImpl(const FilePath &filePath, TextEditor::BaseTextEditor *editor);
|
||||||
void runQMakeImpl(Project *p, ProjectExplorer::Node *node);
|
void runQMakeImpl(Project *p, ProjectExplorer::Node *node);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -181,8 +182,8 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString
|
|||||||
//register actions
|
//register actions
|
||||||
Command *command = nullptr;
|
Command *command = nullptr;
|
||||||
|
|
||||||
d->m_buildSubProjectContextMenu = new Utils::ParameterAction(tr("Build"), tr("Build \"%1\""),
|
d->m_buildSubProjectContextMenu = new ParameterAction(tr("Build"), tr("Build \"%1\""),
|
||||||
Utils::ParameterAction::AlwaysEnabled/*handled manually*/,
|
ParameterAction::AlwaysEnabled/*handled manually*/,
|
||||||
this);
|
this);
|
||||||
command = ActionManager::registerAction(d->m_buildSubProjectContextMenu, Constants::BUILDSUBDIRCONTEXTMENU, projectContext);
|
command = ActionManager::registerAction(d->m_buildSubProjectContextMenu, Constants::BUILDSUBDIRCONTEXTMENU, projectContext);
|
||||||
command->setAttribute(Command::CA_Hide);
|
command->setAttribute(Command::CA_Hide);
|
||||||
@@ -227,8 +228,8 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString
|
|||||||
connect(d->m_buildFileContextMenu, &QAction::triggered,
|
connect(d->m_buildFileContextMenu, &QAction::triggered,
|
||||||
d, &QmakeProjectManagerPluginPrivate::buildFileContextMenu);
|
d, &QmakeProjectManagerPluginPrivate::buildFileContextMenu);
|
||||||
|
|
||||||
d->m_buildSubProjectAction = new Utils::ParameterAction(tr("Build &Subproject"), tr("Build &Subproject \"%1\""),
|
d->m_buildSubProjectAction = new ParameterAction(tr("Build &Subproject"), tr("Build &Subproject \"%1\""),
|
||||||
Utils::ParameterAction::AlwaysEnabled, this);
|
ParameterAction::AlwaysEnabled, this);
|
||||||
command = ActionManager::registerAction(d->m_buildSubProjectAction, Constants::BUILDSUBDIR, projectContext);
|
command = ActionManager::registerAction(d->m_buildSubProjectAction, Constants::BUILDSUBDIR, projectContext);
|
||||||
command->setAttribute(Command::CA_Hide);
|
command->setAttribute(Command::CA_Hide);
|
||||||
command->setAttribute(Command::CA_UpdateText);
|
command->setAttribute(Command::CA_UpdateText);
|
||||||
@@ -244,8 +245,7 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString
|
|||||||
connect(d->m_runQMakeAction, &QAction::triggered,
|
connect(d->m_runQMakeAction, &QAction::triggered,
|
||||||
d, &QmakeProjectManagerPluginPrivate::runQMake);
|
d, &QmakeProjectManagerPluginPrivate::runQMake);
|
||||||
|
|
||||||
d->m_rebuildSubProjectAction = new QAction(Icons::REBUILD.icon(), tr("Rebuild"),
|
d->m_rebuildSubProjectAction = new QAction(ProjectExplorer::Icons::REBUILD.icon(), tr("Rebuild"), this);
|
||||||
this);
|
|
||||||
d->m_rebuildSubProjectAction->setWhatsThis(tr("Rebuild Subproject"));
|
d->m_rebuildSubProjectAction->setWhatsThis(tr("Rebuild Subproject"));
|
||||||
command = ActionManager::registerAction(d->m_rebuildSubProjectAction, Constants::REBUILDSUBDIR, projectContext);
|
command = ActionManager::registerAction(d->m_rebuildSubProjectAction, Constants::REBUILDSUBDIR, projectContext);
|
||||||
command->setAttribute(Command::CA_Hide);
|
command->setAttribute(Command::CA_Hide);
|
||||||
@@ -265,8 +265,8 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString
|
|||||||
connect(d->m_cleanSubProjectAction, &QAction::triggered,
|
connect(d->m_cleanSubProjectAction, &QAction::triggered,
|
||||||
d, &QmakeProjectManagerPluginPrivate::cleanSubDirContextMenu);
|
d, &QmakeProjectManagerPluginPrivate::cleanSubDirContextMenu);
|
||||||
|
|
||||||
d->m_buildFileAction = new Utils::ParameterAction(tr("Build File"), tr("Build File \"%1\""),
|
d->m_buildFileAction = new ParameterAction(tr("Build File"), tr("Build File \"%1\""),
|
||||||
Utils::ParameterAction::AlwaysEnabled, this);
|
ParameterAction::AlwaysEnabled, this);
|
||||||
command = ActionManager::registerAction(d->m_buildFileAction, Constants::BUILDFILE, projectContext);
|
command = ActionManager::registerAction(d->m_buildFileAction, Constants::BUILDFILE, projectContext);
|
||||||
command->setAttribute(Command::CA_Hide);
|
command->setAttribute(Command::CA_Hide);
|
||||||
command->setAttribute(Command::CA_UpdateText);
|
command->setAttribute(Command::CA_UpdateText);
|
||||||
@@ -361,33 +361,33 @@ static QmakeProFileNode *buildableFileProFile(Node *node)
|
|||||||
void QmakeProjectManagerPluginPrivate::addLibrary()
|
void QmakeProjectManagerPluginPrivate::addLibrary()
|
||||||
{
|
{
|
||||||
if (auto editor = qobject_cast<BaseTextEditor *>(Core::EditorManager::currentEditor()))
|
if (auto editor = qobject_cast<BaseTextEditor *>(Core::EditorManager::currentEditor()))
|
||||||
addLibraryImpl(editor->document()->filePath().toString(), editor);
|
addLibraryImpl(editor->document()->filePath(), editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmakeProjectManagerPluginPrivate::addLibraryContextMenu()
|
void QmakeProjectManagerPluginPrivate::addLibraryContextMenu()
|
||||||
{
|
{
|
||||||
QString projectPath;
|
FilePath projectPath;
|
||||||
|
|
||||||
Node *node = ProjectTree::currentNode();
|
Node *node = ProjectTree::currentNode();
|
||||||
if (ContainerNode *cn = node->asContainerNode())
|
if (ContainerNode *cn = node->asContainerNode())
|
||||||
projectPath = cn->project()->projectFilePath().toString();
|
projectPath = cn->project()->projectFilePath();
|
||||||
else if (dynamic_cast<QmakeProFileNode *>(node))
|
else if (dynamic_cast<QmakeProFileNode *>(node))
|
||||||
projectPath = node->filePath().toString();
|
projectPath = node->filePath();
|
||||||
|
|
||||||
addLibraryImpl(projectPath, nullptr);
|
addLibraryImpl(projectPath, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmakeProjectManagerPluginPrivate::addLibraryImpl(const QString &fileName, BaseTextEditor *editor)
|
void QmakeProjectManagerPluginPrivate::addLibraryImpl(const FilePath &filePath, BaseTextEditor *editor)
|
||||||
{
|
{
|
||||||
if (fileName.isEmpty())
|
if (filePath.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Internal::AddLibraryWizard wizard(fileName, Core::ICore::dialogParent());
|
Internal::AddLibraryWizard wizard(filePath, Core::ICore::dialogParent());
|
||||||
if (wizard.exec() != QDialog::Accepted)
|
if (wizard.exec() != QDialog::Accepted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!editor)
|
if (!editor)
|
||||||
editor = qobject_cast<BaseTextEditor *>(Core::EditorManager::openEditor(fileName,
|
editor = qobject_cast<BaseTextEditor *>(Core::EditorManager::openEditor(filePath,
|
||||||
Constants::PROFILE_EDITOR_ID, Core::EditorManager::DoNotMakeVisible));
|
Constants::PROFILE_EDITOR_ID, Core::EditorManager::DoNotMakeVisible));
|
||||||
if (!editor)
|
if (!editor)
|
||||||
return;
|
return;
|
||||||
@@ -448,7 +448,7 @@ void QmakeProjectManagerPluginPrivate::buildFile()
|
|||||||
if (!currentDocument)
|
if (!currentDocument)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const Utils::FilePath file = currentDocument->filePath();
|
const FilePath file = currentDocument->filePath();
|
||||||
Node *n = ProjectTree::nodeForFile(file);
|
Node *n = ProjectTree::nodeForFile(file);
|
||||||
FileNode *node = n ? n->asFileNode() : nullptr;
|
FileNode *node = n ? n->asFileNode() : nullptr;
|
||||||
if (!node)
|
if (!node)
|
||||||
@@ -599,7 +599,7 @@ void QmakeProjectManagerPluginPrivate::disableBuildFileMenus()
|
|||||||
m_buildFileContextMenu->setEnabled(false);
|
m_buildFileContextMenu->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmakeProjectManagerPluginPrivate::enableBuildFileMenus(const Utils::FilePath &file)
|
void QmakeProjectManagerPluginPrivate::enableBuildFileMenus(const FilePath &file)
|
||||||
{
|
{
|
||||||
bool visible = false;
|
bool visible = false;
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
|
@@ -58,6 +58,7 @@
|
|||||||
#include <QGraphicsLinearLayout>
|
#include <QGraphicsLinearLayout>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QMimeData>
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
@@ -241,6 +242,56 @@ ModelNodePreviewImageOperation DesignerActionManager::modelNodePreviewOperation(
|
|||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DesignerActionManager::externalDragHasSupportedAssets(const QMimeData *mimeData) const
|
||||||
|
{
|
||||||
|
if (!mimeData->hasUrls())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QSet<QString> filtersSet;
|
||||||
|
const QList<AddResourceHandler> handlers = addResourceHandler();
|
||||||
|
for (const AddResourceHandler &handler : handlers)
|
||||||
|
filtersSet.insert(handler.filter);
|
||||||
|
|
||||||
|
const QList<QUrl> urls = mimeData->urls();
|
||||||
|
for (const QUrl &url : urls) {
|
||||||
|
QString suffix = "*." + url.fileName().split('.').last().toLower();
|
||||||
|
if (filtersSet.contains(suffix)) // accept drop if it contains a valid file
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DesignerActionManager::handleExternalAssetsDrop(const QMimeData *mimeData) const
|
||||||
|
{
|
||||||
|
const QList<AddResourceHandler> handlers = addResourceHandler();
|
||||||
|
// create suffix to categry and category to operation hashes
|
||||||
|
QHash<QString, QString> suffixCategory;
|
||||||
|
QHash<QString, AddResourceOperation> categoryOperation;
|
||||||
|
for (const AddResourceHandler &handler : handlers) {
|
||||||
|
suffixCategory.insert(handler.filter, handler.category);
|
||||||
|
categoryOperation.insert(handler.category, handler.operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add files grouped by categories (so that files under same category run under 1 operation)
|
||||||
|
QHash<QString, QStringList> categoryFiles;
|
||||||
|
const QList<QUrl> urls = mimeData->urls();
|
||||||
|
for (const QUrl &url : urls) {
|
||||||
|
QString suffix = "*." + url.fileName().split('.').last().toLower();
|
||||||
|
QString category = suffixCategory.value(suffix);
|
||||||
|
if (!category.isEmpty())
|
||||||
|
categoryFiles[category].append(url.toLocalFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
// run operations
|
||||||
|
const QStringList categories = categoryFiles.keys();
|
||||||
|
for (const QString &category : categories) {
|
||||||
|
AddResourceOperation operation = categoryOperation.value(category);
|
||||||
|
QStringList files = categoryFiles.value(category);
|
||||||
|
operation(files, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class VisiblityModelNodeAction : public ModelNodeContextMenuAction
|
class VisiblityModelNodeAction : public ModelNodeContextMenuAction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@@ -38,6 +38,7 @@
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QGraphicsItem;
|
class QGraphicsItem;
|
||||||
class QGraphicsWidget;
|
class QGraphicsWidget;
|
||||||
|
class QMimeData;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
@@ -135,6 +136,8 @@ public:
|
|||||||
void registerModelNodePreviewHandler(const ModelNodePreviewImageHandler &handler);
|
void registerModelNodePreviewHandler(const ModelNodePreviewImageHandler &handler);
|
||||||
bool hasModelNodePreviewHandler(const ModelNode &node) const;
|
bool hasModelNodePreviewHandler(const ModelNode &node) const;
|
||||||
ModelNodePreviewImageOperation modelNodePreviewOperation(const ModelNode &node) const;
|
ModelNodePreviewImageOperation modelNodePreviewOperation(const ModelNode &node) const;
|
||||||
|
bool externalDragHasSupportedAssets(const QMimeData *data) const;
|
||||||
|
void handleExternalAssetsDrop(const QMimeData *data) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addTransitionEffectAction(const TypeName &typeName);
|
void addTransitionEffectAction(const TypeName &typeName);
|
||||||
|
@@ -81,6 +81,18 @@ void CurveEditor::clearCanvas()
|
|||||||
m_view->reset({});
|
m_view->reset({});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CurveEditor::showEvent(QShowEvent *event)
|
||||||
|
{
|
||||||
|
emit viewEnabledChanged(true);
|
||||||
|
QWidget::showEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CurveEditor::hideEvent(QHideEvent *event)
|
||||||
|
{
|
||||||
|
emit viewEnabledChanged(false);
|
||||||
|
QWidget::hideEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
QToolBar *CurveEditor::createToolBar(CurveEditorModel *model)
|
QToolBar *CurveEditor::createToolBar(CurveEditorModel *model)
|
||||||
{
|
{
|
||||||
auto *bar = new QToolBar;
|
auto *bar = new QToolBar;
|
||||||
|
@@ -49,6 +49,13 @@ public:
|
|||||||
|
|
||||||
void clearCanvas();
|
void clearCanvas();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void viewEnabledChanged(const bool);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void showEvent(QShowEvent *event) override;
|
||||||
|
void hideEvent(QHideEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QToolBar *createToolBar(CurveEditorModel *model);
|
QToolBar *createToolBar(CurveEditorModel *model);
|
||||||
|
|
||||||
|
@@ -51,6 +51,13 @@ CurveEditorView::CurveEditorView(QObject *parent)
|
|||||||
connect(m_model, &CurveEditorModel::commitStartFrame, this, &CurveEditorView::commitStartFrame);
|
connect(m_model, &CurveEditorModel::commitStartFrame, this, &CurveEditorView::commitStartFrame);
|
||||||
connect(m_model, &CurveEditorModel::commitEndFrame, this, &CurveEditorView::commitEndFrame);
|
connect(m_model, &CurveEditorModel::commitEndFrame, this, &CurveEditorView::commitEndFrame);
|
||||||
connect(m_model, &CurveEditorModel::curveChanged, this, &CurveEditorView::commitKeyframes);
|
connect(m_model, &CurveEditorModel::curveChanged, this, &CurveEditorView::commitKeyframes);
|
||||||
|
|
||||||
|
connect(m_editor, &CurveEditor::viewEnabledChanged, this, [this](bool enabled){
|
||||||
|
setEnabled(enabled);
|
||||||
|
if (enabled)
|
||||||
|
init();
|
||||||
|
});
|
||||||
|
setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
CurveEditorView::~CurveEditorView() {}
|
CurveEditorView::~CurveEditorView() {}
|
||||||
@@ -70,10 +77,8 @@ void CurveEditorView::modelAttached(Model *model)
|
|||||||
{
|
{
|
||||||
AbstractView::modelAttached(model);
|
AbstractView::modelAttached(model);
|
||||||
|
|
||||||
QmlTimeline timeline = activeTimeline();
|
if (isEnabled())
|
||||||
if (timeline.isValid()) {
|
init();
|
||||||
m_model->setTimeline(timeline);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CurveEditorView::modelAboutToBeDetached(Model *model)
|
void CurveEditorView::modelAboutToBeDetached(Model *model)
|
||||||
@@ -389,4 +394,13 @@ void CurveEditorView::commitEndFrame(int frame)
|
|||||||
timeline.modelNode().variantProperty("endFrame").setValue(frame);
|
timeline.modelNode().variantProperty("endFrame").setValue(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CurveEditorView::init()
|
||||||
|
{
|
||||||
|
QmlTimeline timeline = activeTimeline();
|
||||||
|
if (timeline.isValid()) {
|
||||||
|
m_model->setTimeline(timeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -85,6 +85,7 @@ private:
|
|||||||
void commitCurrentFrame(int frame);
|
void commitCurrentFrame(int frame);
|
||||||
void commitStartFrame(int frame);
|
void commitStartFrame(int frame);
|
||||||
void commitEndFrame(int frame);
|
void commitEndFrame(int frame);
|
||||||
|
void init();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_block;
|
bool m_block;
|
||||||
|
@@ -40,6 +40,7 @@
|
|||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
|
|
||||||
#include <QActionGroup>
|
#include <QActionGroup>
|
||||||
|
#include <QMimeData>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
@@ -47,6 +48,8 @@ namespace QmlDesigner {
|
|||||||
Edit3DWidget::Edit3DWidget(Edit3DView *view) :
|
Edit3DWidget::Edit3DWidget(Edit3DView *view) :
|
||||||
m_view(view)
|
m_view(view)
|
||||||
{
|
{
|
||||||
|
setAcceptDrops(true);
|
||||||
|
|
||||||
Core::Context context(Constants::C_QMLEDITOR3D);
|
Core::Context context(Constants::C_QMLEDITOR3D);
|
||||||
m_context = new Core::IContext(this);
|
m_context = new Core::IContext(this);
|
||||||
m_context->setContext(context);
|
m_context->setContext(context);
|
||||||
@@ -159,4 +162,19 @@ Edit3DView *Edit3DWidget::view() const
|
|||||||
return m_view.data();
|
return m_view.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Edit3DWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
|
||||||
|
{
|
||||||
|
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
||||||
|
->viewManager().designerActionManager();
|
||||||
|
if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData()))
|
||||||
|
dragEnterEvent->acceptProposedAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Edit3DWidget::dropEvent(QDropEvent *dropEvent)
|
||||||
|
{
|
||||||
|
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
||||||
|
->viewManager().designerActionManager();
|
||||||
|
actionManager.handleExternalAssetsDrop(dropEvent->mimeData());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
||||||
|
@@ -48,6 +48,10 @@ public:
|
|||||||
|
|
||||||
void showCanvas(bool show);
|
void showCanvas(bool show);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void dragEnterEvent(QDragEnterEvent *dragEnterEvent) override;
|
||||||
|
void dropEvent(QDropEvent *dropEvent) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void linkActivated(const QString &link);
|
void linkActivated(const QString &link);
|
||||||
|
|
||||||
|
@@ -53,6 +53,7 @@
|
|||||||
|
|
||||||
#include <QActionGroup>
|
#include <QActionGroup>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
#include <QMimeData>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPicture>
|
#include <QPicture>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
@@ -63,6 +64,8 @@ namespace QmlDesigner {
|
|||||||
FormEditorWidget::FormEditorWidget(FormEditorView *view)
|
FormEditorWidget::FormEditorWidget(FormEditorView *view)
|
||||||
: m_formEditorView(view)
|
: m_formEditorView(view)
|
||||||
{
|
{
|
||||||
|
setAcceptDrops(true);
|
||||||
|
|
||||||
Core::Context context(Constants::C_QMLFORMEDITOR);
|
Core::Context context(Constants::C_QMLFORMEDITOR);
|
||||||
m_context = new Core::IContext(this);
|
m_context = new Core::IContext(this);
|
||||||
m_context->setContext(context);
|
m_context->setContext(context);
|
||||||
@@ -582,4 +585,19 @@ void FormEditorWidget::showEvent(QShowEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FormEditorWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
|
||||||
|
{
|
||||||
|
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
||||||
|
->viewManager().designerActionManager();
|
||||||
|
if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData()))
|
||||||
|
dragEnterEvent->acceptProposedAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FormEditorWidget::dropEvent(QDropEvent *dropEvent)
|
||||||
|
{
|
||||||
|
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
||||||
|
->viewManager().designerActionManager();
|
||||||
|
actionManager.handleExternalAssetsDrop(dropEvent->mimeData());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -49,6 +49,7 @@ class QmlItemNode;
|
|||||||
class FormEditorWidget : public QWidget
|
class FormEditorWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FormEditorWidget(FormEditorView *view);
|
FormEditorWidget(FormEditorView *view);
|
||||||
|
|
||||||
@@ -93,6 +94,8 @@ protected:
|
|||||||
DocumentWarningWidget *errorWidget();
|
DocumentWarningWidget *errorWidget();
|
||||||
void hideEvent(QHideEvent *event) override;
|
void hideEvent(QHideEvent *event) override;
|
||||||
void showEvent(QShowEvent *event) override;
|
void showEvent(QShowEvent *event) override;
|
||||||
|
void dragEnterEvent(QDragEnterEvent *dragEnterEvent) override;
|
||||||
|
void dropEvent(QDropEvent *dropEvent) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void changeTransformTool(bool checked);
|
void changeTransformTool(bool checked);
|
||||||
|
@@ -144,6 +144,17 @@ void ItemLibraryCategoriesModel::resetModel()
|
|||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ItemLibraryCategoriesModel::isAllCategoriesHidden() const
|
||||||
|
{
|
||||||
|
for (const auto &category : std::as_const(m_categoryList)) {
|
||||||
|
// ignore "All Other Components" as its categoryVisible is always true
|
||||||
|
if (category->isCategoryVisible() && category->categoryName() != "All Other Components")
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void ItemLibraryCategoriesModel::showAllCategories(bool show)
|
void ItemLibraryCategoriesModel::showAllCategories(bool show)
|
||||||
{
|
{
|
||||||
for (const auto &category : std::as_const(m_categoryList)) {
|
for (const auto &category : std::as_const(m_categoryList)) {
|
||||||
@@ -153,9 +164,43 @@ void ItemLibraryCategoriesModel::showAllCategories(bool show)
|
|||||||
category->ownerImport()->importName());
|
category->ownerImport()->importName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit dataChanged(index(0), index(m_categoryList.size() - 1), {m_roleNames.key("categoryVisible")});
|
emit dataChanged(index(0), index(m_categoryList.size() - 1), {m_roleNames.key("categoryVisible")});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QObject *ItemLibraryCategoriesModel::selectFirstVisibleCategory()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_categoryList.length(); ++i) {
|
||||||
|
const auto category = m_categoryList.at(i);
|
||||||
|
|
||||||
|
if (category->isCategoryVisible()) {
|
||||||
|
category->setCategorySelected(true);
|
||||||
|
emit dataChanged(index(i),index(i), {m_roleNames.key("categorySelected")});
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemLibraryCategoriesModel::clearSelectedCategories()
|
||||||
|
{
|
||||||
|
for (const auto &category : std::as_const(m_categoryList))
|
||||||
|
category->setCategorySelected(false);
|
||||||
|
|
||||||
|
emit dataChanged(index(0), index(m_categoryList.size() - 1), {m_roleNames.key("categorySelected")});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemLibraryCategoriesModel::selectCategory(int categoryIndex)
|
||||||
|
{
|
||||||
|
const auto category = m_categoryList.at(categoryIndex);
|
||||||
|
if (!category->categorySelected()) {
|
||||||
|
clearSelectedCategories();
|
||||||
|
category->setCategorySelected(true);
|
||||||
|
emit dataChanged(index(categoryIndex),index(categoryIndex), {m_roleNames.key("categorySelected")});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ItemLibraryCategoriesModel::addRoleNames()
|
void ItemLibraryCategoriesModel::addRoleNames()
|
||||||
{
|
{
|
||||||
int role = 0;
|
int role = 0;
|
||||||
|
@@ -52,9 +52,13 @@ public:
|
|||||||
|
|
||||||
const QList<QPointer<ItemLibraryCategory>> &categorySections() const;
|
const QList<QPointer<ItemLibraryCategory>> &categorySections() const;
|
||||||
|
|
||||||
|
bool isAllCategoriesHidden() const;
|
||||||
void sortCategorySections();
|
void sortCategorySections();
|
||||||
void resetModel();
|
void resetModel();
|
||||||
void showAllCategories(bool show = true);
|
void showAllCategories(bool show = true);
|
||||||
|
void clearSelectedCategories();
|
||||||
|
QObject *selectFirstVisibleCategory();
|
||||||
|
void selectCategory(int categoryIndex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addRoleNames();
|
void addRoleNames();
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#include "itemlibrarycategory.h"
|
#include "itemlibrarycategory.h"
|
||||||
|
|
||||||
#include "itemlibraryitem.h"
|
#include "itemlibraryitem.h"
|
||||||
|
#include "itemlibrarywidget.h"
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
@@ -46,6 +47,11 @@ bool ItemLibraryCategory::categoryExpanded() const
|
|||||||
return m_categoryExpanded;
|
return m_categoryExpanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ItemLibraryCategory::categorySelected() const
|
||||||
|
{
|
||||||
|
return m_categorySelected;
|
||||||
|
}
|
||||||
|
|
||||||
QString ItemLibraryCategory::sortingName() const
|
QString ItemLibraryCategory::sortingName() const
|
||||||
{
|
{
|
||||||
if (ItemLibraryModel::categorySortingHash.contains(categoryName()))
|
if (ItemLibraryModel::categorySortingHash.contains(categoryName()))
|
||||||
@@ -84,6 +90,10 @@ bool ItemLibraryCategory::updateItemVisibility(const QString &searchText, bool *
|
|||||||
hasVisibleItems = true;
|
hasVisibleItems = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update item model in horizontal view so search text matches item grid
|
||||||
|
if (ItemLibraryWidget::isHorizontalLayout)
|
||||||
|
m_itemModel.resetModel();
|
||||||
|
|
||||||
// expand category if it has an item matching search criteria
|
// expand category if it has an item matching search criteria
|
||||||
if (!searchText.isEmpty() && hasVisibleItems && !categoryExpanded())
|
if (!searchText.isEmpty() && hasVisibleItems && !categoryExpanded())
|
||||||
setExpanded(true);
|
setExpanded(true);
|
||||||
@@ -124,4 +134,9 @@ void ItemLibraryCategory::setExpanded(bool expanded)
|
|||||||
m_categoryExpanded = expanded;
|
m_categoryExpanded = expanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemLibraryCategory::setCategorySelected(bool selected)
|
||||||
|
{
|
||||||
|
m_categorySelected = selected;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -39,6 +39,7 @@ class ItemLibraryCategory : public QObject
|
|||||||
Q_PROPERTY(QString categoryName READ categoryName FINAL)
|
Q_PROPERTY(QString categoryName READ categoryName FINAL)
|
||||||
Q_PROPERTY(bool categoryVisible READ isCategoryVisible WRITE setCategoryVisible NOTIFY categoryVisibilityChanged FINAL)
|
Q_PROPERTY(bool categoryVisible READ isCategoryVisible WRITE setCategoryVisible NOTIFY categoryVisibilityChanged FINAL)
|
||||||
Q_PROPERTY(bool categoryExpanded READ categoryExpanded WRITE setExpanded NOTIFY expandedChanged FINAL)
|
Q_PROPERTY(bool categoryExpanded READ categoryExpanded WRITE setExpanded NOTIFY expandedChanged FINAL)
|
||||||
|
Q_PROPERTY(bool categorySelected READ categorySelected WRITE setCategorySelected NOTIFY categorySelectedChanged FINAL)
|
||||||
Q_PROPERTY(QObject *itemModel READ itemModel NOTIFY itemModelChanged FINAL)
|
Q_PROPERTY(QObject *itemModel READ itemModel NOTIFY itemModelChanged FINAL)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -46,6 +47,7 @@ public:
|
|||||||
|
|
||||||
QString categoryName() const;
|
QString categoryName() const;
|
||||||
bool categoryExpanded() const;
|
bool categoryExpanded() const;
|
||||||
|
bool categorySelected() const;
|
||||||
QString sortingName() const;
|
QString sortingName() const;
|
||||||
|
|
||||||
void addItem(ItemLibraryItem *item);
|
void addItem(ItemLibraryItem *item);
|
||||||
@@ -60,6 +62,7 @@ public:
|
|||||||
void sortItems();
|
void sortItems();
|
||||||
|
|
||||||
void setExpanded(bool expanded);
|
void setExpanded(bool expanded);
|
||||||
|
void setCategorySelected(bool selected);
|
||||||
|
|
||||||
ItemLibraryImport *ownerImport() const { return m_ownerImport; }
|
ItemLibraryImport *ownerImport() const { return m_ownerImport; }
|
||||||
|
|
||||||
@@ -68,6 +71,7 @@ signals:
|
|||||||
void visibilityChanged();
|
void visibilityChanged();
|
||||||
void expandedChanged();
|
void expandedChanged();
|
||||||
void categoryVisibilityChanged();
|
void categoryVisibilityChanged();
|
||||||
|
void categorySelectedChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ItemLibraryItemsModel m_itemModel;
|
ItemLibraryItemsModel m_itemModel;
|
||||||
@@ -75,6 +79,7 @@ private:
|
|||||||
QString m_name;
|
QString m_name;
|
||||||
bool m_categoryExpanded = true;
|
bool m_categoryExpanded = true;
|
||||||
bool m_isVisible = true;
|
bool m_isVisible = true;
|
||||||
|
bool m_categorySelected = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -138,6 +138,26 @@ void ItemLibraryImport::showAllCategories(bool show)
|
|||||||
m_categoryModel.showAllCategories(show);
|
m_categoryModel.showAllCategories(show);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemLibraryImport::selectCategory(int categoryIndex)
|
||||||
|
{
|
||||||
|
m_categoryModel.selectCategory(categoryIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject *ItemLibraryImport::selectFirstVisibleCategory()
|
||||||
|
{
|
||||||
|
return m_categoryModel.selectFirstVisibleCategory();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemLibraryImport::clearSelectedCategories()
|
||||||
|
{
|
||||||
|
m_categoryModel.clearSelectedCategories();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ItemLibraryImport::isAllCategoriesHidden() const
|
||||||
|
{
|
||||||
|
return m_categoryModel.isAllCategoriesHidden();
|
||||||
|
}
|
||||||
|
|
||||||
Import ItemLibraryImport::importEntry() const
|
Import ItemLibraryImport::importEntry() const
|
||||||
{
|
{
|
||||||
return m_import;
|
return m_import;
|
||||||
|
@@ -68,6 +68,7 @@ public:
|
|||||||
bool importCatVisibleState() const;
|
bool importCatVisibleState() const;
|
||||||
bool hasCategories() const;
|
bool hasCategories() const;
|
||||||
bool hasSingleCategory() const;
|
bool hasSingleCategory() const;
|
||||||
|
bool isAllCategoriesHidden() const;
|
||||||
ItemLibraryCategory *getCategorySection(const QString &categoryName) const;
|
ItemLibraryCategory *getCategorySection(const QString &categoryName) const;
|
||||||
|
|
||||||
void addCategory(ItemLibraryCategory *category);
|
void addCategory(ItemLibraryCategory *category);
|
||||||
@@ -80,6 +81,9 @@ public:
|
|||||||
void setImportCatVisibleState(bool show);
|
void setImportCatVisibleState(bool show);
|
||||||
void expandCategories(bool expand = true);
|
void expandCategories(bool expand = true);
|
||||||
void showAllCategories(bool show = true);
|
void showAllCategories(bool show = true);
|
||||||
|
void selectCategory(int categoryIndex);
|
||||||
|
QObject *selectFirstVisibleCategory();
|
||||||
|
void clearSelectedCategories();
|
||||||
|
|
||||||
static QString userComponentsTitle();
|
static QString userComponentsTitle();
|
||||||
static QString quick3DAssetsTitle();
|
static QString quick3DAssetsTitle();
|
||||||
|
@@ -90,6 +90,40 @@ bool ItemLibraryModel::getIsAnyCategoryHidden() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemLibraryModel::selectImportCategory(const QString importUrl, int categoryIndex)
|
||||||
|
{
|
||||||
|
ItemLibraryImport *selectedCategoryImport = importByUrl(importUrl);
|
||||||
|
|
||||||
|
for (int i = 0; i < m_importList.length(); ++i) {
|
||||||
|
const auto importToSelect = m_importList.at(i);
|
||||||
|
|
||||||
|
if (selectedCategoryImport == importToSelect)
|
||||||
|
importToSelect->selectCategory(categoryIndex);
|
||||||
|
else
|
||||||
|
importToSelect->clearSelectedCategories();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ItemLibraryModel::isAllCategoriesHidden() const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_importList.length(); ++i) {
|
||||||
|
if (!m_importList.at(i)->isAllCategoriesHidden())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject *ItemLibraryModel::selectImportFirstVisibleCategory()
|
||||||
|
{
|
||||||
|
for (const QPointer<ItemLibraryImport> &import : std::as_const(m_importList)) {
|
||||||
|
if (!import->isAllCategoriesHidden())
|
||||||
|
return import->selectFirstVisibleCategory();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool ItemLibraryModel::isAnyCategoryHidden() const
|
bool ItemLibraryModel::isAnyCategoryHidden() const
|
||||||
{
|
{
|
||||||
return m_isAnyCategoryHidden;
|
return m_isAnyCategoryHidden;
|
||||||
|
@@ -77,6 +77,9 @@ public:
|
|||||||
Q_INVOKABLE void collapseAll();
|
Q_INVOKABLE void collapseAll();
|
||||||
Q_INVOKABLE void showHiddenCategories();
|
Q_INVOKABLE void showHiddenCategories();
|
||||||
Q_INVOKABLE bool getIsAnyCategoryHidden() const;
|
Q_INVOKABLE bool getIsAnyCategoryHidden() const;
|
||||||
|
Q_INVOKABLE void selectImportCategory(const QString importUrl, int categoryIndex);
|
||||||
|
Q_INVOKABLE QObject *selectImportFirstVisibleCategory();
|
||||||
|
Q_INVOKABLE bool isAllCategoriesHidden() const;
|
||||||
|
|
||||||
Import entryToImport(const ItemLibraryEntry &entry);
|
Import entryToImport(const ItemLibraryEntry &entry);
|
||||||
|
|
||||||
|
@@ -143,6 +143,11 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event)
|
|||||||
return QObject::eventFilter(obj, event);
|
return QObject::eventFilter(obj, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemLibraryWidget::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
isHorizontalLayout = event->size().width() >= HORIZONTAL_LAYOUT_WIDTH_LIMIT;
|
||||||
|
}
|
||||||
|
|
||||||
ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache,
|
ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache,
|
||||||
AsynchronousImageCache &asynchronousFontImageCache,
|
AsynchronousImageCache &asynchronousFontImageCache,
|
||||||
SynchronousImageCache &synchronousFontImageCache)
|
SynchronousImageCache &synchronousFontImageCache)
|
||||||
@@ -196,6 +201,7 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache,
|
|||||||
{{"itemLibraryIconWidth"}, m_itemIconSize.width()},
|
{{"itemLibraryIconWidth"}, m_itemIconSize.width()},
|
||||||
{{"itemLibraryIconHeight"}, m_itemIconSize.height()},
|
{{"itemLibraryIconHeight"}, m_itemIconSize.height()},
|
||||||
{{"rootView"}, QVariant::fromValue(this)},
|
{{"rootView"}, QVariant::fromValue(this)},
|
||||||
|
{{"widthLimit"}, HORIZONTAL_LAYOUT_WIDTH_LIMIT},
|
||||||
{{"highlightColor"}, Utils::StyleHelper::notTooBrightHighlightColor()},
|
{{"highlightColor"}, Utils::StyleHelper::notTooBrightHighlightColor()},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -92,6 +92,8 @@ public:
|
|||||||
void setFlowMode(bool b);
|
void setFlowMode(bool b);
|
||||||
static QPair<QString, QByteArray> getAssetTypeAndData(const QString &assetPath);
|
static QPair<QString, QByteArray> getAssetTypeAndData(const QString &assetPath);
|
||||||
|
|
||||||
|
inline static bool isHorizontalLayout = false;
|
||||||
|
|
||||||
Q_INVOKABLE void startDragAndDrop(const QVariant &itemLibEntry, const QPointF &mousePos);
|
Q_INVOKABLE void startDragAndDrop(const QVariant &itemLibEntry, const QPointF &mousePos);
|
||||||
Q_INVOKABLE void startDragAsset(const QStringList &assetPaths, const QPointF &mousePos);
|
Q_INVOKABLE void startDragAsset(const QStringList &assetPaths, const QPointF &mousePos);
|
||||||
Q_INVOKABLE void removeImport(const QString &importUrl);
|
Q_INVOKABLE void removeImport(const QString &importUrl);
|
||||||
@@ -110,6 +112,7 @@ signals:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void reloadQmlSource();
|
void reloadQmlSource();
|
||||||
@@ -149,6 +152,8 @@ private:
|
|||||||
bool m_updateRetry = false;
|
bool m_updateRetry = false;
|
||||||
QString m_filterText;
|
QString m_filterText;
|
||||||
QPoint m_dragStartPoint;
|
QPoint m_dragStartPoint;
|
||||||
|
|
||||||
|
inline static int HORIZONTAL_LAYOUT_WIDTH_LIMIT = 600;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -49,6 +49,8 @@ NavigatorWidget::NavigatorWidget(NavigatorView *view)
|
|||||||
: m_treeView(new NavigatorTreeView)
|
: m_treeView(new NavigatorTreeView)
|
||||||
, m_navigatorView(view)
|
, m_navigatorView(view)
|
||||||
{
|
{
|
||||||
|
setAcceptDrops(true);
|
||||||
|
|
||||||
m_treeView->setDragEnabled(true);
|
m_treeView->setDragEnabled(true);
|
||||||
m_treeView->setAcceptDrops(true);
|
m_treeView->setAcceptDrops(true);
|
||||||
m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
@@ -184,4 +186,19 @@ NavigatorView *NavigatorWidget::navigatorView() const
|
|||||||
return m_navigatorView.data();
|
return m_navigatorView.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavigatorWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
|
||||||
|
{
|
||||||
|
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
||||||
|
->viewManager().designerActionManager();
|
||||||
|
if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData()))
|
||||||
|
dragEnterEvent->acceptProposedAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigatorWidget::dropEvent(QDropEvent *dropEvent)
|
||||||
|
{
|
||||||
|
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
||||||
|
->viewManager().designerActionManager();
|
||||||
|
actionManager.handleExternalAssetsDrop(dropEvent->mimeData());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -43,6 +43,7 @@ class NavigatorView;
|
|||||||
class NavigatorWidget: public QFrame
|
class NavigatorWidget: public QFrame
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NavigatorWidget(NavigatorView *view);
|
NavigatorWidget(NavigatorView *view);
|
||||||
|
|
||||||
@@ -63,10 +64,13 @@ signals:
|
|||||||
void filterToggled(bool);
|
void filterToggled(bool);
|
||||||
void reverseOrderToggled(bool);
|
void reverseOrderToggled(bool);
|
||||||
|
|
||||||
private: // functions
|
protected:
|
||||||
|
void dragEnterEvent(QDragEnterEvent *dragEnterEvent) override;
|
||||||
|
void dropEvent(QDropEvent *dropEvent) override;
|
||||||
|
|
||||||
|
private:
|
||||||
NavigatorView *navigatorView() const;
|
NavigatorView *navigatorView() const;
|
||||||
|
|
||||||
private: // variables
|
|
||||||
NavigatorTreeView *m_treeView;
|
NavigatorTreeView *m_treeView;
|
||||||
QPointer<NavigatorView> m_navigatorView;
|
QPointer<NavigatorView> m_navigatorView;
|
||||||
};
|
};
|
||||||
|
@@ -53,6 +53,8 @@ TextEditorWidget::TextEditorWidget(TextEditorView *textEditorView)
|
|||||||
, m_textEditorView(textEditorView)
|
, m_textEditorView(textEditorView)
|
||||||
, m_statusBar(new TextEditorStatusBar(this))
|
, m_statusBar(new TextEditorStatusBar(this))
|
||||||
{
|
{
|
||||||
|
setAcceptDrops(true);
|
||||||
|
|
||||||
QBoxLayout *layout = new QVBoxLayout(this);
|
QBoxLayout *layout = new QVBoxLayout(this);
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
layout->setSpacing(0);
|
layout->setSpacing(0);
|
||||||
@@ -216,5 +218,19 @@ bool TextEditorWidget::eventFilter( QObject *, QEvent *event)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextEditorWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent)
|
||||||
|
{
|
||||||
|
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
||||||
|
->viewManager().designerActionManager();
|
||||||
|
if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData()))
|
||||||
|
dragEnterEvent->acceptProposedAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEditorWidget::dropEvent(QDropEvent *dropEvent)
|
||||||
|
{
|
||||||
|
const DesignerActionManager &actionManager = QmlDesignerPlugin::instance()
|
||||||
|
->viewManager().designerActionManager();
|
||||||
|
actionManager.handleExternalAssetsDrop(dropEvent->mimeData());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -63,6 +63,8 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *object, QEvent *event) override;
|
bool eventFilter(QObject *object, QEvent *event) override;
|
||||||
|
void dragEnterEvent(QDragEnterEvent *dragEnterEvent) override;
|
||||||
|
void dropEvent(QDropEvent *dropEvent) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateSelectionByCursorPosition();
|
void updateSelectionByCursorPosition();
|
||||||
|
@@ -71,6 +71,7 @@ TimelineView::TimelineView(QObject *parent)
|
|||||||
, m_timelineWidget(nullptr)
|
, m_timelineWidget(nullptr)
|
||||||
{
|
{
|
||||||
EasingCurve::registerStreamOperators();
|
EasingCurve::registerStreamOperators();
|
||||||
|
setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
TimelineView::~TimelineView() = default;
|
TimelineView::~TimelineView() = default;
|
||||||
|
@@ -606,13 +606,7 @@ void TimelineWidget::showEvent(QShowEvent *event)
|
|||||||
{
|
{
|
||||||
Q_UNUSED(event)
|
Q_UNUSED(event)
|
||||||
|
|
||||||
/*
|
|
||||||
m_timelineView->setEnabled(true);
|
m_timelineView->setEnabled(true);
|
||||||
TODO See QDS-4191
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (m_timelineView->model())
|
|
||||||
init();
|
|
||||||
|
|
||||||
graphicsScene()->setWidth(m_graphicsView->viewport()->width());
|
graphicsScene()->setWidth(m_graphicsView->viewport()->width());
|
||||||
graphicsScene()->invalidateLayout();
|
graphicsScene()->invalidateLayout();
|
||||||
@@ -620,6 +614,10 @@ void TimelineWidget::showEvent(QShowEvent *event)
|
|||||||
graphicsScene()->onShow();
|
graphicsScene()->onShow();
|
||||||
|
|
||||||
QWidget::showEvent(event);
|
QWidget::showEvent(event);
|
||||||
|
|
||||||
|
//All the events have to be fully processed before we call init()
|
||||||
|
if (m_timelineView->model())
|
||||||
|
QTimer::singleShot(0, [this]() { init(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineWidget::resizeEvent(QResizeEvent *event)
|
void TimelineWidget::resizeEvent(QResizeEvent *event)
|
||||||
@@ -630,7 +628,7 @@ void TimelineWidget::resizeEvent(QResizeEvent *event)
|
|||||||
|
|
||||||
void TimelineWidget::hideEvent(QHideEvent *event)
|
void TimelineWidget::hideEvent(QHideEvent *event)
|
||||||
{
|
{
|
||||||
/* m_timelineView->setEnabled(false); TODO See QDS-4191 */
|
m_timelineView->setEnabled(false);
|
||||||
QWidget::hideEvent(event);
|
QWidget::hideEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,30 +33,28 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Qnx {
|
namespace Qnx {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
QnxBaseQtConfigWidget::QnxBaseQtConfigWidget(QnxQtVersion *version) :
|
QnxBaseQtConfigWidget::QnxBaseQtConfigWidget(QnxQtVersion *version) :
|
||||||
m_version(version),
|
m_version(version),
|
||||||
m_sdpPathChooser(new Utils::PathChooser)
|
m_sdpPathChooser(new PathChooser)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(version, return);
|
QTC_ASSERT(version, return);
|
||||||
|
|
||||||
auto layout = new QHBoxLayout(this);
|
auto layout = new QHBoxLayout(this);
|
||||||
layout->addWidget(m_sdpPathChooser);
|
layout->addWidget(m_sdpPathChooser);
|
||||||
|
|
||||||
m_sdpPathChooser->setExpectedKind(Utils::PathChooser::ExistingDirectory);
|
m_sdpPathChooser->setExpectedKind(PathChooser::ExistingDirectory);
|
||||||
m_sdpPathChooser->setHistoryCompleter(QLatin1String("Qnx.Sdp.History"));
|
m_sdpPathChooser->setHistoryCompleter("Qnx.Sdp.History");
|
||||||
m_sdpPathChooser->setPath(version->sdpPath());
|
m_sdpPathChooser->setFilePath(version->sdpPath());
|
||||||
|
|
||||||
connect(m_sdpPathChooser, &Utils::PathChooser::rawPathChanged,
|
connect(m_sdpPathChooser, &PathChooser::rawPathChanged, [this] {
|
||||||
this, &QnxBaseQtConfigWidget::updateSdpPath);
|
m_version->setSdpPath(m_sdpPathChooser->filePath());
|
||||||
}
|
|
||||||
|
|
||||||
void QnxBaseQtConfigWidget::updateSdpPath(const QString &path)
|
|
||||||
{
|
|
||||||
m_version->setSdpPath(path);
|
|
||||||
emit changed();
|
emit changed();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -27,7 +27,10 @@
|
|||||||
|
|
||||||
#include <qtsupport/qtconfigwidget.h>
|
#include <qtsupport/qtconfigwidget.h>
|
||||||
|
|
||||||
namespace Utils { class PathChooser; }
|
namespace Utils {
|
||||||
|
class PathChooser;
|
||||||
|
class FilePath;
|
||||||
|
} // Utils
|
||||||
|
|
||||||
namespace Qnx {
|
namespace Qnx {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -41,9 +44,6 @@ class QnxBaseQtConfigWidget : public QtSupport::QtConfigWidget
|
|||||||
public:
|
public:
|
||||||
explicit QnxBaseQtConfigWidget(QnxQtVersion *version);
|
explicit QnxBaseQtConfigWidget(QnxQtVersion *version);
|
||||||
|
|
||||||
private slots:
|
|
||||||
void updateSdpPath(const QString &path);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QnxQtVersion *m_version;
|
QnxQtVersion *m_version;
|
||||||
Utils::PathChooser *m_sdpPathChooser;
|
Utils::PathChooser *m_sdpPathChooser;
|
||||||
|
@@ -225,7 +225,7 @@ QnxQtVersion *QnxConfiguration::qnxQtVersion(const Target &target) const
|
|||||||
QtVersionManager::instance()->versions(Utils::equal(&BaseQtVersion::type,
|
QtVersionManager::instance()->versions(Utils::equal(&BaseQtVersion::type,
|
||||||
QString::fromLatin1(Constants::QNX_QNX_QT)))) {
|
QString::fromLatin1(Constants::QNX_QNX_QT)))) {
|
||||||
auto qnxQt = dynamic_cast<QnxQtVersion *>(version);
|
auto qnxQt = dynamic_cast<QnxQtVersion *>(version);
|
||||||
if (qnxQt && FilePath::fromString(qnxQt->sdpPath()) == sdpPath()) {
|
if (qnxQt && qnxQt->sdpPath() == sdpPath()) {
|
||||||
foreach (const Abi &qtAbi, version->qtAbis()) {
|
foreach (const Abi &qtAbi, version->qtAbis()) {
|
||||||
if ((qtAbi == target.m_abi) && (qnxQt->cpuDir() == target.cpuDir()))
|
if ((qtAbi == target.m_abi) && (qnxQt->cpuDir() == target.cpuDir()))
|
||||||
return qnxQt;
|
return qnxQt;
|
||||||
@@ -240,7 +240,7 @@ QList<ToolChain *> QnxConfiguration::autoDetect(const QList<ToolChain *> &alread
|
|||||||
{
|
{
|
||||||
QList<ToolChain *> result;
|
QList<ToolChain *> result;
|
||||||
|
|
||||||
foreach (const Target &target, m_targets)
|
for (const Target &target : qAsConst(m_targets))
|
||||||
result += findToolChain(alreadyKnown, target.m_abi);
|
result += findToolChain(alreadyKnown, target.m_abi);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -286,7 +286,7 @@ QnxConfiguration::QnxToolChainMap QnxConfiguration::createToolChain(const Target
|
|||||||
"QCC for %1 (%2)")
|
"QCC for %1 (%2)")
|
||||||
.arg(displayName())
|
.arg(displayName())
|
||||||
.arg(target.shortDescription()));
|
.arg(target.shortDescription()));
|
||||||
toolChain->setSdpPath(sdpPath().toString());
|
toolChain->setSdpPath(sdpPath());
|
||||||
toolChain->setCpuDir(target.cpuDir());
|
toolChain->setCpuDir(target.cpuDir());
|
||||||
toolChain->resetToolChain(qccCompilerPath());
|
toolChain->resetToolChain(qccCompilerPath());
|
||||||
ToolChainManager::registerToolChain(toolChain);
|
ToolChainManager::registerToolChain(toolChain);
|
||||||
@@ -372,11 +372,11 @@ void QnxConfiguration::setVersion(const QnxVersionNumber &version)
|
|||||||
void QnxConfiguration::readInformation()
|
void QnxConfiguration::readInformation()
|
||||||
{
|
{
|
||||||
const QString qConfigPath = m_qnxConfiguration.pathAppended("qconfig").toString();
|
const QString qConfigPath = m_qnxConfiguration.pathAppended("qconfig").toString();
|
||||||
QList <ConfigInstallInformation> installInfoList = QnxUtils::installedConfigs(qConfigPath);
|
const QList <ConfigInstallInformation> installInfoList = QnxUtils::installedConfigs(qConfigPath);
|
||||||
if (installInfoList.isEmpty())
|
if (installInfoList.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (const ConfigInstallInformation &info, installInfoList) {
|
for (const ConfigInstallInformation &info : installInfoList) {
|
||||||
if (m_qnxHost == FilePath::fromString(info.host).canonicalPath()
|
if (m_qnxHost == FilePath::fromString(info.host).canonicalPath()
|
||||||
&& m_qnxTarget == FilePath::fromString(info.target).canonicalPath()) {
|
&& m_qnxTarget == FilePath::fromString(info.target).canonicalPath()) {
|
||||||
m_configName = info.name;
|
m_configName = info.name;
|
||||||
@@ -386,11 +386,11 @@ void QnxConfiguration::readInformation()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QnxConfiguration::setDefaultConfiguration(const Utils::FilePath &envScript)
|
void QnxConfiguration::setDefaultConfiguration(const FilePath &envScript)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!envScript.isEmpty(), return);
|
QTC_ASSERT(!envScript.isEmpty(), return);
|
||||||
m_envFile = envScript;
|
m_envFile = envScript;
|
||||||
m_qnxEnv = QnxUtils::qnxEnvironmentFromEnvFile(m_envFile.toString());
|
m_qnxEnv = QnxUtils::qnxEnvironmentFromEnvFile(m_envFile);
|
||||||
foreach (const EnvironmentItem &item, m_qnxEnv) {
|
foreach (const EnvironmentItem &item, m_qnxEnv) {
|
||||||
if (item.name == QNXConfiguration)
|
if (item.name == QNXConfiguration)
|
||||||
m_qnxConfiguration = FilePath::fromString(item.value).canonicalPath();
|
m_qnxConfiguration = FilePath::fromString(item.value).canonicalPath();
|
||||||
|
@@ -109,14 +109,14 @@ QString QnxQtVersion::cpuDir() const
|
|||||||
QVariantMap QnxQtVersion::toMap() const
|
QVariantMap QnxQtVersion::toMap() const
|
||||||
{
|
{
|
||||||
QVariantMap result = BaseQtVersion::toMap();
|
QVariantMap result = BaseQtVersion::toMap();
|
||||||
result.insert(QLatin1String(SDP_PATH_KEY), sdpPath());
|
result.insert(SDP_PATH_KEY, sdpPath().toVariant());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QnxQtVersion::fromMap(const QVariantMap &map)
|
void QnxQtVersion::fromMap(const QVariantMap &map)
|
||||||
{
|
{
|
||||||
BaseQtVersion::fromMap(map);
|
BaseQtVersion::fromMap(map);
|
||||||
setSdpPath(QDir::fromNativeSeparators(map.value(QLatin1String(SDP_PATH_KEY)).toString()));
|
setSdpPath(FilePath::fromVariant(map.value(SDP_PATH_KEY)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Abis QnxQtVersion::detectQtAbis() const
|
Abis QnxQtVersion::detectQtAbis() const
|
||||||
@@ -134,7 +134,7 @@ void QnxQtVersion::addToEnvironment(const Kit *k, Environment &env) const
|
|||||||
env.prependOrSetLibrarySearchPath(libraryPath().toString());
|
env.prependOrSetLibrarySearchPath(libraryPath().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QnxQtVersion::setupQmakeRunEnvironment(Utils::Environment &env) const
|
void QnxQtVersion::setupQmakeRunEnvironment(Environment &env) const
|
||||||
{
|
{
|
||||||
if (!sdpPath().isEmpty())
|
if (!sdpPath().isEmpty())
|
||||||
updateEnvironment();
|
updateEnvironment();
|
||||||
@@ -160,12 +160,12 @@ QString QnxQtVersion::invalidReason() const
|
|||||||
return QtSupport::BaseQtVersion::invalidReason();
|
return QtSupport::BaseQtVersion::invalidReason();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QnxQtVersion::sdpPath() const
|
FilePath QnxQtVersion::sdpPath() const
|
||||||
{
|
{
|
||||||
return m_sdpPath;
|
return m_sdpPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QnxQtVersion::setSdpPath(const QString &sdpPath)
|
void QnxQtVersion::setSdpPath(const FilePath &sdpPath)
|
||||||
{
|
{
|
||||||
if (m_sdpPath == sdpPath)
|
if (m_sdpPath == sdpPath)
|
||||||
return;
|
return;
|
||||||
|
@@ -63,15 +63,15 @@ public:
|
|||||||
bool isValid() const override;
|
bool isValid() const override;
|
||||||
QString invalidReason() const override;
|
QString invalidReason() const override;
|
||||||
|
|
||||||
QString sdpPath() const;
|
Utils::FilePath sdpPath() const;
|
||||||
void setSdpPath(const QString &sdpPath);
|
void setSdpPath(const Utils::FilePath &sdpPath);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateEnvironment() const;
|
void updateEnvironment() const;
|
||||||
|
|
||||||
Utils::EnvironmentItems environment() const;
|
Utils::EnvironmentItems environment() const;
|
||||||
|
|
||||||
QString m_sdpPath;
|
Utils::FilePath m_sdpPath;
|
||||||
|
|
||||||
mutable QString m_cpuDir;
|
mutable QString m_cpuDir;
|
||||||
mutable bool m_environmentUpToDate = false;
|
mutable bool m_environmentUpToDate = false;
|
||||||
|
@@ -41,8 +41,8 @@ using namespace Utils;
|
|||||||
namespace Qnx {
|
namespace Qnx {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
static const char CompilerSdpPath[] = "Qnx.QnxToolChain.NDKPath";
|
const char CompilerSdpPath[] = "Qnx.QnxToolChain.NDKPath";
|
||||||
static const char CpuDirKey[] = "Qnx.QnxToolChain.CpuDir";
|
const char CpuDirKey[] = "Qnx.QnxToolChain.CpuDir";
|
||||||
|
|
||||||
static Abis detectTargetAbis(const FilePath &sdpPath)
|
static Abis detectTargetAbis(const FilePath &sdpPath)
|
||||||
{
|
{
|
||||||
@@ -50,8 +50,8 @@ static Abis detectTargetAbis(const FilePath &sdpPath)
|
|||||||
FilePath qnxTarget;
|
FilePath qnxTarget;
|
||||||
|
|
||||||
if (!sdpPath.fileName().isEmpty()) {
|
if (!sdpPath.fileName().isEmpty()) {
|
||||||
Utils::EnvironmentItems environment = QnxUtils::qnxEnvironment(sdpPath.toString());
|
const EnvironmentItems environment = QnxUtils::qnxEnvironment(sdpPath);
|
||||||
foreach (const Utils::EnvironmentItem &item, environment) {
|
for (const EnvironmentItem &item : environment) {
|
||||||
if (item.name == QLatin1String("QNX_TARGET"))
|
if (item.name == QLatin1String("QNX_TARGET"))
|
||||||
qnxTarget = FilePath::fromString(item.value);
|
qnxTarget = FilePath::fromString(item.value);
|
||||||
}
|
}
|
||||||
@@ -137,7 +137,7 @@ QStringList QnxToolChain::suggestedMkspecList() const
|
|||||||
QVariantMap QnxToolChain::toMap() const
|
QVariantMap QnxToolChain::toMap() const
|
||||||
{
|
{
|
||||||
QVariantMap data = GccToolChain::toMap();
|
QVariantMap data = GccToolChain::toMap();
|
||||||
data.insert(QLatin1String(CompilerSdpPath), m_sdpPath);
|
data.insert(QLatin1String(CompilerSdpPath), m_sdpPath.toVariant());
|
||||||
data.insert(QLatin1String(CpuDirKey), m_cpuDir);
|
data.insert(QLatin1String(CpuDirKey), m_cpuDir);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@@ -147,7 +147,7 @@ bool QnxToolChain::fromMap(const QVariantMap &data)
|
|||||||
if (!GccToolChain::fromMap(data))
|
if (!GccToolChain::fromMap(data))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_sdpPath = data.value(QLatin1String(CompilerSdpPath)).toString();
|
m_sdpPath = FilePath::fromVariant(data.value(CompilerSdpPath));
|
||||||
m_cpuDir = data.value(QLatin1String(CpuDirKey)).toString();
|
m_cpuDir = data.value(QLatin1String(CpuDirKey)).toString();
|
||||||
|
|
||||||
// Make the ABIs QNX specific (if they aren't already).
|
// Make the ABIs QNX specific (if they aren't already).
|
||||||
@@ -157,12 +157,12 @@ bool QnxToolChain::fromMap(const QVariantMap &data)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QnxToolChain::sdpPath() const
|
FilePath QnxToolChain::sdpPath() const
|
||||||
{
|
{
|
||||||
return m_sdpPath;
|
return m_sdpPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QnxToolChain::setSdpPath(const QString &sdpPath)
|
void QnxToolChain::setSdpPath(const FilePath &sdpPath)
|
||||||
{
|
{
|
||||||
if (m_sdpPath == sdpPath)
|
if (m_sdpPath == sdpPath)
|
||||||
return;
|
return;
|
||||||
@@ -185,7 +185,7 @@ void QnxToolChain::setCpuDir(const QString &cpuDir)
|
|||||||
|
|
||||||
GccToolChain::DetectedAbisResult QnxToolChain::detectSupportedAbis() const
|
GccToolChain::DetectedAbisResult QnxToolChain::detectSupportedAbis() const
|
||||||
{
|
{
|
||||||
return detectTargetAbis(FilePath::fromString(m_sdpPath));
|
return detectTargetAbis(m_sdpPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QnxToolChain::operator ==(const ToolChain &other) const
|
bool QnxToolChain::operator ==(const ToolChain &other) const
|
||||||
@@ -243,7 +243,7 @@ QnxToolChainConfigWidget::QnxToolChainConfigWidget(QnxToolChain *tc)
|
|||||||
|
|
||||||
m_sdpPath->setExpectedKind(PathChooser::ExistingDirectory);
|
m_sdpPath->setExpectedKind(PathChooser::ExistingDirectory);
|
||||||
m_sdpPath->setHistoryCompleter(QLatin1String("Qnx.Sdp.History"));
|
m_sdpPath->setHistoryCompleter(QLatin1String("Qnx.Sdp.History"));
|
||||||
m_sdpPath->setPath(tc->sdpPath());
|
m_sdpPath->setFilePath(tc->sdpPath());
|
||||||
m_sdpPath->setEnabled(!tc->isAutoDetected());
|
m_sdpPath->setEnabled(!tc->isAutoDetected());
|
||||||
|
|
||||||
const Abis abiList = detectTargetAbis(m_sdpPath->filePath());
|
const Abis abiList = detectTargetAbis(m_sdpPath->filePath());
|
||||||
@@ -270,7 +270,7 @@ void QnxToolChainConfigWidget::applyImpl()
|
|||||||
Q_ASSERT(tc);
|
Q_ASSERT(tc);
|
||||||
QString displayName = tc->displayName();
|
QString displayName = tc->displayName();
|
||||||
tc->setDisplayName(displayName); // reset display name
|
tc->setDisplayName(displayName); // reset display name
|
||||||
tc->setSdpPath(m_sdpPath->filePath().toString());
|
tc->setSdpPath(m_sdpPath->filePath());
|
||||||
tc->setTargetAbi(m_abiWidget->currentAbi());
|
tc->setTargetAbi(m_abiWidget->currentAbi());
|
||||||
tc->resetToolChain(m_compilerCommand->filePath());
|
tc->resetToolChain(m_compilerCommand->filePath());
|
||||||
}
|
}
|
||||||
@@ -281,7 +281,7 @@ void QnxToolChainConfigWidget::discardImpl()
|
|||||||
QSignalBlocker blocker(this);
|
QSignalBlocker blocker(this);
|
||||||
auto tc = static_cast<const QnxToolChain *>(toolChain());
|
auto tc = static_cast<const QnxToolChain *>(toolChain());
|
||||||
m_compilerCommand->setFilePath(tc->compilerCommand());
|
m_compilerCommand->setFilePath(tc->compilerCommand());
|
||||||
m_sdpPath->setPath(tc->sdpPath());
|
m_sdpPath->setFilePath(tc->sdpPath());
|
||||||
m_abiWidget->setAbis(tc->supportedAbis(), tc->targetAbi());
|
m_abiWidget->setAbis(tc->supportedAbis(), tc->targetAbi());
|
||||||
if (!m_compilerCommand->filePath().toString().isEmpty())
|
if (!m_compilerCommand->filePath().toString().isEmpty())
|
||||||
m_abiWidget->setEnabled(true);
|
m_abiWidget->setEnabled(true);
|
||||||
@@ -292,7 +292,7 @@ bool QnxToolChainConfigWidget::isDirtyImpl() const
|
|||||||
auto tc = static_cast<const QnxToolChain *>(toolChain());
|
auto tc = static_cast<const QnxToolChain *>(toolChain());
|
||||||
Q_ASSERT(tc);
|
Q_ASSERT(tc);
|
||||||
return m_compilerCommand->filePath() != tc->compilerCommand()
|
return m_compilerCommand->filePath() != tc->compilerCommand()
|
||||||
|| m_sdpPath->filePath().toString() != tc->sdpPath()
|
|| m_sdpPath->filePath() != tc->sdpPath()
|
||||||
|| m_abiWidget->currentAbi() != tc->targetAbi();
|
|| m_abiWidget->currentAbi() != tc->targetAbi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -46,8 +46,8 @@ public:
|
|||||||
QVariantMap toMap() const override;
|
QVariantMap toMap() const override;
|
||||||
bool fromMap(const QVariantMap &data) override;
|
bool fromMap(const QVariantMap &data) override;
|
||||||
|
|
||||||
QString sdpPath() const;
|
Utils::FilePath sdpPath() const;
|
||||||
void setSdpPath(const QString &sdpPath);
|
void setSdpPath(const Utils::FilePath &sdpPath);
|
||||||
QString cpuDir() const;
|
QString cpuDir() const;
|
||||||
void setCpuDir(const QString &cpuDir);
|
void setCpuDir(const QString &cpuDir);
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ protected:
|
|||||||
DetectedAbisResult detectSupportedAbis() const override;
|
DetectedAbisResult detectSupportedAbis() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_sdpPath;
|
Utils::FilePath m_sdpPath;
|
||||||
QString m_cpuDir;
|
QString m_cpuDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -78,11 +78,11 @@ QString QnxUtils::cpuDirShortDescription(const QString &cpuDir)
|
|||||||
return cpuDir;
|
return cpuDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnvironmentItems QnxUtils::qnxEnvironmentFromEnvFile(const QString &fileName)
|
EnvironmentItems QnxUtils::qnxEnvironmentFromEnvFile(const FilePath &filePath)
|
||||||
{
|
{
|
||||||
EnvironmentItems items;
|
EnvironmentItems items;
|
||||||
|
|
||||||
if (!QFileInfo::exists(fileName))
|
if (!filePath.exists())
|
||||||
return items;
|
return items;
|
||||||
|
|
||||||
const bool isWindows = HostOsInfo::isWindowsHost();
|
const bool isWindows = HostOsInfo::isWindowsHost();
|
||||||
@@ -97,10 +97,10 @@ EnvironmentItems QnxUtils::qnxEnvironmentFromEnvFile(const QString &fileName)
|
|||||||
QTextStream fileContent(&tmpFile);
|
QTextStream fileContent(&tmpFile);
|
||||||
if (isWindows)
|
if (isWindows)
|
||||||
fileContent << "@echo off\n"
|
fileContent << "@echo off\n"
|
||||||
<< "call " << fileName << '\n';
|
<< "call " << filePath.path() << '\n';
|
||||||
else
|
else
|
||||||
fileContent << "#!/bin/bash\n"
|
fileContent << "#!/bin/bash\n"
|
||||||
<< ". " << fileName << '\n';
|
<< ". " << filePath.path() << '\n';
|
||||||
QString linePattern = QString::fromLatin1(isWindows ? "echo %1=%%1%" : "echo %1=$%1");
|
QString linePattern = QString::fromLatin1(isWindows ? "echo %1=%%1%" : "echo %1=$%1");
|
||||||
for (int i = 0, len = sizeof(EVAL_ENV_VARS) / sizeof(const char *); i < len; ++i)
|
for (int i = 0, len = sizeof(EVAL_ENV_VARS) / sizeof(const char *); i < len; ++i)
|
||||||
fileContent << linePattern.arg(QLatin1String(EVAL_ENV_VARS[i])) << QLatin1Char('\n');
|
fileContent << linePattern.arg(QLatin1String(EVAL_ENV_VARS[i])) << QLatin1Char('\n');
|
||||||
@@ -140,19 +140,18 @@ EnvironmentItems QnxUtils::qnxEnvironmentFromEnvFile(const QString &fileName)
|
|||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QnxUtils::envFilePath(const QString &sdpPath)
|
FilePath QnxUtils::envFilePath(const FilePath &sdpPath)
|
||||||
{
|
{
|
||||||
QDir sdp(sdpPath);
|
FilePaths entries;
|
||||||
QStringList entries;
|
if (sdpPath.osType() == OsTypeWindows)
|
||||||
if (HostOsInfo::isWindowsHost())
|
entries = sdpPath.dirEntries({"*-env.bat"});
|
||||||
entries = sdp.entryList(QStringList(QLatin1String("*-env.bat")));
|
|
||||||
else
|
else
|
||||||
entries = sdp.entryList(QStringList(QLatin1String("*-env.sh")));
|
entries = sdpPath.dirEntries({"*-env.sh"});
|
||||||
|
|
||||||
if (!entries.isEmpty())
|
if (!entries.isEmpty())
|
||||||
return sdp.absoluteFilePath(entries.first());
|
return entries.first();
|
||||||
|
|
||||||
return QString();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QnxUtils::defaultTargetVersion(const QString &sdpPath)
|
QString QnxUtils::defaultTargetVersion(const QString &sdpPath)
|
||||||
@@ -208,7 +207,7 @@ QList<ConfigInstallInformation> QnxUtils::installedConfigs(const QString &config
|
|||||||
return sdpList;
|
return sdpList;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnvironmentItems QnxUtils::qnxEnvironment(const QString &sdpPath)
|
EnvironmentItems QnxUtils::qnxEnvironment(const FilePath &sdpPath)
|
||||||
{
|
{
|
||||||
return qnxEnvironmentFromEnvFile(envFilePath(sdpPath));
|
return qnxEnvironmentFromEnvFile(envFilePath(sdpPath));
|
||||||
}
|
}
|
||||||
|
@@ -68,11 +68,11 @@ class QnxUtils
|
|||||||
public:
|
public:
|
||||||
static QString cpuDirFromAbi(const ProjectExplorer::Abi &abi);
|
static QString cpuDirFromAbi(const ProjectExplorer::Abi &abi);
|
||||||
static QString cpuDirShortDescription(const QString &cpuDir);
|
static QString cpuDirShortDescription(const QString &cpuDir);
|
||||||
static Utils::EnvironmentItems qnxEnvironmentFromEnvFile(const QString &fileName);
|
static Utils::EnvironmentItems qnxEnvironmentFromEnvFile(const Utils::FilePath &filePath);
|
||||||
static QString envFilePath(const QString &sdpPath);
|
static Utils::FilePath envFilePath(const Utils::FilePath &sdpPath);
|
||||||
static QString defaultTargetVersion(const QString &sdpPath);
|
static QString defaultTargetVersion(const QString &sdpPath);
|
||||||
static QList<ConfigInstallInformation> installedConfigs(const QString &configPath = QString());
|
static QList<ConfigInstallInformation> installedConfigs(const QString &configPath = QString());
|
||||||
static Utils::EnvironmentItems qnxEnvironment(const QString &sdpPath);
|
static Utils::EnvironmentItems qnxEnvironment(const Utils::FilePath &sdpPath);
|
||||||
static QList<QnxTarget> findTargets(const Utils::FilePath &basePath);
|
static QList<QnxTarget> findTargets(const Utils::FilePath &basePath);
|
||||||
static ProjectExplorer::Abi convertAbi(const ProjectExplorer::Abi &abi);
|
static ProjectExplorer::Abi convertAbi(const ProjectExplorer::Abi &abi);
|
||||||
static ProjectExplorer::Abis convertAbis(const ProjectExplorer::Abis &abis);
|
static ProjectExplorer::Abis convertAbis(const ProjectExplorer::Abis &abis);
|
||||||
|
Before Width: | Height: | Size: 374 KiB After Width: | Height: | Size: 372 KiB |