Merge remote-tracking branch 'origin/5.0'
Change-Id: I9dca34a9895d19ace05aef5b73e9a806b23607fb
55
dist/changes-4.15.2.md
vendored
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
Qt Creator 4.15.2
|
||||||
|
=================
|
||||||
|
|
||||||
|
Qt Creator version 4.15.2 contains bug fixes.
|
||||||
|
|
||||||
|
The most important changes are listed in this document. For a complete
|
||||||
|
list of changes, see the Git log for the Qt Creator sources that
|
||||||
|
you can check out from the public Git repository. For example:
|
||||||
|
|
||||||
|
git clone git://code.qt.io/qt-creator/qt-creator.git
|
||||||
|
git log --cherry-pick --pretty=oneline origin/v4.15.1..v4.15.2
|
||||||
|
|
||||||
|
Projects
|
||||||
|
--------
|
||||||
|
|
||||||
|
### CMake
|
||||||
|
|
||||||
|
* Improved performance after project load and reparse
|
||||||
|
* Fixed crash on session switch (QTCREATORBUG-25837)
|
||||||
|
|
||||||
|
### qmake
|
||||||
|
|
||||||
|
* Fixed issues with executing system calls (QTCREATORBUG-25970)
|
||||||
|
|
||||||
|
Test Integration
|
||||||
|
----------------
|
||||||
|
|
||||||
|
### CTest
|
||||||
|
|
||||||
|
* Fixed test detection if `ctest` takes long to run (QTCREATORBUG-25851)
|
||||||
|
|
||||||
|
Platforms
|
||||||
|
---------
|
||||||
|
|
||||||
|
### WASM
|
||||||
|
|
||||||
|
* Fixed Python version that is on Windows (QTCREATORBUG-25897)
|
||||||
|
|
||||||
|
Credits for these changes go to:
|
||||||
|
--------------------------------
|
||||||
|
Ahmad Samir
|
||||||
|
Alessandro Portale
|
||||||
|
Christian Stenger
|
||||||
|
Cristian Adam
|
||||||
|
Eike Ziller
|
||||||
|
Ivan Komissarov
|
||||||
|
Kai Köhne
|
||||||
|
Knud Dollereder
|
||||||
|
Michael Winkelmann
|
||||||
|
Mitch Curtis
|
||||||
|
Robert Löhning
|
||||||
|
Thomas Hartmann
|
||||||
|
Tim Blechmann
|
||||||
|
Tim Jenssen
|
||||||
|
Tuomo Pelkonen
|
BIN
doc/qtcreator/images/icons/copy-formatting.png
Normal file
After Width: | Height: | Size: 277 B |
BIN
doc/qtcreator/images/icons/paste-formatting.png
Normal file
After Width: | Height: | Size: 243 B |
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 32 KiB |
@@ -131,8 +131,9 @@
|
|||||||
|
|
||||||
\section1 Image Alignment
|
\section1 Image Alignment
|
||||||
|
|
||||||
You can align images horizontally and vertically. By default, images are
|
You can align images horizontally and vertically in the
|
||||||
centered.
|
\uicontrol {Alignment H} and \uicontrol {Alignment V}
|
||||||
|
fields. By default, images are centered.
|
||||||
|
|
||||||
Select the \uicontrol Mirrored check box to horizontally invert the image,
|
Select the \uicontrol Mirrored check box to horizontally invert the image,
|
||||||
effectively displaying a mirrored image.
|
effectively displaying a mirrored image.
|
||||||
@@ -161,8 +162,7 @@
|
|||||||
of each image. A source image is broken into 9 regions that are scaled or
|
of each image. A source image is broken into 9 regions that are scaled or
|
||||||
tiled individually. The corner regions are not scaled at all, while the
|
tiled individually. The corner regions are not scaled at all, while the
|
||||||
horizontal and vertical regions are scaled according to the values of the
|
horizontal and vertical regions are scaled according to the values of the
|
||||||
\uicontrol {Horizontal tile mode} and \uicontrol {Vertical tile mode} field,
|
\uicontrol {Tile mode H} and \uicontrol {Tile mode V} field, or both.
|
||||||
or both.
|
|
||||||
|
|
||||||
The \uicontrol Stretch option scales the image to fit the available area.
|
The \uicontrol Stretch option scales the image to fit the available area.
|
||||||
The \uicontrol Repeat option tiles the image until there is no more space.
|
The \uicontrol Repeat option tiles the image until there is no more space.
|
||||||
@@ -193,8 +193,10 @@
|
|||||||
|
|
||||||
\image qtquick-designer-animated-image-properties.png "Animated Image properties"
|
\image qtquick-designer-animated-image-properties.png "Animated Image properties"
|
||||||
|
|
||||||
To pause or play the animation, select the \uicontrol Paused or
|
To play the animation, select the \uicontrol Playing check box.
|
||||||
\uicontrol Playing check boxes.
|
|
||||||
|
To pause the animation, select the \inlineimage icons/pause-icon.png
|
||||||
|
(\uicontrol Paused) check box.
|
||||||
|
|
||||||
When the \uicontrol Cache check box is selected, every frame of the
|
When the \uicontrol Cache check box is selected, every frame of the
|
||||||
animation is cached. Deselect the check box if you are playing a long
|
animation is cached. Deselect the check box if you are playing a long
|
||||||
|
@@ -230,6 +230,17 @@
|
|||||||
\li Resets anchors to their saved state for the selected component.
|
\li Resets anchors to their saved state for the selected component.
|
||||||
\li \key Ctrl+Shift+R (\key Shift+Cmd+R on \macos)
|
\li \key Ctrl+Shift+R (\key Shift+Cmd+R on \macos)
|
||||||
\li \l{Setting Anchors and Margins}
|
\li \l{Setting Anchors and Margins}
|
||||||
|
\row
|
||||||
|
\li \inlineimage icons/copy-formatting.png
|
||||||
|
\li Copies property values from the selected component.
|
||||||
|
\li
|
||||||
|
\li \l{Copying and Pasting Formatting}
|
||||||
|
\row
|
||||||
|
\li \inlineimage icons/paste-formatting.png
|
||||||
|
\li Applies copied property values to one or several selected
|
||||||
|
components.
|
||||||
|
\li
|
||||||
|
\li \l{Copying and Pasting Formatting}
|
||||||
\row
|
\row
|
||||||
\li \inlineimage row.png
|
\li \inlineimage row.png
|
||||||
\li Uses a \uicontrol Row component to lay out the selected components.
|
\li Uses a \uicontrol Row component to lay out the selected components.
|
||||||
|
@@ -409,6 +409,22 @@
|
|||||||
and vertically. Note that some OpenGL ES 2 implementations do not support
|
and vertically. Note that some OpenGL ES 2 implementations do not support
|
||||||
the \uicontrol Repeat wrap mode with non-power-of-two textures.
|
the \uicontrol Repeat wrap mode with non-power-of-two textures.
|
||||||
|
|
||||||
|
\section1 Copying and Pasting Formatting
|
||||||
|
|
||||||
|
You can copy property values from a component and paste them to one or
|
||||||
|
several other components. The values are applied if the target components
|
||||||
|
have those particular properties.
|
||||||
|
|
||||||
|
To copy property values from the selected component, select
|
||||||
|
\inlineimage icons/copy-formatting.png
|
||||||
|
on the \uicontrol Design mode \l{Summary of Main Toolbar Actions}
|
||||||
|
{main toolbar}.
|
||||||
|
|
||||||
|
To apply the values to one or several other components, select
|
||||||
|
them in \l Navigator or \l{Form Editor}, and then select
|
||||||
|
\inlineimage icons/paste-formatting.png
|
||||||
|
.
|
||||||
|
|
||||||
\section1 Editing Properties Inline
|
\section1 Editing Properties Inline
|
||||||
|
|
||||||
You can double-click components in \l {Form Editor} to edit their
|
You can double-click components in \l {Form Editor} to edit their
|
||||||
|
@@ -153,6 +153,7 @@ Section {
|
|||||||
visible: section.showEasingCurve
|
visible: section.showEasingCurve
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SecondColumnLayout {
|
||||||
BoolButtonRowButton {
|
BoolButtonRowButton {
|
||||||
visible: section.showEasingCurve
|
visible: section.showEasingCurve
|
||||||
buttonIcon: StudioTheme.Constants.curveDesigner
|
buttonIcon: StudioTheme.Constants.curveDesigner
|
||||||
@@ -164,5 +165,8 @@ Section {
|
|||||||
|
|
||||||
onClicked: easingCurveEditor.runDialog()
|
onClicked: easingCurveEditor.runDialog()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExpandingSpacer {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,7 +32,6 @@ StudioControls.ButtonRow {
|
|||||||
id: buttonRow
|
id: buttonRow
|
||||||
|
|
||||||
enabled: anchorBackend.hasParent && isBaseState
|
enabled: anchorBackend.hasParent && isBaseState
|
||||||
opacity: enabled ? 1 : 0.5
|
|
||||||
actionIndicatorVisible: false
|
actionIndicatorVisible: false
|
||||||
|
|
||||||
StudioControls.ButtonGroup { id: group }
|
StudioControls.ButtonGroup { id: group }
|
||||||
|
@@ -28,42 +28,39 @@ import QtQuick.Layouts 1.15
|
|||||||
import StudioControls 1.0 as StudioControls
|
import StudioControls 1.0 as StudioControls
|
||||||
import StudioTheme 1.0 as StudioTheme
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
id: editableListView
|
id: editableListView
|
||||||
|
|
||||||
property variant backendValue
|
|
||||||
|
|
||||||
ExtendedFunctionLogic {
|
ExtendedFunctionLogic {
|
||||||
id: extFuncLogic
|
id: extFuncLogic
|
||||||
backendValue: editableListView.backendValue
|
backendValue: editableListView.backendValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property var backendValue
|
||||||
property var model
|
property var model
|
||||||
onModelChanged: myRepeater.updateModel()
|
onModelChanged: myRepeater.updateModel()
|
||||||
|
|
||||||
|
property alias actionIndicator: actionIndicator
|
||||||
|
property alias actionIndicatorVisible: actionIndicator.visible
|
||||||
|
property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth
|
||||||
|
property real __actionIndicatorHeight: StudioTheme.Values.height
|
||||||
|
property string typeFilter: "QtQuick3D.Material"
|
||||||
|
property int activatedReason: ComboBox.ActivatedReason.Other
|
||||||
|
|
||||||
|
property bool delegateHover: false
|
||||||
|
|
||||||
signal add(string value)
|
signal add(string value)
|
||||||
signal remove(int idx)
|
signal remove(int idx)
|
||||||
signal replace(int idx, string value)
|
signal replace(int idx, string value)
|
||||||
|
|
||||||
property alias actionIndicator: actionIndicator
|
|
||||||
|
|
||||||
property alias actionIndicatorVisible: actionIndicator.visible
|
|
||||||
property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth
|
|
||||||
property real __actionIndicatorHeight: StudioTheme.Values.height
|
|
||||||
|
|
||||||
property string typeFilter: "QtQuick3D.Material"
|
|
||||||
|
|
||||||
property int activatedReason: ComboBox.ActivatedReason.Other
|
|
||||||
|
|
||||||
color: "transparent"
|
|
||||||
border.color: StudioTheme.Values.themeControlOutline
|
|
||||||
border.width: StudioTheme.Values.border
|
|
||||||
|
|
||||||
Layout.preferredWidth: StudioTheme.Values.height * 10
|
Layout.preferredWidth: StudioTheme.Values.height * 10
|
||||||
Layout.preferredHeight: myColumn.height
|
Layout.preferredHeight: myColumn.height
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: myDelegate
|
id: myDelegate
|
||||||
|
|
||||||
|
Row {
|
||||||
|
property alias comboBox: itemFilterComboBox
|
||||||
ListViewComboBox {
|
ListViewComboBox {
|
||||||
id: itemFilterComboBox
|
id: itemFilterComboBox
|
||||||
|
|
||||||
@@ -76,13 +73,12 @@ Rectangle {
|
|||||||
typeFilter: editableListView.typeFilter
|
typeFilter: editableListView.typeFilter
|
||||||
editText: modelData
|
editText: modelData
|
||||||
initialModelData: modelData
|
initialModelData: modelData
|
||||||
|
implicitWidth: StudioTheme.Values.singleControlColumnWidth
|
||||||
width: editableListView.width
|
width: implicitWidth
|
||||||
|
|
||||||
onFocusChanged: {
|
onFocusChanged: {
|
||||||
if (itemFilterComboBox.focus) {
|
if (itemFilterComboBox.focus)
|
||||||
myColumn.currentIndex = index
|
myColumn.currentIndex = index
|
||||||
}
|
|
||||||
|
|
||||||
if (itemFilterComboBox.empty && itemFilterComboBox.editText !== "") {
|
if (itemFilterComboBox.empty && itemFilterComboBox.editText !== "") {
|
||||||
myRepeater.dirty = false
|
myRepeater.dirty = false
|
||||||
@@ -100,20 +96,39 @@ Rectangle {
|
|||||||
editableListView.replace(itemFilterComboBox.myIndex, itemFilterComboBox.editText)
|
editableListView.replace(itemFilterComboBox.myIndex, itemFilterComboBox.editText)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onHoverChanged: editableListView.delegateHover = itemFilterComboBox.hover
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer { implicitWidth: StudioTheme.Values.twoControlColumnGap }
|
||||||
|
|
||||||
|
IconIndicator {
|
||||||
|
id: closeIndicator
|
||||||
|
icon: StudioTheme.Constants.closeCross
|
||||||
|
onClicked: {
|
||||||
|
var lastItem = index === myRepeater.localModel.length - 1
|
||||||
|
if (myColumn.currentItem.initialModelData === "") {
|
||||||
|
myRepeater.localModel.pop()
|
||||||
|
myRepeater.dirty = false
|
||||||
|
myRepeater.model = myRepeater.localModel // trigger on change handler
|
||||||
|
} else {
|
||||||
|
editableListView.remove(index)
|
||||||
|
}
|
||||||
|
if (!lastItem)
|
||||||
|
myColumn.currentIndex = index - 1
|
||||||
|
}
|
||||||
|
onHoveredChanged: editableListView.delegateHover = closeIndicator.hovered
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Row {
|
||||||
id: highlightRect
|
ActionIndicator {
|
||||||
color: "transparent"
|
id: actionIndicator
|
||||||
border.width: StudioTheme.Values.border
|
icon.visible: editableListView.delegateHover
|
||||||
border.color: StudioTheme.Values.themeInteraction
|
icon.color: extFuncLogic.color
|
||||||
visible: myColumn.currentItem ? myColumn.currentItem.focus : false
|
icon.text: extFuncLogic.glyph
|
||||||
x: myColumn.currentItem ? myColumn.currentItem.x : 0
|
onClicked: extFuncLogic.show()
|
||||||
y: myColumn.currentItem ? myColumn.currentItem.y : 0
|
|
||||||
z: 10
|
|
||||||
width: myColumn.currentItem ? myColumn.currentItem.width : 0
|
|
||||||
height: myColumn.currentItem ? myColumn.currentItem.height : 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
@@ -122,9 +137,13 @@ Rectangle {
|
|||||||
property int currentIndex: -1
|
property int currentIndex: -1
|
||||||
property Item currentItem
|
property Item currentItem
|
||||||
|
|
||||||
spacing: -1
|
spacing: StudioTheme.Values.sectionRowSpacing
|
||||||
|
|
||||||
onCurrentIndexChanged: myColumn.currentItem = myRepeater.itemAt(myColumn.currentIndex)
|
onCurrentIndexChanged: {
|
||||||
|
var tmp = myRepeater.itemAt(myColumn.currentIndex)
|
||||||
|
if (tmp !== null)
|
||||||
|
myColumn.currentItem = tmp.comboBox
|
||||||
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: myRepeater
|
id: myRepeater
|
||||||
@@ -161,37 +180,60 @@ Rectangle {
|
|||||||
else
|
else
|
||||||
myColumn.currentIndex = myRepeater.localModel.length - 1
|
myColumn.currentIndex = myRepeater.localModel.length - 1
|
||||||
|
|
||||||
if (editableListView.activatedReason === ComboBox.ActivatedReason.Other)
|
if (editableListView.activatedReason === ComboBox.ActivatedReason.Other
|
||||||
|
&& myColumn.currentItem !== null)
|
||||||
myColumn.currentItem.forceActiveFocus()
|
myColumn.currentItem.forceActiveFocus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
ListViewComboBox {
|
||||||
id: dummyItem
|
id: dummyComboBox
|
||||||
|
|
||||||
|
//property int myIndex: index
|
||||||
|
//property bool empty: dummyComboBox.initialModelData === ""
|
||||||
|
|
||||||
visible: myRepeater.count === 0
|
visible: myRepeater.count === 0
|
||||||
width: StudioTheme.Values.height
|
|
||||||
height: StudioTheme.Values.height
|
validator: RegExpValidator { regExp: /(^[a-z_]\w*|^[A-Z]\w*\.{1}([a-z_]\w*\.?)+)/ }
|
||||||
|
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
typeFilter: editableListView.typeFilter
|
||||||
|
//editText: modelData
|
||||||
|
//initialModelData: modelData
|
||||||
|
implicitWidth: StudioTheme.Values.singleControlColumnWidth
|
||||||
|
width: implicitWidth
|
||||||
|
|
||||||
|
onFocusChanged: {
|
||||||
|
//if (itemFilterComboBox.focus)
|
||||||
|
// myColumn.currentIndex = index
|
||||||
|
|
||||||
|
if (/*dummyComboBox.empty && */dummyComboBox.editText !== "") {
|
||||||
|
//myRepeater.dirty = false
|
||||||
|
editableListView.add(dummyComboBox.editText)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
onCompressedActivated: {
|
||||||
id: row
|
editableListView.activatedReason = reason
|
||||||
spacing: -StudioTheme.Values.border
|
|
||||||
|
|
||||||
StudioControls.ActionIndicator {
|
if (/*dummyComboBox.empty && */dummyComboBox.editText !== "") {
|
||||||
id: actionIndicator
|
//myRepeater.dirty = false
|
||||||
width: actionIndicator.visible ? __actionIndicatorWidth : 0
|
editableListView.add(dummyComboBox.editText)
|
||||||
height: actionIndicator.visible ? __actionIndicatorHeight : 0
|
} else {
|
||||||
|
editableListView.replace(dummyComboBox.myIndex, dummyComboBox.editText)
|
||||||
border.width: StudioTheme.Values.border
|
|
||||||
border.color: StudioTheme.Values.themeControlOutline
|
|
||||||
|
|
||||||
icon.color: extFuncLogic.color
|
|
||||||
icon.text: extFuncLogic.glyph
|
|
||||||
onClicked: extFuncLogic.show()
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onHoverChanged: editableListView.delegateHover = dummyComboBox.hover
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
StudioControls.AbstractButton {
|
StudioControls.AbstractButton {
|
||||||
|
id: plusButton
|
||||||
buttonIcon: StudioTheme.Constants.plus
|
buttonIcon: StudioTheme.Constants.plus
|
||||||
enabled: !myRepeater.dirty && !(editableListView.backendValue.isInModel && !editableListView.backendValue.isIdList)
|
enabled: !myRepeater.dirty && !(editableListView.backendValue.isInModel
|
||||||
|
&& !editableListView.backendValue.isIdList)
|
||||||
onClicked: {
|
onClicked: {
|
||||||
var idx = myRepeater.localModel.push("") - 1
|
var idx = myRepeater.localModel.push("") - 1
|
||||||
myRepeater.model = myRepeater.localModel // trigger on change handler
|
myRepeater.model = myRepeater.localModel // trigger on change handler
|
||||||
@@ -199,29 +241,7 @@ Rectangle {
|
|||||||
myColumn.currentIndex = idx
|
myColumn.currentIndex = idx
|
||||||
myColumn.currentItem.forceActiveFocus()
|
myColumn.currentItem.forceActiveFocus()
|
||||||
}
|
}
|
||||||
}
|
onHoveredChanged: editableListView.delegateHover = plusButton.hovered
|
||||||
StudioControls.AbstractButton {
|
|
||||||
buttonIcon: StudioTheme.Constants.minus
|
|
||||||
enabled: myRepeater.model.length && !(editableListView.backendValue.isInModel && !editableListView.backendValue.isIdList)
|
|
||||||
onClicked: {
|
|
||||||
var lastItem = myColumn.currentIndex === myRepeater.localModel.length - 1
|
|
||||||
if (myColumn.currentItem.initialModelData === "") {
|
|
||||||
myRepeater.localModel.pop()
|
|
||||||
myRepeater.dirty = false
|
|
||||||
myRepeater.model = myRepeater.localModel // trigger on change handler
|
|
||||||
} else {
|
|
||||||
editableListView.remove(myColumn.currentIndex)
|
|
||||||
}
|
|
||||||
if (!lastItem)
|
|
||||||
myColumn.currentIndex = myColumn.currentIndex - 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
color: StudioTheme.Values.themeControlBackground
|
|
||||||
border.width: StudioTheme.Values.border
|
|
||||||
border.color: StudioTheme.Values.themeControlOutline
|
|
||||||
height: StudioTheme.Values.height
|
|
||||||
width: editableListView.width - (StudioTheme.Values.height - StudioTheme.Values.border) * (actionIndicatorVisible ? 3 : 2)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -97,7 +97,7 @@ Item {
|
|||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: modelNodeBackend
|
target: modelNodeBackend
|
||||||
onSelectionChanged: menu.close()
|
function onSelectionChanged() { menu.close() }
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
|
@@ -37,6 +37,8 @@ Rectangle {
|
|||||||
property alias pixelSize: indicatorIcon.font.pixelSize
|
property alias pixelSize: indicatorIcon.font.pixelSize
|
||||||
property alias tooltip: toolTipArea.tooltip
|
property alias tooltip: toolTipArea.tooltip
|
||||||
|
|
||||||
|
property bool hovered: toolTipArea.containsMouse && root.enabled
|
||||||
|
|
||||||
signal clicked()
|
signal clicked()
|
||||||
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
@@ -258,7 +258,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: spinBoxIndicator
|
target: spinBoxIndicator
|
||||||
color: StudioTheme.Values.themeControlBackground
|
color: StudioTheme.Values.themeControlBackgroundDisabled
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
|
@@ -22,7 +22,7 @@ DSdisabledColor=ff8e8e8e
|
|||||||
|
|
||||||
DScontrolBackground=ffeaeaea
|
DScontrolBackground=ffeaeaea
|
||||||
DScontrolBackgroundInteraction=ffc9c9c9
|
DScontrolBackgroundInteraction=ffc9c9c9
|
||||||
DScontrolBackgroundDisabled=ff8e8e8e
|
DScontrolBackgroundDisabled=ffeaeaea
|
||||||
DScontrolBackgroundGlobalHover=ffe5e5e5
|
DScontrolBackgroundGlobalHover=ffe5e5e5
|
||||||
DScontrolBackgroundHover=ffd1d1d1
|
DScontrolBackgroundHover=ffd1d1d1
|
||||||
|
|
||||||
|
@@ -36,7 +36,7 @@ DSdisabledColor=ff8e8e8e
|
|||||||
|
|
||||||
DScontrolBackground=ffeaeaea
|
DScontrolBackground=ffeaeaea
|
||||||
DScontrolBackgroundInteraction=ffc9c9c9
|
DScontrolBackgroundInteraction=ffc9c9c9
|
||||||
DScontrolBackgroundDisabled=ff8e8e8e
|
DScontrolBackgroundDisabled=ffeaeaea
|
||||||
DScontrolBackgroundGlobalHover=ffe5e5e5
|
DScontrolBackgroundGlobalHover=ffe5e5e5
|
||||||
DScontrolBackgroundHover=ffd1d1d1
|
DScontrolBackgroundHover=ffd1d1d1
|
||||||
|
|
||||||
|
@@ -31,7 +31,7 @@ DSdisabledColor=ff8e8e8e
|
|||||||
|
|
||||||
DScontrolBackground=ffeaeaea
|
DScontrolBackground=ffeaeaea
|
||||||
DScontrolBackgroundInteraction=ffc9c9c9
|
DScontrolBackgroundInteraction=ffc9c9c9
|
||||||
DScontrolBackgroundDisabled=ff8e8e8e
|
DScontrolBackgroundDisabled=ffeaeaea
|
||||||
DScontrolBackgroundGlobalHover=ffe5e5e5
|
DScontrolBackgroundGlobalHover=ffe5e5e5
|
||||||
DScontrolBackgroundHover=ffd1d1d1
|
DScontrolBackgroundHover=ffd1d1d1
|
||||||
|
|
||||||
|
@@ -1374,17 +1374,17 @@ FilePath FilePath::onDevice(const FilePath &deviceTemplate) const
|
|||||||
Example usage:
|
Example usage:
|
||||||
\code
|
\code
|
||||||
binary = FilePath::fromUrl("docker://123/./make);
|
binary = FilePath::fromUrl("docker://123/./make);
|
||||||
fullPath = binary.onDeviceSearchInPath();
|
fullPath = binary.searchOnDevice();
|
||||||
assert(fullPath == FilePath::fromUrl("docker://123/usr/bin/make"))
|
assert(fullPath == FilePath::fromUrl("docker://123/usr/bin/make"))
|
||||||
\endcode
|
\endcode
|
||||||
*/
|
*/
|
||||||
FilePath FilePath::onDeviceSearchInPath(const FilePaths &additionalDirs) const
|
FilePath FilePath::searchOnDevice(const FilePaths &dirs) const
|
||||||
{
|
{
|
||||||
if (needsDevice()) {
|
if (needsDevice()) {
|
||||||
QTC_ASSERT(s_deviceHooks.searchInPath, return {});
|
QTC_ASSERT(s_deviceHooks.searchInPath, return {});
|
||||||
return s_deviceHooks.searchInPath(*this, additionalDirs);
|
return s_deviceHooks.searchInPath(*this, dirs);
|
||||||
}
|
}
|
||||||
return Environment::systemEnvironment().searchInPath(path(), additionalDirs);
|
return Environment::systemEnvironment().searchInPath(path(), dirs);
|
||||||
}
|
}
|
||||||
|
|
||||||
Environment FilePath::deviceEnvironment() const
|
Environment FilePath::deviceEnvironment() const
|
||||||
|
@@ -216,7 +216,7 @@ public:
|
|||||||
|
|
||||||
static void setDeviceFileHooks(const DeviceFileHooks &hooks);
|
static void setDeviceFileHooks(const DeviceFileHooks &hooks);
|
||||||
|
|
||||||
FilePath onDeviceSearchInPath(const QList<FilePath> &additionalDirs = {}) const;
|
FilePath searchOnDevice(const QList<FilePath> &dirs) const;
|
||||||
Environment deviceEnvironment() const;
|
Environment deviceEnvironment() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -196,6 +196,8 @@ void QtTestOutputReader::processXMLOutput(const QByteArray &outputLine)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (m_cdataMode == Description)
|
||||||
|
m_xmlReader.addData("\n");
|
||||||
m_xmlReader.addData(QString::fromUtf8(outputLine));
|
m_xmlReader.addData(QString::fromUtf8(outputLine));
|
||||||
while (!m_xmlReader.atEnd()) {
|
while (!m_xmlReader.atEnd()) {
|
||||||
if (m_futureInterface.isCanceled())
|
if (m_futureInterface.isCanceled())
|
||||||
|
@@ -410,8 +410,7 @@ QtTestParseResult *QtTestParser::createParseResult(
|
|||||||
dataTag->itemType = tag.m_type;
|
dataTag->itemType = tag.m_type;
|
||||||
dataTag->name = tag.m_name;
|
dataTag->name = tag.m_name;
|
||||||
dataTag->displayName = tag.m_name;
|
dataTag->displayName = tag.m_name;
|
||||||
dataTag->fileName = Utils::FilePath::fromString(
|
dataTag->fileName = data.testFunctions.value(it.key() + "_data").m_filePath;
|
||||||
data.testFunctions.value(it.key() + "_data").m_name);
|
|
||||||
dataTag->line = tag.m_line;
|
dataTag->line = tag.m_line;
|
||||||
dataTag->column = tag.m_column;
|
dataTag->column = tag.m_column;
|
||||||
dataTag->setInherited(tag.m_inherited);
|
dataTag->setInherited(tag.m_inherited);
|
||||||
|
@@ -839,13 +839,15 @@ void ClangdClient::openExtraFile(const Utils::FilePath &filePath, const QString
|
|||||||
item.setUri(DocumentUri::fromFilePath(filePath));
|
item.setUri(DocumentUri::fromFilePath(filePath));
|
||||||
item.setText(!content.isEmpty() ? content : QString::fromUtf8(cxxFile.readAll()));
|
item.setText(!content.isEmpty() ? content : QString::fromUtf8(cxxFile.readAll()));
|
||||||
item.setVersion(0);
|
item.setVersion(0);
|
||||||
sendContent(DidOpenTextDocumentNotification(DidOpenTextDocumentParams(item)));
|
sendContent(DidOpenTextDocumentNotification(DidOpenTextDocumentParams(item)),
|
||||||
|
SendDocUpdates::Ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangdClient::closeExtraFile(const Utils::FilePath &filePath)
|
void ClangdClient::closeExtraFile(const Utils::FilePath &filePath)
|
||||||
{
|
{
|
||||||
sendContent(DidCloseTextDocumentNotification(DidCloseTextDocumentParams(
|
sendContent(DidCloseTextDocumentNotification(DidCloseTextDocumentParams(
|
||||||
TextDocumentIdentifier{DocumentUri::fromFilePath(filePath)})));
|
TextDocumentIdentifier{DocumentUri::fromFilePath(filePath)})),
|
||||||
|
SendDocUpdates::Ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangdClient::findUsages(TextEditor::TextDocument *document, const QTextCursor &cursor,
|
void ClangdClient::findUsages(TextEditor::TextDocument *document, const QTextCursor &cursor,
|
||||||
@@ -1036,7 +1038,7 @@ void ClangdClient::Private::handleFindUsagesResult(quint64 key, const QList<Loca
|
|||||||
});
|
});
|
||||||
qCDebug(clangdLog) << "requesting AST for" << it.key().toFilePath();
|
qCDebug(clangdLog) << "requesting AST for" << it.key().toFilePath();
|
||||||
refData->pendingAstRequests << request.id();
|
refData->pendingAstRequests << request.id();
|
||||||
q->sendContent(request);
|
q->sendContent(request, SendDocUpdates::Ignore);
|
||||||
|
|
||||||
if (extraOpen)
|
if (extraOpen)
|
||||||
q->closeExtraFile(it.key().toFilePath());
|
q->closeExtraFile(it.key().toFilePath());
|
||||||
@@ -1194,7 +1196,7 @@ void ClangdClient::followSymbol(
|
|||||||
if (d->followSymbolData->defLink.hasValidTarget())
|
if (d->followSymbolData->defLink.hasValidTarget())
|
||||||
d->handleGotoDefinitionResult();
|
d->handleGotoDefinitionResult();
|
||||||
});
|
});
|
||||||
sendContent(astRequest);
|
sendContent(astRequest, SendDocUpdates::Ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangdClient::switchDeclDef(TextEditor::TextDocument *document, const QTextCursor &cursor,
|
void ClangdClient::switchDeclDef(TextEditor::TextDocument *document, const QTextCursor &cursor,
|
||||||
@@ -1228,7 +1230,7 @@ void ClangdClient::switchDeclDef(TextEditor::TextDocument *document, const QText
|
|||||||
d->handleDeclDefSwitchReplies();
|
d->handleDeclDefSwitchReplies();
|
||||||
|
|
||||||
});
|
});
|
||||||
sendContent(astRequest);
|
sendContent(astRequest, SendDocUpdates::Ignore);
|
||||||
documentSymbolCache()->requestSymbols(d->switchDeclDefData->uri);
|
documentSymbolCache()->requestSymbols(d->switchDeclDefData->uri);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1315,8 +1317,7 @@ void ClangdClient::findLocalUsages(TextEditor::TextDocument *document, const QTe
|
|||||||
d->localRefsData.reset();
|
d->localRefsData.reset();
|
||||||
});
|
});
|
||||||
qCDebug(clangdLog) << "sending ast request for link";
|
qCDebug(clangdLog) << "sending ast request for link";
|
||||||
sendContent(astRequest);
|
sendContent(astRequest, SendDocUpdates::Ignore);
|
||||||
|
|
||||||
};
|
};
|
||||||
symbolSupport().findLinkAt(document, cursor, std::move(gotoDefCallback), true);
|
symbolSupport().findLinkAt(document, cursor, std::move(gotoDefCallback), true);
|
||||||
}
|
}
|
||||||
@@ -1401,7 +1402,7 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
|
|||||||
// with mainOverload = true, such information would get ignored anyway.
|
// with mainOverload = true, such information would get ignored anyway.
|
||||||
d->setHelpItemForTooltip(id, fqn, HelpItem::Function, isFunction ? type : "()");
|
d->setHelpItemForTooltip(id, fqn, HelpItem::Function, isFunction ? type : "()");
|
||||||
});
|
});
|
||||||
sendContent(symReq);
|
sendContent(symReq, SendDocUpdates::Ignore);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((node.role() == "expression" && node.kind() == "DeclRef")
|
if ((node.role() == "expression" && node.kind() == "DeclRef")
|
||||||
@@ -1466,7 +1467,7 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
|
|||||||
}
|
}
|
||||||
d->setHelpItemForTooltip(id);
|
d->setHelpItemForTooltip(id);
|
||||||
});
|
});
|
||||||
sendContent(req);
|
sendContent(req, SendDocUpdates::Ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangdClient::Private::handleGotoDefinitionResult()
|
void ClangdClient::Private::handleGotoDefinitionResult()
|
||||||
@@ -1507,7 +1508,7 @@ void ClangdClient::Private::sendGotoImplementationRequest(const Utils::Link &lin
|
|||||||
followSymbolData->pendingGotoImplRequests.removeOne(reqId);
|
followSymbolData->pendingGotoImplRequests.removeOne(reqId);
|
||||||
handleGotoImplementationResult(response);
|
handleGotoImplementationResult(response);
|
||||||
});
|
});
|
||||||
q->sendContent(req);
|
q->sendContent(req, SendDocUpdates::Ignore);
|
||||||
followSymbolData->pendingGotoImplRequests << req.id();
|
followSymbolData->pendingGotoImplRequests << req.id();
|
||||||
qCDebug(clangdLog) << "sending go to implementation request" << link.targetLine;
|
qCDebug(clangdLog) << "sending go to implementation request" << link.targetLine;
|
||||||
}
|
}
|
||||||
@@ -1594,7 +1595,7 @@ void ClangdClient::Private::handleGotoImplementationResult(
|
|||||||
});
|
});
|
||||||
followSymbolData->pendingSymbolInfoRequests << symReq.id();
|
followSymbolData->pendingSymbolInfoRequests << symReq.id();
|
||||||
qCDebug(clangdLog) << "sending symbol info request";
|
qCDebug(clangdLog) << "sending symbol info request";
|
||||||
q->sendContent(symReq);
|
q->sendContent(symReq, SendDocUpdates::Ignore);
|
||||||
|
|
||||||
if (link == followSymbolData->defLink)
|
if (link == followSymbolData->defLink)
|
||||||
continue;
|
continue;
|
||||||
@@ -1628,7 +1629,7 @@ void ClangdClient::Private::handleGotoImplementationResult(
|
|||||||
followSymbolData->pendingGotoDefRequests << defReq.id();
|
followSymbolData->pendingGotoDefRequests << defReq.id();
|
||||||
qCDebug(clangdLog) << "sending additional go to definition request"
|
qCDebug(clangdLog) << "sending additional go to definition request"
|
||||||
<< link.targetFilePath << link.targetLine;
|
<< link.targetFilePath << link.targetLine;
|
||||||
q->sendContent(defReq);
|
q->sendContent(defReq, SendDocUpdates::Ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
const DocumentUri defLinkUri
|
const DocumentUri defLinkUri
|
||||||
@@ -1651,7 +1652,7 @@ void ClangdClient::Private::handleGotoImplementationResult(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
qCDebug(clangdLog) << "sending ast request for def link";
|
qCDebug(clangdLog) << "sending ast request for def link";
|
||||||
q->sendContent(astRequest);
|
q->sendContent(astRequest, SendDocUpdates::Ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangdClient::Private::handleDocumentInfoResults()
|
void ClangdClient::Private::handleDocumentInfoResults()
|
||||||
@@ -2385,7 +2386,7 @@ void ClangdClient::Private::handleSemanticTokens(TextEditor::TextDocument *doc,
|
|||||||
it->second.setHighlightingRunner(runner);
|
it->second.setHighlightingRunner(runner);
|
||||||
it->second.run();
|
it->second.run();
|
||||||
});
|
});
|
||||||
q->sendContent(astReq);
|
q->sendContent(astReq, SendDocUpdates::Ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangdClient::VirtualFunctionAssistProcessor::cancel()
|
void ClangdClient::VirtualFunctionAssistProcessor::cancel()
|
||||||
|
@@ -65,11 +65,11 @@ public:
|
|||||||
|
|
||||||
static void clearTaskHubIssues();
|
static void clearTaskHubIssues();
|
||||||
void generateTaskHubIssues();
|
void generateTaskHubIssues();
|
||||||
|
void cleanMarks();
|
||||||
|
|
||||||
static void addTask(const ClangBackEnd::DiagnosticContainer &diagnostic, bool isChild = false);
|
static void addTask(const ClangBackEnd::DiagnosticContainer &diagnostic, bool isChild = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void cleanMarks();
|
|
||||||
QString filePath() const;
|
QString filePath() const;
|
||||||
void filterDiagnostics(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics);
|
void filterDiagnostics(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics);
|
||||||
void generateEditorSelections();
|
void generateEditorSelections();
|
||||||
|
@@ -251,6 +251,14 @@ void ClangEditorDocumentProcessor::generateTaskHubIssues()
|
|||||||
m_diagnosticManager.generateTaskHubIssues();
|
m_diagnosticManager.generateTaskHubIssues();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClangEditorDocumentProcessor::clearTextMarks(const Utils::FilePath &filePath)
|
||||||
|
{
|
||||||
|
if (ClangEditorDocumentProcessor * const proc = get(filePath.toString())) {
|
||||||
|
proc->m_diagnosticManager.cleanMarks();
|
||||||
|
emit proc->codeWarningsUpdated(proc->revision(), {}, {}, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ClangEditorDocumentProcessor::updateHighlighting(
|
void ClangEditorDocumentProcessor::updateHighlighting(
|
||||||
const QVector<ClangBackEnd::TokenInfoContainer> &tokenInfos,
|
const QVector<ClangBackEnd::TokenInfoContainer> &tokenInfos,
|
||||||
const QVector<ClangBackEnd::SourceRangeContainer> &skippedPreprocessorRanges,
|
const QVector<ClangBackEnd::SourceRangeContainer> &skippedPreprocessorRanges,
|
||||||
|
@@ -108,6 +108,8 @@ public:
|
|||||||
static void clearTaskHubIssues();
|
static void clearTaskHubIssues();
|
||||||
void generateTaskHubIssues();
|
void generateTaskHubIssues();
|
||||||
|
|
||||||
|
static void clearTextMarks(const Utils::FilePath &filePath);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static ClangEditorDocumentProcessor *get(const QString &filePath);
|
static ClangEditorDocumentProcessor *get(const QString &filePath);
|
||||||
|
|
||||||
|
@@ -316,6 +316,7 @@ void ClangModelManagerSupport::updateLanguageClient(ProjectExplorer::Project *pr
|
|||||||
if (!project->isKnownFile(entry->fileName()))
|
if (!project->isKnownFile(entry->fileName()))
|
||||||
continue;
|
continue;
|
||||||
client->openDocument(textDocument);
|
client->openDocument(textDocument);
|
||||||
|
ClangEditorDocumentProcessor::clearTextMarks(textDocument->filePath());
|
||||||
hasDocuments = true;
|
hasDocuments = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -500,7 +500,7 @@ QList<BaseQtVersion *> KitDetectorPrivate::autoDetectQtVersions() const
|
|||||||
emit q->logOutput('\n' + tr("Searching Qt installations..."));
|
emit q->logOutput('\n' + tr("Searching Qt installations..."));
|
||||||
for (const QString &candidate : candidates) {
|
for (const QString &candidate : candidates) {
|
||||||
emit q->logOutput(tr("Searching for %1 executable...").arg(candidate));
|
emit q->logOutput(tr("Searching for %1 executable...").arg(candidate));
|
||||||
const FilePath qmake = m_device->searchInPath(FilePath::fromString(candidate));
|
const FilePath qmake = m_device->searchExecutableInPath(candidate);
|
||||||
if (qmake.isEmpty())
|
if (qmake.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
BaseQtVersion *qtVersion = QtVersionFactory::createQtVersionFromQMakePath(qmake, false, m_sharedId, &error);
|
BaseQtVersion *qtVersion = QtVersionFactory::createQtVersionFromQMakePath(qmake, false, m_sharedId, &error);
|
||||||
@@ -546,8 +546,8 @@ void KitDetectorPrivate::autoDetectCMake()
|
|||||||
QString error;
|
QString error;
|
||||||
const QStringList candidates = {"cmake"};
|
const QStringList candidates = {"cmake"};
|
||||||
for (const QString &candidate : candidates) {
|
for (const QString &candidate : candidates) {
|
||||||
const FilePath cmake = m_device->searchInPath(FilePath::fromString(candidate));
|
const FilePath cmake = m_device->searchExecutableInPath(candidate);
|
||||||
if (cmake.isExecutableFile()) {
|
if (!cmake.isEmpty()) {
|
||||||
emit q->logOutput(tr("Found CMake binary: %1").arg(cmake.toUserOutput()));
|
emit q->logOutput(tr("Found CMake binary: %1").arg(cmake.toUserOutput()));
|
||||||
const bool res = QMetaObject::invokeMethod(cmakeManager,
|
const bool res = QMetaObject::invokeMethod(cmakeManager,
|
||||||
"registerCMakeByPath",
|
"registerCMakeByPath",
|
||||||
@@ -1046,35 +1046,6 @@ FilePath DockerDevice::symLinkTarget(const FilePath &filePath) const
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePath DockerDevice::searchInPath(const FilePath &filePath, const FilePaths &additionalDirs) const
|
|
||||||
{
|
|
||||||
QTC_ASSERT(handlesFile(filePath), return {});
|
|
||||||
tryCreateLocalFileAccess();
|
|
||||||
|
|
||||||
const QString path = filePath.path();
|
|
||||||
|
|
||||||
// FIXME: Check whether local search via deviceEnvironment/PATH is faster?
|
|
||||||
CommandLine dcmd{"docker", {"exec", d->m_container, "which", path}};
|
|
||||||
QtcProcess proc;
|
|
||||||
proc.setCommand(dcmd);
|
|
||||||
proc.start();
|
|
||||||
proc.waitForFinished();
|
|
||||||
|
|
||||||
LOG("Run sync:" << dcmd.toUserOutput() << " result: " << proc.exitCode());
|
|
||||||
if (proc.exitCode() == 0) {
|
|
||||||
const QString output = proc.stdOut().trimmed();
|
|
||||||
return mapToGlobalPath(FilePath::fromString(output));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const FilePath &dir : additionalDirs) {
|
|
||||||
const FilePath candidate = dir / filePath.path();
|
|
||||||
if (candidate.exists())
|
|
||||||
return candidate;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
FilePaths DockerDevice::directoryEntries(const FilePath &filePath,
|
FilePaths DockerDevice::directoryEntries(const FilePath &filePath,
|
||||||
const QStringList &nameFilters,
|
const QStringList &nameFilters,
|
||||||
QDir::Filters filters,
|
QDir::Filters filters,
|
||||||
|
@@ -88,8 +88,6 @@ public:
|
|||||||
bool removeRecursively(const Utils::FilePath &filePath) const override;
|
bool removeRecursively(const Utils::FilePath &filePath) const override;
|
||||||
bool copyFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const override;
|
bool copyFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const override;
|
||||||
bool renameFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const override;
|
bool renameFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const override;
|
||||||
Utils::FilePath searchInPath(const Utils::FilePath &filePath,
|
|
||||||
const Utils::FilePaths &additionalDirs) const override;
|
|
||||||
Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override;
|
Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override;
|
||||||
QList<Utils::FilePath> directoryEntries(const Utils::FilePath &filePath,
|
QList<Utils::FilePath> directoryEntries(const Utils::FilePath &filePath,
|
||||||
const QStringList &nameFilters,
|
const QStringList &nameFilters,
|
||||||
|
@@ -400,10 +400,11 @@ void Client::openDocument(TextEditor::TextDocument *document)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::sendContent(const IContent &content)
|
void Client::sendContent(const IContent &content, SendDocUpdates sendUpdates)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_clientInterface, return);
|
QTC_ASSERT(m_clientInterface, return);
|
||||||
QTC_ASSERT(m_state == Initialized, return);
|
QTC_ASSERT(m_state == Initialized, return);
|
||||||
|
if (sendUpdates == SendDocUpdates::Send)
|
||||||
sendPostponedDocumentUpdates();
|
sendPostponedDocumentUpdates();
|
||||||
if (Utils::optional<ResponseHandler> responseHandler = content.responseHandler())
|
if (Utils::optional<ResponseHandler> responseHandler = content.responseHandler())
|
||||||
m_responseHandlers[responseHandler->id] = responseHandler->callback;
|
m_responseHandlers[responseHandler->id] = responseHandler->callback;
|
||||||
@@ -418,7 +419,7 @@ void Client::sendContent(const IContent &content)
|
|||||||
void Client::cancelRequest(const MessageId &id)
|
void Client::cancelRequest(const MessageId &id)
|
||||||
{
|
{
|
||||||
m_responseHandlers.remove(id);
|
m_responseHandlers.remove(id);
|
||||||
sendContent(CancelRequest(CancelParameter(id)));
|
sendContent(CancelRequest(CancelParameter(id)), SendDocUpdates::Ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::closeDocument(TextEditor::TextDocument *document)
|
void Client::closeDocument(TextEditor::TextDocument *document)
|
||||||
|
@@ -92,7 +92,11 @@ public:
|
|||||||
Utils::Id id() const { return m_id; }
|
Utils::Id id() const { return m_id; }
|
||||||
void setName(const QString &name) { m_displayName = name; }
|
void setName(const QString &name) { m_displayName = name; }
|
||||||
QString name() const;
|
QString name() const;
|
||||||
void sendContent(const LanguageServerProtocol::IContent &content);
|
|
||||||
|
enum class SendDocUpdates { Send, Ignore };
|
||||||
|
void sendContent(const LanguageServerProtocol::IContent &content,
|
||||||
|
SendDocUpdates sendUpdates = SendDocUpdates::Send);
|
||||||
|
|
||||||
void cancelRequest(const LanguageServerProtocol::MessageId &id);
|
void cancelRequest(const LanguageServerProtocol::MessageId &id);
|
||||||
|
|
||||||
// server state handling
|
// server state handling
|
||||||
|
@@ -283,7 +283,7 @@ private:
|
|||||||
void updateModel(const DocumentUri &resultUri, const DocumentSymbolsResult &result);
|
void updateModel(const DocumentUri &resultUri, const DocumentSymbolsResult &result);
|
||||||
void updateEntry();
|
void updateEntry();
|
||||||
void activateEntry();
|
void activateEntry();
|
||||||
void requestSymbols();
|
void documentUpdated(TextEditor::TextDocument *document);
|
||||||
|
|
||||||
LanguageClientOutlineModel m_model;
|
LanguageClientOutlineModel m_model;
|
||||||
QPointer<Client> m_client;
|
QPointer<Client> m_client;
|
||||||
@@ -318,13 +318,12 @@ OutlineComboBox::OutlineComboBox(Client *client, TextEditor::BaseTextEditor *edi
|
|||||||
|
|
||||||
connect(client->documentSymbolCache(), &DocumentSymbolCache::gotSymbols,
|
connect(client->documentSymbolCache(), &DocumentSymbolCache::gotSymbols,
|
||||||
this, &OutlineComboBox::updateModel);
|
this, &OutlineComboBox::updateModel);
|
||||||
connect(editor->textDocument(), &TextEditor::TextDocument::contentsChanged,
|
connect(client, &Client::documentUpdated, this, &OutlineComboBox::documentUpdated);
|
||||||
this, &OutlineComboBox::requestSymbols);
|
|
||||||
connect(m_editorWidget, &TextEditor::TextEditorWidget::cursorPositionChanged,
|
connect(m_editorWidget, &TextEditor::TextEditorWidget::cursorPositionChanged,
|
||||||
this, &OutlineComboBox::updateEntry);
|
this, &OutlineComboBox::updateEntry);
|
||||||
connect(this, QOverload<int>::of(&QComboBox::activated), this, &OutlineComboBox::activateEntry);
|
connect(this, QOverload<int>::of(&QComboBox::activated), this, &OutlineComboBox::activateEntry);
|
||||||
|
|
||||||
requestSymbols();
|
documentUpdated(editor->textDocument());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutlineComboBox::updateModel(const DocumentUri &resultUri, const DocumentSymbolsResult &result)
|
void OutlineComboBox::updateModel(const DocumentUri &resultUri, const DocumentSymbolsResult &result)
|
||||||
@@ -365,9 +364,9 @@ void OutlineComboBox::activateEntry()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutlineComboBox::requestSymbols()
|
void OutlineComboBox::documentUpdated(TextEditor::TextDocument *document)
|
||||||
{
|
{
|
||||||
if (m_client)
|
if (document == m_editorWidget->textDocument())
|
||||||
m_client->documentSymbolCache()->requestSymbols(m_uri);
|
m_client->documentSymbolCache()->requestSymbols(m_uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -371,12 +371,12 @@ SemanticRequestTypes SemanticTokenSupport::supportedSemanticRequests(TextDocumen
|
|||||||
void SemanticTokenSupport::handleSemanticTokens(const Utils::FilePath &filePath,
|
void SemanticTokenSupport::handleSemanticTokens(const Utils::FilePath &filePath,
|
||||||
const SemanticTokensResult &result)
|
const SemanticTokensResult &result)
|
||||||
{
|
{
|
||||||
if (auto tokens = Utils::get_if<SemanticTokens>(&result))
|
if (auto tokens = Utils::get_if<SemanticTokens>(&result)) {
|
||||||
m_tokens[filePath] = *tokens;
|
m_tokens[filePath] = *tokens;
|
||||||
else
|
|
||||||
m_tokens.remove(filePath);
|
|
||||||
highlight(filePath);
|
highlight(filePath);
|
||||||
}
|
}
|
||||||
|
m_tokens.remove(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
void SemanticTokenSupport::handleSemanticTokensDelta(
|
void SemanticTokenSupport::handleSemanticTokensDelta(
|
||||||
const Utils::FilePath &filePath, const LanguageServerProtocol::SemanticTokensDeltaResult &result)
|
const Utils::FilePath &filePath, const LanguageServerProtocol::SemanticTokensDeltaResult &result)
|
||||||
@@ -427,6 +427,7 @@ void SemanticTokenSupport::handleSemanticTokensDelta(
|
|||||||
tokens.setResultId(tokensDelta->resultId());
|
tokens.setResultId(tokensDelta->resultId());
|
||||||
} else {
|
} else {
|
||||||
m_tokens.remove(filePath);
|
m_tokens.remove(filePath);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
highlight(filePath);
|
highlight(filePath);
|
||||||
}
|
}
|
||||||
|
@@ -58,7 +58,7 @@ QList<ToolChain *> NimToolChainFactory::autoDetect(const QList<ToolChain *> &alr
|
|||||||
QList<ToolChain *> result;
|
QList<ToolChain *> result;
|
||||||
|
|
||||||
IDevice::ConstPtr dev = device ? device : DeviceManager::defaultDesktopDevice();
|
IDevice::ConstPtr dev = device ? device : DeviceManager::defaultDesktopDevice();
|
||||||
const FilePath compilerPath = dev->searchInPath(FilePath::fromString("nim"));
|
const FilePath compilerPath = dev->searchExecutableInPath("nim");
|
||||||
if (compilerPath.isEmpty())
|
if (compilerPath.isEmpty())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
@@ -1168,11 +1168,8 @@ Abis Abi::abisOfBinary(const Utils::FilePath &path)
|
|||||||
&& getUint8(data, 6) == '>' && getUint8(data, 7) == 0x0a) {
|
&& getUint8(data, 6) == '>' && getUint8(data, 7) == 0x0a) {
|
||||||
// We got an ar file: possibly a static lib for ELF, PE or Mach-O
|
// We got an ar file: possibly a static lib for ELF, PE or Mach-O
|
||||||
|
|
||||||
// FIXME: Implement remote
|
|
||||||
QTC_ASSERT(!path.needsDevice(), return tmp);
|
|
||||||
QFile f(path.toString());
|
QFile f(path.toString());
|
||||||
if (!f.open(QFile::ReadOnly))
|
const bool canRead = f.open(QFile::ReadOnly);
|
||||||
return tmp;
|
|
||||||
|
|
||||||
data = data.mid(8); // Cut of ar file magic
|
data = data.mid(8); // Cut of ar file magic
|
||||||
quint64 offset = 8;
|
quint64 offset = 8;
|
||||||
@@ -1199,6 +1196,11 @@ Abis Abi::abisOfBinary(const Utils::FilePath &path)
|
|||||||
if (!tmp.isEmpty() && tmp.at(0).binaryFormat() != MachOFormat)
|
if (!tmp.isEmpty() && tmp.at(0).binaryFormat() != MachOFormat)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (!canRead) {
|
||||||
|
// FIXME: Implement remote
|
||||||
|
QTC_ASSERT(!path.needsDevice(), return {});
|
||||||
|
}
|
||||||
|
|
||||||
offset += (offset % 2); // ar is 2 byte aligned
|
offset += (offset % 2); // ar is 2 byte aligned
|
||||||
f.seek(offset);
|
f.seek(offset);
|
||||||
data = f.read(1024);
|
data = f.read(1024);
|
||||||
|
@@ -43,6 +43,7 @@
|
|||||||
#include <utils/url.h>
|
#include <utils/url.h>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
using namespace ProjectExplorer::Constants;
|
using namespace ProjectExplorer::Constants;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
@@ -194,4 +195,101 @@ Environment DesktopDevice::systemEnvironment() const
|
|||||||
return Environment::systemEnvironment();
|
return Environment::systemEnvironment();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DesktopDevice::isExecutableFile(const FilePath &filePath) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(handlesFile(filePath), return false);
|
||||||
|
return filePath.isExecutableFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DesktopDevice::isReadableFile(const FilePath &filePath) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(handlesFile(filePath), return false);
|
||||||
|
return filePath.isReadableFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DesktopDevice::isWritableFile(const Utils::FilePath &filePath) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(handlesFile(filePath), return false);
|
||||||
|
return filePath.isWritableFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DesktopDevice::isReadableDirectory(const FilePath &filePath) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(handlesFile(filePath), return false);
|
||||||
|
return filePath.isReadableDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DesktopDevice::isWritableDirectory(const FilePath &filePath) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(handlesFile(filePath), return false);
|
||||||
|
return filePath.isWritableDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DesktopDevice::createDirectory(const FilePath &filePath) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(handlesFile(filePath), return false);
|
||||||
|
return filePath.createDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DesktopDevice::exists(const FilePath &filePath) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(handlesFile(filePath), return false);
|
||||||
|
return filePath.exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DesktopDevice::ensureExistingFile(const FilePath &filePath) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(handlesFile(filePath), return false);
|
||||||
|
return filePath.ensureExistingFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DesktopDevice::removeFile(const FilePath &filePath) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(handlesFile(filePath), return false);
|
||||||
|
return filePath.removeFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DesktopDevice::removeRecursively(const FilePath &filePath) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(handlesFile(filePath), return false);
|
||||||
|
return filePath.removeRecursively();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DesktopDevice::copyFile(const FilePath &filePath, const FilePath &target) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(handlesFile(filePath), return false);
|
||||||
|
return filePath.copyFile(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DesktopDevice::renameFile(const FilePath &filePath, const FilePath &target) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(handlesFile(filePath), return false);
|
||||||
|
QTC_ASSERT(handlesFile(target), return false);
|
||||||
|
return filePath.renameFile(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDateTime DesktopDevice::lastModified(const FilePath &filePath) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(handlesFile(filePath), return {});
|
||||||
|
return filePath.lastModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePath DesktopDevice::symLinkTarget(const FilePath &filePath) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(handlesFile(filePath), return {});
|
||||||
|
return filePath.symLinkTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray DesktopDevice::fileContents(const FilePath &filePath, int limit) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(handlesFile(filePath), return {});
|
||||||
|
return filePath.fileContents(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DesktopDevice::writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(handlesFile(filePath), return {});
|
||||||
|
return filePath.writeFileContents(data);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ProjectExplorer
|
} // namespace ProjectExplorer
|
||||||
|
@@ -54,13 +54,29 @@ public:
|
|||||||
DeviceProcessSignalOperation::Ptr signalOperation() const override;
|
DeviceProcessSignalOperation::Ptr signalOperation() const override;
|
||||||
DeviceEnvironmentFetcher::Ptr environmentFetcher() const override;
|
DeviceEnvironmentFetcher::Ptr environmentFetcher() const override;
|
||||||
QUrl toolControlChannel(const ControlChannelHint &) const override;
|
QUrl toolControlChannel(const ControlChannelHint &) const override;
|
||||||
|
|
||||||
bool handlesFile(const Utils::FilePath &filePath) const override;
|
bool handlesFile(const Utils::FilePath &filePath) const override;
|
||||||
QList<Utils::FilePath> directoryEntries(const Utils::FilePath &filePath,
|
QList<Utils::FilePath> directoryEntries(const Utils::FilePath &filePath,
|
||||||
const QStringList &nameFilters,
|
const QStringList &nameFilters,
|
||||||
QDir::Filters filters,
|
QDir::Filters filters,
|
||||||
QDir::SortFlags sort) const override;
|
QDir::SortFlags sort) const override;
|
||||||
Utils::Environment systemEnvironment() const override;
|
Utils::Environment systemEnvironment() const override;
|
||||||
|
bool isExecutableFile(const Utils::FilePath &filePath) const override;
|
||||||
|
bool isReadableFile(const Utils::FilePath &filePath) const override;
|
||||||
|
bool isWritableFile(const Utils::FilePath &filePath) const override;
|
||||||
|
bool isReadableDirectory(const Utils::FilePath &filePath) const override;
|
||||||
|
bool isWritableDirectory(const Utils::FilePath &filePath) const override;
|
||||||
|
bool ensureExistingFile(const Utils::FilePath &filePath) const override;
|
||||||
|
bool createDirectory(const Utils::FilePath &filePath) const override;
|
||||||
|
bool exists(const Utils::FilePath &filePath) const override;
|
||||||
|
bool removeFile(const Utils::FilePath &filePath) const override;
|
||||||
|
bool removeRecursively(const Utils::FilePath &filePath) const override;
|
||||||
|
bool copyFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const override;
|
||||||
|
bool renameFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const override;
|
||||||
|
QDateTime lastModified(const Utils::FilePath &filePath) const override;
|
||||||
|
Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const override;
|
||||||
|
QByteArray fileContents(const Utils::FilePath &filePath, int limit) const override;
|
||||||
|
bool writeFileContents(const Utils::FilePath &filePath, const QByteArray &data) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DesktopDevice();
|
DesktopDevice();
|
||||||
|
@@ -458,10 +458,10 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_unique<DeviceManager
|
|||||||
return device->renameFile(filePath, target);
|
return device->renameFile(filePath, target);
|
||||||
};
|
};
|
||||||
|
|
||||||
deviceHooks.searchInPath = [](const FilePath &filePath, const FilePaths &additionalDirs) {
|
deviceHooks.searchInPath = [](const FilePath &filePath, const FilePaths &dirs) {
|
||||||
auto device = DeviceManager::deviceForPath(filePath);
|
auto device = DeviceManager::deviceForPath(filePath);
|
||||||
QTC_ASSERT(device, return FilePath{});
|
QTC_ASSERT(device, return FilePath{});
|
||||||
return device->searchInPath(filePath, additionalDirs);
|
return device->searchExecutable(filePath.path(), dirs);
|
||||||
};
|
};
|
||||||
|
|
||||||
deviceHooks.symLinkTarget = [](const FilePath &filePath) {
|
deviceHooks.symLinkTarget = [](const FilePath &filePath) {
|
||||||
|
@@ -311,9 +311,26 @@ bool IDevice::renameFile(const FilePath &filePath, const FilePath &target) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePath IDevice::searchInPath(const FilePath &filePath, const FilePaths &additionalDirs) const
|
FilePath IDevice::searchExecutableInPath(const QString &fileName) const
|
||||||
{
|
{
|
||||||
return Environment::systemEnvironment().searchInPath(filePath.path());
|
FilePaths paths;
|
||||||
|
for (const FilePath &path : systemEnvironment().path())
|
||||||
|
paths.append(mapToGlobalPath(path));
|
||||||
|
return searchExecutable(fileName, paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
FilePath IDevice::searchExecutable(const QString &fileName, const FilePaths &dirs) const
|
||||||
|
{
|
||||||
|
for (FilePath dir : dirs) {
|
||||||
|
if (!handlesFile(dir)) // Allow device-local dirs to be used.
|
||||||
|
dir = mapToGlobalPath(dir);
|
||||||
|
QTC_CHECK(handlesFile(dir));
|
||||||
|
const FilePath candidate = dir / fileName;
|
||||||
|
if (isExecutableFile(candidate))
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePath IDevice::symLinkTarget(const FilePath &filePath) const
|
FilePath IDevice::symLinkTarget(const FilePath &filePath) const
|
||||||
|
@@ -249,8 +249,9 @@ public:
|
|||||||
virtual bool removeRecursively(const Utils::FilePath &filePath) const;
|
virtual bool removeRecursively(const Utils::FilePath &filePath) const;
|
||||||
virtual bool copyFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const;
|
virtual bool copyFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const;
|
||||||
virtual bool renameFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const;
|
virtual bool renameFile(const Utils::FilePath &filePath, const Utils::FilePath &target) const;
|
||||||
virtual Utils::FilePath searchInPath(const Utils::FilePath &filePath,
|
virtual Utils::FilePath searchExecutableInPath(const QString &fileName) const;
|
||||||
const QList<Utils::FilePath> &additionalDirs = {}) const;
|
virtual Utils::FilePath searchExecutable(const QString &fileName,
|
||||||
|
const QList<Utils::FilePath> &dirs) const;
|
||||||
virtual Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const;
|
virtual Utils::FilePath symLinkTarget(const Utils::FilePath &filePath) const;
|
||||||
virtual QList<Utils::FilePath> directoryEntries(const Utils::FilePath &filePath,
|
virtual QList<Utils::FilePath> directoryEntries(const Utils::FilePath &filePath,
|
||||||
const QStringList &nameFilters,
|
const QStringList &nameFilters,
|
||||||
|
@@ -284,8 +284,11 @@ QmakeBuildSystem::~QmakeBuildSystem()
|
|||||||
delete m_qmakeVfs;
|
delete m_qmakeVfs;
|
||||||
m_qmakeVfs = nullptr;
|
m_qmakeVfs = nullptr;
|
||||||
|
|
||||||
m_asyncUpdateFutureInterface.reportCanceled();
|
if (m_asyncUpdateFutureInterface) {
|
||||||
m_asyncUpdateFutureInterface.reportFinished();
|
m_asyncUpdateFutureInterface->reportCanceled();
|
||||||
|
m_asyncUpdateFutureInterface->reportFinished();
|
||||||
|
m_asyncUpdateFutureInterface.reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmakeBuildSystem::updateCodeModels()
|
void QmakeBuildSystem::updateCodeModels()
|
||||||
@@ -591,8 +594,9 @@ void QmakeBuildSystem::incrementPendingEvaluateFutures()
|
|||||||
}
|
}
|
||||||
++m_pendingEvaluateFuturesCount;
|
++m_pendingEvaluateFuturesCount;
|
||||||
TRACE("pending inc to: " << m_pendingEvaluateFuturesCount);
|
TRACE("pending inc to: " << m_pendingEvaluateFuturesCount);
|
||||||
m_asyncUpdateFutureInterface.setProgressRange(m_asyncUpdateFutureInterface.progressMinimum(),
|
m_asyncUpdateFutureInterface->setProgressRange(m_asyncUpdateFutureInterface->progressMinimum(),
|
||||||
m_asyncUpdateFutureInterface.progressMaximum() + 1);
|
m_asyncUpdateFutureInterface->progressMaximum()
|
||||||
|
+ 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmakeBuildSystem::decrementPendingEvaluateFutures()
|
void QmakeBuildSystem::decrementPendingEvaluateFutures()
|
||||||
@@ -605,15 +609,17 @@ void QmakeBuildSystem::decrementPendingEvaluateFutures()
|
|||||||
return; // We are closing the project!
|
return; // We are closing the project!
|
||||||
}
|
}
|
||||||
|
|
||||||
m_asyncUpdateFutureInterface.setProgressValue(m_asyncUpdateFutureInterface.progressValue() + 1);
|
m_asyncUpdateFutureInterface->setProgressValue(m_asyncUpdateFutureInterface->progressValue()
|
||||||
|
+ 1);
|
||||||
if (m_pendingEvaluateFuturesCount == 0) {
|
if (m_pendingEvaluateFuturesCount == 0) {
|
||||||
// We are done!
|
// We are done!
|
||||||
setRootProjectNode(QmakeNodeTreeBuilder::buildTree(this));
|
setRootProjectNode(QmakeNodeTreeBuilder::buildTree(this));
|
||||||
|
|
||||||
if (!m_rootProFile->validParse())
|
if (!m_rootProFile->validParse())
|
||||||
m_asyncUpdateFutureInterface.reportCanceled();
|
m_asyncUpdateFutureInterface->reportCanceled();
|
||||||
|
|
||||||
m_asyncUpdateFutureInterface.reportFinished();
|
m_asyncUpdateFutureInterface->reportFinished();
|
||||||
|
m_asyncUpdateFutureInterface.reset();
|
||||||
m_cancelEvaluate = false;
|
m_cancelEvaluate = false;
|
||||||
|
|
||||||
// TODO clear the profile cache ?
|
// TODO clear the profile cache ?
|
||||||
@@ -659,12 +665,13 @@ void QmakeBuildSystem::asyncUpdate()
|
|||||||
m_qmakeVfs->invalidateCache();
|
m_qmakeVfs->invalidateCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_asyncUpdateFutureInterface.setProgressRange(0, 0);
|
m_asyncUpdateFutureInterface.reset(new QFutureInterface<void>);
|
||||||
Core::ProgressManager::addTask(m_asyncUpdateFutureInterface.future(),
|
m_asyncUpdateFutureInterface->setProgressRange(0, 0);
|
||||||
|
Core::ProgressManager::addTask(m_asyncUpdateFutureInterface->future(),
|
||||||
tr("Reading Project \"%1\"").arg(project()->displayName()),
|
tr("Reading Project \"%1\"").arg(project()->displayName()),
|
||||||
Constants::PROFILE_EVALUATE);
|
Constants::PROFILE_EVALUATE);
|
||||||
|
|
||||||
m_asyncUpdateFutureInterface.reportStarted();
|
m_asyncUpdateFutureInterface->reportStarted();
|
||||||
const auto watcher = new QFutureWatcher<void>(this);
|
const auto watcher = new QFutureWatcher<void>(this);
|
||||||
connect(watcher, &QFutureWatcher<void>::canceled, this, [this, watcher] {
|
connect(watcher, &QFutureWatcher<void>::canceled, this, [this, watcher] {
|
||||||
if (!m_qmakeGlobals)
|
if (!m_qmakeGlobals)
|
||||||
@@ -676,7 +683,7 @@ void QmakeBuildSystem::asyncUpdate()
|
|||||||
watcher->disconnect();
|
watcher->disconnect();
|
||||||
watcher->deleteLater();
|
watcher->deleteLater();
|
||||||
});
|
});
|
||||||
watcher->setFuture(m_asyncUpdateFutureInterface.future());
|
watcher->setFuture(m_asyncUpdateFutureInterface->future());
|
||||||
|
|
||||||
const Kit *const k = kit();
|
const Kit *const k = kit();
|
||||||
QtSupport::BaseQtVersion *const qtVersion = QtSupport::QtKitAspect::qtVersion(k);
|
QtSupport::BaseQtVersion *const qtVersion = QtSupport::QtKitAspect::qtVersion(k);
|
||||||
@@ -687,8 +694,9 @@ void QmakeBuildSystem::asyncUpdate()
|
|||||||
.arg(project()->displayName(), k->displayName())
|
.arg(project()->displayName(), k->displayName())
|
||||||
: tr("Cannot parse project \"%1\": No kit selected.").arg(project()->displayName());
|
: tr("Cannot parse project \"%1\": No kit selected.").arg(project()->displayName());
|
||||||
proFileParseError(errorMessage, project()->projectFilePath());
|
proFileParseError(errorMessage, project()->projectFilePath());
|
||||||
m_asyncUpdateFutureInterface.reportCanceled();
|
m_asyncUpdateFutureInterface->reportCanceled();
|
||||||
m_asyncUpdateFutureInterface.reportFinished();
|
m_asyncUpdateFutureInterface->reportFinished();
|
||||||
|
m_asyncUpdateFutureInterface.reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -200,7 +200,7 @@ private:
|
|||||||
|
|
||||||
QString m_qmakeSysroot;
|
QString m_qmakeSysroot;
|
||||||
|
|
||||||
QFutureInterface<void> m_asyncUpdateFutureInterface;
|
std::unique_ptr<QFutureInterface<void>> m_asyncUpdateFutureInterface;
|
||||||
int m_pendingEvaluateFuturesCount = 0;
|
int m_pendingEvaluateFuturesCount = 0;
|
||||||
AsyncUpdateState m_asyncUpdateState = Base;
|
AsyncUpdateState m_asyncUpdateState = Base;
|
||||||
bool m_cancelEvaluate = false;
|
bool m_cancelEvaluate = false;
|
||||||
|
@@ -1007,20 +1007,32 @@ void DesignerActionManager::createDefaultDesignerActions()
|
|||||||
&selectionNotEmptyAndHasXorYProperty));
|
&selectionNotEmptyAndHasXorYProperty));
|
||||||
|
|
||||||
const QString fontName = "qtds_propertyIconFont.ttf";
|
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||||
const QColor iconColorNormal(Theme::getColor(Theme::IconsBaseColor));
|
const QColor iconColorDefault(Theme::getColor(Theme::IconsBaseColor));
|
||||||
const QIcon pasteIcon = Utils::StyleHelper::getIconFromIconFont(fontName,
|
const QColor iconColorDisabled(Theme::getColor(Theme::IconsDisabledColor));
|
||||||
Theme::getIconUnicode(
|
const QString copyUnicode = Theme::getIconUnicode(Theme::Icon::copyStyle);
|
||||||
Theme::Icon::pasteStyle),
|
const QString pasteUnicode = Theme::getIconUnicode(Theme::Icon::pasteStyle);
|
||||||
28,
|
|
||||||
28,
|
|
||||||
iconColorNormal);
|
|
||||||
|
|
||||||
|
const auto copyDefault = Utils::StyleHelper::IconFontHelper(copyUnicode,
|
||||||
|
iconColorDefault,
|
||||||
|
QSize(28, 28),
|
||||||
|
QIcon::Normal);
|
||||||
|
const auto copyDisabled = Utils::StyleHelper::IconFontHelper(copyUnicode,
|
||||||
|
iconColorDisabled,
|
||||||
|
QSize(28, 28),
|
||||||
|
QIcon::Disabled);
|
||||||
const QIcon copyIcon = Utils::StyleHelper::getIconFromIconFont(fontName,
|
const QIcon copyIcon = Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||||
Theme::getIconUnicode(
|
{copyDefault, copyDisabled});
|
||||||
Theme::Icon::copyStyle),
|
|
||||||
28,
|
const auto pasteDefault = Utils::StyleHelper::IconFontHelper(pasteUnicode,
|
||||||
28,
|
iconColorDefault,
|
||||||
iconColorNormal);
|
QSize(28, 28),
|
||||||
|
QIcon::Normal);
|
||||||
|
const auto pasteDisabled = Utils::StyleHelper::IconFontHelper(pasteUnicode,
|
||||||
|
iconColorDisabled,
|
||||||
|
QSize(28, 28),
|
||||||
|
QIcon::Disabled);
|
||||||
|
const QIcon pasteIcon = Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||||
|
{pasteDefault, pasteDisabled});
|
||||||
|
|
||||||
addDesignerAction(new ModelNodeAction(copyFormatCommandId,
|
addDesignerAction(new ModelNodeAction(copyFormatCommandId,
|
||||||
copyFormatDisplayName,
|
copyFormatDisplayName,
|
||||||
|
@@ -43,35 +43,36 @@ using namespace Utils;
|
|||||||
namespace WebAssembly {
|
namespace WebAssembly {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
using EmSdkEnvCache = QCache<QString, QByteArray>;
|
using EmSdkEnvCache = QCache<QString, QString>;
|
||||||
Q_GLOBAL_STATIC_WITH_ARGS(EmSdkEnvCache, emSdkEnvCache, (10))
|
Q_GLOBAL_STATIC_WITH_ARGS(EmSdkEnvCache, emSdkEnvCache, (10))
|
||||||
using EmSdkVersionCache = QCache<QString, QVersionNumber>;
|
using EmSdkVersionCache = QCache<QString, QVersionNumber>;
|
||||||
Q_GLOBAL_STATIC_WITH_ARGS(EmSdkVersionCache, emSdkVersionCache, (10))
|
Q_GLOBAL_STATIC_WITH_ARGS(EmSdkVersionCache, emSdkVersionCache, (10))
|
||||||
|
|
||||||
static QByteArray emSdkEnvOutput(const FilePath &sdkRoot)
|
static QString emSdkEnvOutput(const FilePath &sdkRoot)
|
||||||
{
|
{
|
||||||
const QString cacheKey = sdkRoot.toString();
|
const QString cacheKey = sdkRoot.toString();
|
||||||
|
const bool isWindows = sdkRoot.osType() == OsTypeWindows;
|
||||||
if (!emSdkEnvCache()->contains(cacheKey)) {
|
if (!emSdkEnvCache()->contains(cacheKey)) {
|
||||||
const QString scriptFile = sdkRoot.pathAppended(QLatin1String("emsdk_env") +
|
const QString scriptFile = sdkRoot.pathAppended(QLatin1String("emsdk_env") +
|
||||||
(HostOsInfo::isWindowsHost() ? ".bat" : ".sh")).toString();
|
(isWindows ? ".bat" : ".sh")).path();
|
||||||
QtcProcess emSdkEnv;
|
QtcProcess emSdkEnv;
|
||||||
if (HostOsInfo::isWindowsHost()) {
|
if (isWindows) {
|
||||||
emSdkEnv.setCommand(CommandLine(scriptFile));
|
emSdkEnv.setCommand(CommandLine(scriptFile));
|
||||||
} else {
|
} else {
|
||||||
// File needs to be source'd, not executed.
|
// File needs to be source'd, not executed.
|
||||||
emSdkEnv.setCommand({"bash", {"-c", ". " + scriptFile}});
|
emSdkEnv.setCommand({FilePath::fromString("bash").onDevice(sdkRoot),
|
||||||
|
{"-c", ". " + scriptFile}});
|
||||||
}
|
}
|
||||||
emSdkEnv.start();
|
emSdkEnv.runBlocking();
|
||||||
if (!emSdkEnv.waitForFinished())
|
const QString output = emSdkEnv.allOutput();
|
||||||
return {};
|
emSdkEnvCache()->insert(cacheKey, new QString(output));
|
||||||
emSdkEnvCache()->insert(cacheKey, new QByteArray(emSdkEnv.readAllStandardError()));
|
|
||||||
}
|
}
|
||||||
return *emSdkEnvCache()->object(cacheKey);
|
return *emSdkEnvCache()->object(cacheKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parseEmSdkEnvOutputAndAddToEnv(const QByteArray &output, Environment &env)
|
static void parseEmSdkEnvOutputAndAddToEnv(const QString &output, Environment &env)
|
||||||
{
|
{
|
||||||
const QStringList lines = QString::fromLocal8Bit(output).split('\n');
|
const QStringList lines = output.split('\n');
|
||||||
|
|
||||||
for (const QString &line : lines) {
|
for (const QString &line : lines) {
|
||||||
const QStringList prependParts = line.trimmed().split(" += ");
|
const QStringList prependParts = line.trimmed().split(" += ");
|
||||||
@@ -104,18 +105,17 @@ QVersionNumber WebAssemblyEmSdk::version(const FilePath &sdkRoot)
|
|||||||
return {};
|
return {};
|
||||||
const QString cacheKey = sdkRoot.toString();
|
const QString cacheKey = sdkRoot.toString();
|
||||||
if (!emSdkVersionCache()->contains(cacheKey)) {
|
if (!emSdkVersionCache()->contains(cacheKey)) {
|
||||||
Environment env = Environment::systemEnvironment();
|
Environment env;
|
||||||
WebAssemblyEmSdk::addToEnvironment(sdkRoot, env);
|
WebAssemblyEmSdk::addToEnvironment(sdkRoot, env);
|
||||||
const QString scriptFile =
|
QLatin1String scriptFile{sdkRoot.osType() == OsType::OsTypeWindows ? "emcc.bat" : "emcc"};
|
||||||
QLatin1String("emcc") + QLatin1String(HostOsInfo::isWindowsHost() ? ".bat" : "");
|
FilePath script =
|
||||||
const CommandLine command(env.searchInPath(scriptFile), {"-dumpversion"});
|
FilePath::fromString(scriptFile).onDevice(sdkRoot).searchOnDevice(env.path());
|
||||||
|
const CommandLine command(script, {"-dumpversion"});
|
||||||
QtcProcess emcc;
|
QtcProcess emcc;
|
||||||
emcc.setCommand(command);
|
emcc.setCommand(command);
|
||||||
emcc.setEnvironment(env);
|
emcc.setEnvironment(env);
|
||||||
emcc.start();
|
emcc.runBlocking();
|
||||||
if (!emcc.waitForFinished())
|
const QString version = emcc.stdOut();
|
||||||
return {};
|
|
||||||
const QString version = QLatin1String(emcc.readAllStandardOutput());
|
|
||||||
emSdkVersionCache()->insert(cacheKey,
|
emSdkVersionCache()->insert(cacheKey,
|
||||||
new QVersionNumber(QVersionNumber::fromString(version)));
|
new QVersionNumber(QVersionNumber::fromString(version)));
|
||||||
}
|
}
|
||||||
@@ -146,10 +146,31 @@ void WebAssemblyEmSdk::clearCaches()
|
|||||||
// Unit tests:
|
// Unit tests:
|
||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
void WebAssemblyPlugin::testEmSdkEnvParsing()
|
void WebAssemblyPlugin::testEmSdkEnvParsing()
|
||||||
|
{
|
||||||
|
QFETCH(QString, emSdkEnvOutput);
|
||||||
|
QFETCH(int, osType);
|
||||||
|
QFETCH(int, pathCount);
|
||||||
|
QFETCH(QString, emsdk);
|
||||||
|
QFETCH(QString, em_config);
|
||||||
|
|
||||||
|
Environment env{OsType(osType)};
|
||||||
|
parseEmSdkEnvOutputAndAddToEnv(emSdkEnvOutput, env);
|
||||||
|
|
||||||
|
QVERIFY(env.path().count() == pathCount);
|
||||||
|
QCOMPARE(env.value("EMSDK"), emsdk);
|
||||||
|
QCOMPARE(env.value("EM_CONFIG"), em_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebAssemblyPlugin::testEmSdkEnvParsing_data()
|
||||||
{
|
{
|
||||||
// Output of "emsdk_env"
|
// Output of "emsdk_env"
|
||||||
const QByteArray emSdkEnvOutput = HostOsInfo::isWindowsHost() ?
|
QTest::addColumn<QString>("emSdkEnvOutput");
|
||||||
R"(
|
QTest::addColumn<int>("osType");
|
||||||
|
QTest::addColumn<int>("pathCount");
|
||||||
|
QTest::addColumn<QString>("emsdk");
|
||||||
|
QTest::addColumn<QString>("em_config");
|
||||||
|
|
||||||
|
QTest::newRow("windows") << R"(
|
||||||
Adding directories to PATH:
|
Adding directories to PATH:
|
||||||
PATH += C:\Users\user\dev\emsdk
|
PATH += C:\Users\user\dev\emsdk
|
||||||
PATH += C:\Users\user\dev\emsdk\upstream\emscripten
|
PATH += C:\Users\user\dev\emsdk\upstream\emscripten
|
||||||
@@ -165,7 +186,9 @@ EM_CACHE = C:/Users/user/dev/emsdk/upstream/emscripten\cache
|
|||||||
EMSDK_NODE = C:\Users\user\dev\emsdk\node\12.18.1_64bit\bin\node.exe
|
EMSDK_NODE = C:\Users\user\dev\emsdk\node\12.18.1_64bit\bin\node.exe
|
||||||
EMSDK_PYTHON = C:\Users\user\dev\emsdk\python\3.7.4-pywin32_64bit\python.exe
|
EMSDK_PYTHON = C:\Users\user\dev\emsdk\python\3.7.4-pywin32_64bit\python.exe
|
||||||
JAVA_HOME = C:\Users\user\dev\emsdk\java\8.152_64bit
|
JAVA_HOME = C:\Users\user\dev\emsdk\java\8.152_64bit
|
||||||
)" : R"(
|
)" << int(OsTypeWindows) << 5 << "C:/Users/user/dev/emsdk" << "C:\\Users\\user\\dev\\emsdk\\.emscripten";
|
||||||
|
|
||||||
|
QTest::newRow("linux") << R"(
|
||||||
Adding directories to PATH:
|
Adding directories to PATH:
|
||||||
PATH += /home/user/dev/emsdk
|
PATH += /home/user/dev/emsdk
|
||||||
PATH += /home/user/dev/emsdk/upstream/emscripten
|
PATH += /home/user/dev/emsdk/upstream/emscripten
|
||||||
@@ -177,20 +200,9 @@ EMSDK = /home/user/dev/emsdk
|
|||||||
EM_CONFIG = /home/user/dev/emsdk/.emscripten
|
EM_CONFIG = /home/user/dev/emsdk/.emscripten
|
||||||
EM_CACHE = /home/user/dev/emsdk/upstream/emscripten/cache
|
EM_CACHE = /home/user/dev/emsdk/upstream/emscripten/cache
|
||||||
EMSDK_NODE = /home/user/dev/emsdk/node/12.18.1_64bit/bin/node
|
EMSDK_NODE = /home/user/dev/emsdk/node/12.18.1_64bit/bin/node
|
||||||
)";
|
)" << int(OsTypeLinux) << 3 << "/home/user/dev/emsdk" << "/home/user/dev/emsdk/.emscripten";
|
||||||
Environment env;
|
}
|
||||||
parseEmSdkEnvOutputAndAddToEnv(emSdkEnvOutput, env);
|
|
||||||
|
|
||||||
if (HostOsInfo::isWindowsHost()) {
|
|
||||||
QVERIFY(env.path().count() == 5);
|
|
||||||
QCOMPARE(env.value("EMSDK"), "C:/Users/user/dev/emsdk");
|
|
||||||
QCOMPARE(env.value("EM_CONFIG"), "C:\\Users\\user\\dev\\emsdk\\.emscripten");
|
|
||||||
} else {
|
|
||||||
QVERIFY(env.path().count() == 3);
|
|
||||||
QCOMPARE(env.value("EMSDK"), "/home/user/dev/emsdk");
|
|
||||||
QCOMPARE(env.value("EM_CONFIG"), "/home/user/dev/emsdk/.emscripten");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // WITH_TESTS
|
#endif // WITH_TESTS
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -129,7 +129,7 @@ static QString environmentDisplay(const FilePath &sdkRoot)
|
|||||||
WebAssemblyEmSdk::addToEnvironment(sdkRoot, env);
|
WebAssemblyEmSdk::addToEnvironment(sdkRoot, env);
|
||||||
QString result;
|
QString result;
|
||||||
result.append(WebAssemblyOptionsWidget::tr("<h4>Adding directories to PATH:</h4>"));
|
result.append(WebAssemblyOptionsWidget::tr("<h4>Adding directories to PATH:</h4>"));
|
||||||
result.append(env.value("PATH").replace(HostOsInfo::pathListSeparator(), "<br/>"));
|
result.append(env.value("PATH").replace(OsSpecificAspects::pathListSeparator(sdkRoot.osType()), "<br/>"));
|
||||||
result.append(WebAssemblyOptionsWidget::tr("<h4>Setting environment variables:</h4>"));
|
result.append(WebAssemblyOptionsWidget::tr("<h4>Setting environment variables:</h4>"));
|
||||||
for (const QString &envVar : env.toStringList()) {
|
for (const QString &envVar : env.toStringList()) {
|
||||||
if (!envVar.startsWith("PATH")) // Path was already printed out above
|
if (!envVar.startsWith("PATH")) // Path was already printed out above
|
||||||
|
@@ -48,6 +48,7 @@ public:
|
|||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
private slots:
|
private slots:
|
||||||
void testEmSdkEnvParsing();
|
void testEmSdkEnvParsing();
|
||||||
|
void testEmSdkEnvParsing_data();
|
||||||
#endif // WITH_TESTS
|
#endif // WITH_TESTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -50,8 +50,9 @@ static CommandLine emrunCommand(Target *target, const QString &browser, const QS
|
|||||||
// that the web server is killed when the application is stopped in Qt Creator.
|
// that the web server is killed when the application is stopped in Qt Creator.
|
||||||
// On Non-windows, we prefer using the shell script, because that knows how to find the
|
// On Non-windows, we prefer using the shell script, because that knows how to find the
|
||||||
// right python (not part of emsdk). The shell script stays attached to the server process.
|
// right python (not part of emsdk). The shell script stays attached to the server process.
|
||||||
const FilePath interpreter = bc->environment().searchInPath(
|
const FilePath interpreter = HostOsInfo::isWindowsHost()
|
||||||
QLatin1String(HostOsInfo::isWindowsHost() ? "python" : "sh"));
|
? FilePath::fromUserInput(bc->environment().value("EMSDK_PYTHON"))
|
||||||
|
: bc->environment().searchInPath("sh");
|
||||||
const QString emrunLaunchScript = HostOsInfo::isWindowsHost()
|
const QString emrunLaunchScript = HostOsInfo::isWindowsHost()
|
||||||
? emrun.absolutePath() + "/" + emrun.baseName() + ".py"
|
? emrun.absolutePath() + "/" + emrun.baseName() + ".py"
|
||||||
: emrun.absoluteFilePath();
|
: emrun.absoluteFilePath();
|
||||||
|
@@ -27,20 +27,20 @@
|
|||||||
#include "webassemblyconstants.h"
|
#include "webassemblyconstants.h"
|
||||||
#include "webassemblyemsdk.h"
|
#include "webassemblyemsdk.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/devicesupport/devicemanager.h>
|
||||||
#include <projectexplorer/kitmanager.h>
|
#include <projectexplorer/kitmanager.h>
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
#include <projectexplorer/projectmacro.h>
|
#include <projectexplorer/projectmacro.h>
|
||||||
#include <projectexplorer/toolchainmanager.h>
|
#include <projectexplorer/toolchainmanager.h>
|
||||||
|
|
||||||
#include <qtsupport/qtkitinformation.h>
|
#include <qtsupport/qtkitinformation.h>
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/environment.h>
|
#include <utils/environment.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QDir>
|
|
||||||
#include <QSettings>
|
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
using namespace QtSupport;
|
using namespace QtSupport;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
@@ -73,7 +73,7 @@ static void addRegisteredMinGWToEnvironment(Environment &env)
|
|||||||
void WebAssemblyToolChain::addToEnvironment(Environment &env) const
|
void WebAssemblyToolChain::addToEnvironment(Environment &env) const
|
||||||
{
|
{
|
||||||
WebAssemblyEmSdk::addToEnvironment(WebAssemblyEmSdk::registeredEmSdk(), env);
|
WebAssemblyEmSdk::addToEnvironment(WebAssemblyEmSdk::registeredEmSdk(), env);
|
||||||
if (HostOsInfo::isWindowsHost())
|
if (env.osType() == OsTypeWindows)
|
||||||
addRegisteredMinGWToEnvironment(env);
|
addRegisteredMinGWToEnvironment(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,8 +88,8 @@ WebAssemblyToolChain::WebAssemblyToolChain() :
|
|||||||
FilePath WebAssemblyToolChain::makeCommand(const Environment &environment) const
|
FilePath WebAssemblyToolChain::makeCommand(const Environment &environment) const
|
||||||
{
|
{
|
||||||
// Diverged duplicate of ClangToolChain::makeCommand and MingwToolChain::makeCommand
|
// Diverged duplicate of ClangToolChain::makeCommand and MingwToolChain::makeCommand
|
||||||
const QStringList makes
|
const QStringList makes = environment.osType() == OsTypeWindows
|
||||||
= HostOsInfo::isWindowsHost() ? QStringList({"mingw32-make.exe", "make.exe"})
|
? QStringList({"mingw32-make.exe", "make.exe"})
|
||||||
: QStringList({"make"});
|
: QStringList({"make"});
|
||||||
|
|
||||||
FilePath tmp;
|
FilePath tmp;
|
||||||
@@ -162,13 +162,12 @@ QList<ToolChain *> WebAssemblyToolChainFactory::autoDetect(
|
|||||||
const IDevice::Ptr &device)
|
const IDevice::Ptr &device)
|
||||||
{
|
{
|
||||||
Q_UNUSED(alreadyKnown)
|
Q_UNUSED(alreadyKnown)
|
||||||
Q_UNUSED(device)
|
|
||||||
|
|
||||||
const FilePath sdk = WebAssemblyEmSdk::registeredEmSdk();
|
const FilePath sdk = WebAssemblyEmSdk::registeredEmSdk();
|
||||||
if (!WebAssemblyEmSdk::isValid(sdk))
|
if (!WebAssemblyEmSdk::isValid(sdk))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
Environment env;
|
Environment env = sdk.deviceEnvironment();
|
||||||
WebAssemblyEmSdk::addToEnvironment(sdk, env);
|
WebAssemblyEmSdk::addToEnvironment(sdk, env);
|
||||||
|
|
||||||
QList<ToolChain *> result;
|
QList<ToolChain *> result;
|
||||||
@@ -178,9 +177,11 @@ QList<ToolChain *> WebAssemblyToolChainFactory::autoDetect(
|
|||||||
toolChain->setLanguage(languageId);
|
toolChain->setLanguage(languageId);
|
||||||
toolChain->setDetection(ToolChain::AutoDetection);
|
toolChain->setDetection(ToolChain::AutoDetection);
|
||||||
const bool cLanguage = languageId == ProjectExplorer::Constants::C_LANGUAGE_ID;
|
const bool cLanguage = languageId == ProjectExplorer::Constants::C_LANGUAGE_ID;
|
||||||
const QString scriptFile = QLatin1String(cLanguage ? "emcc" : "em++")
|
const QString script = QLatin1String(cLanguage ? "emcc" : "em++")
|
||||||
+ QLatin1String(HostOsInfo::isWindowsHost() ? ".bat" : "");
|
+ QLatin1String(sdk.osType() == OsTypeWindows ? ".bat" : "");
|
||||||
toolChain->setCompilerCommand(env.searchInPath(scriptFile));
|
const FilePath scriptFile =
|
||||||
|
FilePath::fromString(script).onDevice(sdk).searchOnDevice(env.path());
|
||||||
|
toolChain->setCompilerCommand(scriptFile);
|
||||||
|
|
||||||
const QString displayName = WebAssemblyToolChain::tr("Emscripten Compiler %1 for %2")
|
const QString displayName = WebAssemblyToolChain::tr("Emscripten Compiler %1 for %2")
|
||||||
.arg(toolChain->version(), QLatin1String(cLanguage ? "C" : "C++"));
|
.arg(toolChain->version(), QLatin1String(cLanguage ? "C" : "C++"));
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "proitems.h"
|
#include "proitems.h"
|
||||||
|
|
||||||
|
#include <qdebug.h>
|
||||||
#include <qfileinfo.h>
|
#include <qfileinfo.h>
|
||||||
#include <qset.h>
|
#include <qset.h>
|
||||||
#include <qstringlist.h>
|
#include <qstringlist.h>
|
||||||
@@ -50,6 +51,11 @@ ProString::ProString() :
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProString::ProString(const ProString &other) :
|
||||||
|
m_string(other.m_string), m_offset(other.m_offset), m_length(other.m_length), m_file(other.m_file), m_hash(other.m_hash)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ProString::ProString(const ProString &other, OmitPreHashing) :
|
ProString::ProString(const ProString &other, OmitPreHashing) :
|
||||||
m_string(other.m_string), m_offset(other.m_offset), m_length(other.m_length), m_file(other.m_file), m_hash(0x80000000)
|
m_string(other.m_string), m_offset(other.m_offset), m_length(other.m_length), m_file(other.m_file), m_hash(0x80000000)
|
||||||
{
|
{
|
||||||
@@ -72,13 +78,13 @@ ProString::ProString(Utils::StringView str) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
ProString::ProString(const char *str, DoPreHashing) :
|
ProString::ProString(const char *str, DoPreHashing) :
|
||||||
m_string(QString::fromLatin1(str)), m_offset(0), m_length(qstrlen(str)), m_file(0)
|
m_string(QString::fromLatin1(str)), m_offset(0), m_length(int(qstrlen(str))), m_file(0)
|
||||||
{
|
{
|
||||||
updatedHash();
|
updatedHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
ProString::ProString(const char *str) :
|
ProString::ProString(const char *str) :
|
||||||
m_string(QString::fromLatin1(str)), m_offset(0), m_length(qstrlen(str)), m_file(0), m_hash(0x80000000)
|
m_string(QString::fromLatin1(str)), m_offset(0), m_length(int(qstrlen(str))), m_file(0), m_hash(0x80000000)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +154,8 @@ QString ProString::toQString() const
|
|||||||
|
|
||||||
QString &ProString::toQString(QString &tmp) const
|
QString &ProString::toQString(QString &tmp) const
|
||||||
{
|
{
|
||||||
return tmp.setRawData(m_string.constData() + m_offset, m_length);
|
tmp = m_string.mid(m_offset, m_length);
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProString &ProString::prepend(const ProString &other)
|
ProString &ProString::prepend(const ProString &other)
|
||||||
@@ -493,4 +500,9 @@ ProKey ProFile::getHashStr(const ushort *&tPtr)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const ProString &str)
|
||||||
|
{
|
||||||
|
return debug << str.toQString();
|
||||||
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@@ -64,6 +64,8 @@ class ProFile;
|
|||||||
class ProString {
|
class ProString {
|
||||||
public:
|
public:
|
||||||
ProString();
|
ProString();
|
||||||
|
ProString(const ProString &other);
|
||||||
|
ProString &operator=(const ProString &) = default;
|
||||||
template<typename A, typename B>
|
template<typename A, typename B>
|
||||||
ProString &operator=(const QStringBuilder<A, B> &str)
|
ProString &operator=(const QStringBuilder<A, B> &str)
|
||||||
{ return *this = QString(str); }
|
{ return *this = QString(str); }
|
||||||
@@ -74,7 +76,6 @@ public:
|
|||||||
ProString(const QStringBuilder<A, B> &str)
|
ProString(const QStringBuilder<A, B> &str)
|
||||||
: ProString(QString(str))
|
: ProString(QString(str))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
ProString(const QString &str, int offset, int length);
|
ProString(const QString &str, int offset, int length);
|
||||||
void setValue(const QString &str);
|
void setValue(const QString &str);
|
||||||
void clear() { m_string.clear(); m_length = 0; }
|
void clear() { m_string.clear(); m_length = 0; }
|
||||||
@@ -83,14 +84,14 @@ public:
|
|||||||
int sourceFile() const { return m_file; }
|
int sourceFile() const { return m_file; }
|
||||||
|
|
||||||
ProString &prepend(const ProString &other);
|
ProString &prepend(const ProString &other);
|
||||||
ProString &append(const ProString &other, bool *pending = 0);
|
ProString &append(const ProString &other, bool *pending = nullptr);
|
||||||
ProString &append(const QString &other) { return append(ProString(other)); }
|
ProString &append(const QString &other) { return append(ProString(other)); }
|
||||||
template<typename A, typename B>
|
template<typename A, typename B>
|
||||||
ProString &append(const QStringBuilder<A, B> &other) { return append(QString(other)); }
|
ProString &append(const QStringBuilder<A, B> &other) { return append(QString(other)); }
|
||||||
ProString &append(const QLatin1String other);
|
ProString &append(const QLatin1String other);
|
||||||
ProString &append(const char *other) { return append(QLatin1String(other)); }
|
ProString &append(const char *other) { return append(QLatin1String(other)); }
|
||||||
ProString &append(QChar other);
|
ProString &append(QChar other);
|
||||||
ProString &append(const ProStringList &other, bool *pending = 0, bool skipEmpty1st = false);
|
ProString &append(const ProStringList &other, bool *pending = nullptr, bool skipEmpty1st = false);
|
||||||
ProString &operator+=(const ProString &other) { return append(other); }
|
ProString &operator+=(const ProString &other) { return append(other); }
|
||||||
ProString &operator+=(const QString &other) { return append(other); }
|
ProString &operator+=(const QString &other) { return append(other); }
|
||||||
template<typename A, typename B>
|
template<typename A, typename B>
|
||||||
@@ -146,9 +147,9 @@ public:
|
|||||||
bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(s, 0, cs) >= 0; }
|
bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(s, 0, cs) >= 0; }
|
||||||
bool contains(const char *s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(QLatin1String(s), 0, cs) >= 0; }
|
bool contains(const char *s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(QLatin1String(s), 0, cs) >= 0; }
|
||||||
bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(c, 0, cs) >= 0; }
|
bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(c, 0, cs) >= 0; }
|
||||||
int toLongLong(bool *ok = 0, int base = 10) const { return toStringView().toLongLong(ok, base); }
|
qlonglong toLongLong(bool *ok = nullptr, int base = 10) const { return toStringView().toLongLong(ok, base); }
|
||||||
int toInt(bool *ok = 0, int base = 10) const { return toStringView().toInt(ok, base); }
|
int toInt(bool *ok = nullptr, int base = 10) const { return toStringView().toInt(ok, base); }
|
||||||
short toShort(bool *ok = 0, int base = 10) const { return toStringView().toShort(ok, base); }
|
short toShort(bool *ok = nullptr, int base = 10) const { return toStringView().toShort(ok, base); }
|
||||||
|
|
||||||
uint hash() const { return m_hash; }
|
uint hash() const { return m_hash; }
|
||||||
static uint hash(const QChar *p, int n);
|
static uint hash(const QChar *p, int n);
|
||||||
@@ -185,7 +186,8 @@ private:
|
|||||||
friend QString operator+(const ProString &one, const ProString &two);
|
friend QString operator+(const ProString &one, const ProString &two);
|
||||||
friend class ProKey;
|
friend class ProKey;
|
||||||
};
|
};
|
||||||
Q_DECLARE_TYPEINFO(ProString, Q_MOVABLE_TYPE);
|
Q_DECLARE_TYPEINFO(ProString, Q_RELOCATABLE_TYPE);
|
||||||
|
|
||||||
|
|
||||||
class ProKey : public ProString {
|
class ProKey : public ProString {
|
||||||
public:
|
public:
|
||||||
@@ -195,7 +197,6 @@ public:
|
|||||||
ProKey(const QStringBuilder<A, B> &str)
|
ProKey(const QStringBuilder<A, B> &str)
|
||||||
: ProString(str)
|
: ProString(str)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
PROITEM_EXPLICIT ProKey(const char *str);
|
PROITEM_EXPLICIT ProKey(const char *str);
|
||||||
ProKey(const QString &str, int off, int len);
|
ProKey(const QString &str, int off, int len);
|
||||||
ProKey(const QString &str, int off, int len, uint hash);
|
ProKey(const QString &str, int off, int len, uint hash);
|
||||||
@@ -217,7 +218,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
ProKey(const ProString &other);
|
ProKey(const ProString &other);
|
||||||
};
|
};
|
||||||
Q_DECLARE_TYPEINFO(ProKey, Q_MOVABLE_TYPE);
|
Q_DECLARE_TYPEINFO(ProKey, Q_RELOCATABLE_TYPE);
|
||||||
|
|
||||||
template <> struct QConcatenable<ProString> : private QAbstractConcatenable
|
template <> struct QConcatenable<ProString> : private QAbstractConcatenable
|
||||||
{
|
{
|
||||||
@@ -228,6 +229,8 @@ template <> struct QConcatenable<ProString> : private QAbstractConcatenable
|
|||||||
static inline void appendTo(const ProString &a, QChar *&out)
|
static inline void appendTo(const ProString &a, QChar *&out)
|
||||||
{
|
{
|
||||||
const auto n = a.size();
|
const auto n = a.size();
|
||||||
|
if (!n)
|
||||||
|
return;
|
||||||
memcpy(out, a.toStringView().data(), sizeof(QChar) * n);
|
memcpy(out, a.toStringView().data(), sizeof(QChar) * n);
|
||||||
out += n;
|
out += n;
|
||||||
}
|
}
|
||||||
@@ -242,6 +245,8 @@ template <> struct QConcatenable<ProKey> : private QAbstractConcatenable
|
|||||||
static inline void appendTo(const ProKey &a, QChar *&out)
|
static inline void appendTo(const ProKey &a, QChar *&out)
|
||||||
{
|
{
|
||||||
const auto n = a.size();
|
const auto n = a.size();
|
||||||
|
if (!n)
|
||||||
|
return;
|
||||||
memcpy(out, a.toStringView().data(), sizeof(QChar) * n);
|
memcpy(out, a.toStringView().data(), sizeof(QChar) * n);
|
||||||
out += n;
|
out += n;
|
||||||
}
|
}
|
||||||
@@ -257,6 +262,54 @@ QTextStream &operator<<(QTextStream &t, const ProString &str);
|
|||||||
template<typename A, typename B>
|
template<typename A, typename B>
|
||||||
QTextStream &operator<<(QTextStream &t, const QStringBuilder<A, B> &str) { return t << QString(str); }
|
QTextStream &operator<<(QTextStream &t, const QStringBuilder<A, B> &str) { return t << QString(str); }
|
||||||
|
|
||||||
|
// This class manages read-only access to a ProString via a raw data QString
|
||||||
|
// temporary, ensuring that the latter is accessed exclusively.
|
||||||
|
class ProStringRoUser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ProStringRoUser(QString &rs)
|
||||||
|
{
|
||||||
|
m_rs = &rs;
|
||||||
|
}
|
||||||
|
ProStringRoUser(const ProString &ps, QString &rs)
|
||||||
|
: ProStringRoUser(rs)
|
||||||
|
{
|
||||||
|
ps.toQString(rs);
|
||||||
|
}
|
||||||
|
// No destructor, as a RAII pattern cannot be used: references to the
|
||||||
|
// temporary string can legitimately outlive instances of this class
|
||||||
|
// (if they are held by Qt, e.g. in QRegExp).
|
||||||
|
QString &set(const ProString &ps) { return ps.toQString(*m_rs); }
|
||||||
|
QString &str() { return *m_rs; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QString *m_rs;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This class manages read-write access to a ProString via a raw data QString
|
||||||
|
// temporary, ensuring that the latter is accessed exclusively, and that raw
|
||||||
|
// data does not leak outside its source's refcounting.
|
||||||
|
class ProStringRwUser : public ProStringRoUser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ProStringRwUser(QString &rs)
|
||||||
|
: ProStringRoUser(rs), m_ps(nullptr) {}
|
||||||
|
ProStringRwUser(const ProString &ps, QString &rs)
|
||||||
|
: ProStringRoUser(ps, rs), m_ps(&ps) {}
|
||||||
|
QString &set(const ProString &ps) { m_ps = &ps; return ProStringRoUser::set(ps); }
|
||||||
|
ProString extract(const QString &s) const
|
||||||
|
{ return s.isSharedWith(*m_rs) ? *m_ps : ProString(s).setSource(*m_ps); }
|
||||||
|
ProString extract(const QString &s, const ProStringRwUser &other) const
|
||||||
|
{
|
||||||
|
if (other.m_ps && s.isSharedWith(*other.m_rs))
|
||||||
|
return *other.m_ps;
|
||||||
|
return extract(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const ProString *m_ps;
|
||||||
|
};
|
||||||
|
|
||||||
class ProStringList : public QVector<ProString> {
|
class ProStringList : public QVector<ProString> {
|
||||||
public:
|
public:
|
||||||
ProStringList() {}
|
ProStringList() {}
|
||||||
@@ -290,21 +343,12 @@ public:
|
|||||||
{ return contains(ProString(str), cs); }
|
{ return contains(ProString(str), cs); }
|
||||||
bool contains(const char *str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
|
bool contains(const char *str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
|
||||||
};
|
};
|
||||||
Q_DECLARE_TYPEINFO(ProStringList, Q_MOVABLE_TYPE);
|
Q_DECLARE_TYPEINFO(ProStringList, Q_RELOCATABLE_TYPE);
|
||||||
|
|
||||||
inline ProStringList operator+(const ProStringList &one, const ProStringList &two)
|
inline ProStringList operator+(const ProStringList &one, const ProStringList &two)
|
||||||
{ ProStringList ret = one; ret += two; return ret; }
|
{ ProStringList ret = one; ret += two; return ret; }
|
||||||
|
|
||||||
typedef QHash<ProKey, ProStringList> ProValueMap;
|
typedef QMap<ProKey, ProStringList> ProValueMap;
|
||||||
|
|
||||||
// For std::list (sic!)
|
|
||||||
#ifdef Q_CC_MSVC
|
|
||||||
inline bool operator<(const ProValueMap &, const ProValueMap &)
|
|
||||||
{
|
|
||||||
Q_ASSERT(false);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// These token definitions affect both ProFileEvaluator and ProWriter
|
// These token definitions affect both ProFileEvaluator and ProWriter
|
||||||
enum ProToken {
|
enum ProToken {
|
||||||
@@ -419,7 +463,7 @@ class ProFunctionDef {
|
|||||||
public:
|
public:
|
||||||
ProFunctionDef(ProFile *pro, int offset) : m_pro(pro), m_offset(offset) { m_pro->ref(); }
|
ProFunctionDef(ProFile *pro, int offset) : m_pro(pro), m_offset(offset) { m_pro->ref(); }
|
||||||
ProFunctionDef(const ProFunctionDef &o) : m_pro(o.m_pro), m_offset(o.m_offset) { m_pro->ref(); }
|
ProFunctionDef(const ProFunctionDef &o) : m_pro(o.m_pro), m_offset(o.m_offset) { m_pro->ref(); }
|
||||||
ProFunctionDef(ProFunctionDef &&other) Q_DECL_NOTHROW
|
ProFunctionDef(ProFunctionDef &&other) noexcept
|
||||||
: m_pro(other.m_pro), m_offset(other.m_offset) { other.m_pro = nullptr; }
|
: m_pro(other.m_pro), m_offset(other.m_offset) { other.m_pro = nullptr; }
|
||||||
~ProFunctionDef() { if (m_pro) m_pro->deref(); }
|
~ProFunctionDef() { if (m_pro) m_pro->deref(); }
|
||||||
ProFunctionDef &operator=(const ProFunctionDef &o)
|
ProFunctionDef &operator=(const ProFunctionDef &o)
|
||||||
@@ -433,13 +477,13 @@ public:
|
|||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ProFunctionDef &operator=(ProFunctionDef &&other) Q_DECL_NOTHROW
|
ProFunctionDef &operator=(ProFunctionDef &&other) noexcept
|
||||||
{
|
{
|
||||||
ProFunctionDef moved(std::move(other));
|
ProFunctionDef moved(std::move(other));
|
||||||
swap(moved);
|
swap(moved);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
void swap(ProFunctionDef &other) Q_DECL_NOTHROW
|
void swap(ProFunctionDef &other) noexcept
|
||||||
{
|
{
|
||||||
qSwap(m_pro, other.m_pro);
|
qSwap(m_pro, other.m_pro);
|
||||||
qSwap(m_offset, other.m_offset);
|
qSwap(m_offset, other.m_offset);
|
||||||
@@ -452,11 +496,13 @@ private:
|
|||||||
int m_offset;
|
int m_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_TYPEINFO(ProFunctionDef, Q_MOVABLE_TYPE);
|
Q_DECLARE_TYPEINFO(ProFunctionDef, Q_RELOCATABLE_TYPE);
|
||||||
|
|
||||||
struct ProFunctionDefs {
|
struct ProFunctionDefs {
|
||||||
QHash<ProKey, ProFunctionDef> testFunctions;
|
QHash<ProKey, ProFunctionDef> testFunctions;
|
||||||
QHash<ProKey, ProFunctionDef> replaceFunctions;
|
QHash<ProKey, ProFunctionDef> replaceFunctions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const ProString &str);
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@@ -144,9 +144,10 @@ def checkForStillRunningQmlExecutable(possibleNames):
|
|||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
if subprocess.call(["taskkill", "/F", "/FI", "IMAGENAME eq %s" % qmlHelper]) == 0:
|
if subprocess.call(["taskkill", "/F", "/FI", "IMAGENAME eq %s" % qmlHelper]) == 0:
|
||||||
print "Killed still running %s" % qmlHelper
|
print("Killed still running %s" % qmlHelper)
|
||||||
else:
|
else:
|
||||||
print "%s is still running - failed to kill it" % qmlHelper
|
print("%s is still running - failed to kill it" % qmlHelper)
|
||||||
|
|
||||||
|
|
||||||
def __removeTestingDir__():
|
def __removeTestingDir__():
|
||||||
def __removeIt__(directory):
|
def __removeIt__(directory):
|
||||||
|
@@ -579,7 +579,7 @@ def dumpChildren(item):
|
|||||||
|
|
||||||
def writeTestResults(folder):
|
def writeTestResults(folder):
|
||||||
if not os.path.exists(folder):
|
if not os.path.exists(folder):
|
||||||
print "Skipping writing test results (folder '%s' does not exist)." % folder
|
print("Skipping writing test results (folder '%s' does not exist)." % folder)
|
||||||
return
|
return
|
||||||
resultFile = open("%s.srf" % os.path.join(folder, os.path.basename(squishinfo.testCase)), "w")
|
resultFile = open("%s.srf" % os.path.join(folder, os.path.basename(squishinfo.testCase)), "w")
|
||||||
resultFile.write("suite:%s\n" % os.path.basename(os.path.dirname(squishinfo.testCase)))
|
resultFile.write("suite:%s\n" % os.path.basename(os.path.dirname(squishinfo.testCase)))
|
||||||
|
@@ -66,6 +66,11 @@ def checkQtCreatorHelpVersion(expectedVersion):
|
|||||||
test.log("Exception caught", "%s(%s)" % (str(t), str(v)))
|
test.log("Exception caught", "%s(%s)" % (str(t), str(v)))
|
||||||
test.fail("Missing Qt Creator Manual.")
|
test.fail("Missing Qt Creator Manual.")
|
||||||
|
|
||||||
|
|
||||||
|
def _shortcutMatches_(shortcutEdit, expectedText):
|
||||||
|
return str(findObject(shortcutEdit).text) == expectedText
|
||||||
|
|
||||||
|
|
||||||
def setKeyboardShortcutForAboutQtC():
|
def setKeyboardShortcutForAboutQtC():
|
||||||
invokeMenuItem("Tools", "Options...")
|
invokeMenuItem("Tools", "Options...")
|
||||||
mouseClick(waitForObjectItem(":Options_QListView", "Environment"))
|
mouseClick(waitForObjectItem(":Options_QListView", "Environment"))
|
||||||
@@ -85,20 +90,19 @@ def setKeyboardShortcutForAboutQtC():
|
|||||||
"visible='1' text~='(Stop Recording|Record)'}" % shortcutGB)
|
"visible='1' text~='(Stop Recording|Record)'}" % shortcutGB)
|
||||||
shortcut = ("{container=%s type='Utils::FancyLineEdit' unnamed='1' visible='1' "
|
shortcut = ("{container=%s type='Utils::FancyLineEdit' unnamed='1' visible='1' "
|
||||||
"placeholderText='Enter key sequence as text'}" % shortcutGB)
|
"placeholderText='Enter key sequence as text'}" % shortcutGB)
|
||||||
|
expected = 'Ctrl+Opt+A' if platform.system() == 'Darwin' else 'Ctrl+Alt+A'
|
||||||
clickButton(record)
|
clickButton(record)
|
||||||
nativeType("<Ctrl+Alt+a>")
|
nativeType("<Ctrl+Alt+a>")
|
||||||
|
waitFor("_shortcutMatches_(shortcut, expected)", 5000)
|
||||||
clickButton(record)
|
clickButton(record)
|
||||||
expected = 'Ctrl+Alt+A'
|
|
||||||
if platform.system() == 'Darwin':
|
|
||||||
expected = 'Ctrl+Opt+A'
|
|
||||||
|
|
||||||
shortcutMatches = waitFor("str(findObject(shortcut).text) == expected", 5000)
|
gotExpectedShortcut = _shortcutMatches_(shortcut, expected)
|
||||||
if not shortcutMatches and platform.system() == 'Darwin':
|
if not gotExpectedShortcut and platform.system() == 'Darwin':
|
||||||
test.warning("Squish Issue: shortcut was set to %s - entering it manually now"
|
test.warning("Squish Issue: shortcut was set to %s - entering it manually now"
|
||||||
% waitForObject(shortcut).text)
|
% waitForObject(shortcut).text)
|
||||||
replaceEditorContent(shortcut, expected)
|
replaceEditorContent(shortcut, expected)
|
||||||
else:
|
else:
|
||||||
test.verify(shortcutMatches, "Expected key sequence is displayed.")
|
test.verify(gotExpectedShortcut, "Expected key sequence is displayed.")
|
||||||
clickButton(waitForObject(":Options.OK_QPushButton"))
|
clickButton(waitForObject(":Options.OK_QPushButton"))
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|