forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/5.0'
Change-Id: I4236e3d2f87d56aea787905f4b78b1f5f933c069
This commit is contained in:
@@ -34,6 +34,7 @@ import StudioTheme 1.0 as StudioTheme
|
||||
Item {
|
||||
property var selectedAssets: ({})
|
||||
property int allExpandedState: 0
|
||||
property string delFilePath: ""
|
||||
|
||||
DropArea {
|
||||
id: dropArea
|
||||
@@ -83,14 +84,25 @@ Item {
|
||||
StudioControls.MenuItem {
|
||||
text: qsTr("Expand All")
|
||||
enabled: allExpandedState !== 1
|
||||
visible: !delFilePath
|
||||
height: visible ? implicitHeight : 0
|
||||
onTriggered: assetsModel.toggleExpandAll(true)
|
||||
}
|
||||
|
||||
StudioControls.MenuItem {
|
||||
text: qsTr("Collapse All")
|
||||
enabled: allExpandedState !== 2
|
||||
visible: !delFilePath
|
||||
height: visible ? implicitHeight : 0
|
||||
onTriggered: assetsModel.toggleExpandAll(false)
|
||||
}
|
||||
|
||||
StudioControls.MenuItem {
|
||||
text: qsTr("Delete File")
|
||||
visible: delFilePath
|
||||
height: visible ? implicitHeight : 0
|
||||
onTriggered: assetsModel.removeFile(delFilePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +133,7 @@ Item {
|
||||
dirExpanded = !dirExpanded
|
||||
}
|
||||
onShowContextMenu: {
|
||||
delFilePath = ""
|
||||
allExpandedState = assetsModel.getAllExpandedState()
|
||||
contextMenu.popup()
|
||||
}
|
||||
@@ -173,6 +186,7 @@ Item {
|
||||
|
||||
readonly property string suffix: fileName.substr(-4)
|
||||
readonly property bool isFont: suffix === ".ttf" || suffix === ".otf"
|
||||
property bool currFileSelected: false
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
@@ -190,7 +204,8 @@ Item {
|
||||
var ctrlDown = mouse.modifiers & Qt.ControlModifier
|
||||
if (!selectedAssets[filePath] && !ctrlDown)
|
||||
selectedAssets = {}
|
||||
selectedAssets[filePath] = true
|
||||
currFileSelected = ctrlDown ? !selectedAssets[filePath] : true
|
||||
selectedAssets[filePath] = currFileSelected
|
||||
selectedAssetsChanged()
|
||||
|
||||
var selectedAssetsArr = []
|
||||
@@ -199,9 +214,12 @@ Item {
|
||||
selectedAssetsArr.push(assetPath)
|
||||
}
|
||||
|
||||
rootView.startDragAsset(selectedAssetsArr, mapToGlobal(mouse.x, mouse.y))
|
||||
if (currFileSelected)
|
||||
rootView.startDragAsset(selectedAssetsArr, mapToGlobal(mouse.x, mouse.y))
|
||||
} else {
|
||||
print("TODO: impl context menu")
|
||||
delFilePath = filePath
|
||||
tooltipBackend.hideTooltip()
|
||||
contextMenu.popup()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,13 +227,13 @@ Item {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
if (!(mouse.modifiers & Qt.ControlModifier))
|
||||
selectedAssets = {}
|
||||
selectedAssets[filePath] = true
|
||||
selectedAssets[filePath] = currFileSelected
|
||||
selectedAssetsChanged()
|
||||
}
|
||||
}
|
||||
|
||||
ToolTip {
|
||||
visible: !isFont && mouseArea.containsMouse
|
||||
visible: !isFont && mouseArea.containsMouse && !contextMenu.visible
|
||||
text: filePath
|
||||
delay: 1000
|
||||
}
|
||||
|
||||
@@ -58,24 +58,18 @@ Section {
|
||||
ExpandingSpacer {}
|
||||
}
|
||||
|
||||
PropertyLabel { text: qsTr("Alignment") }
|
||||
PropertyLabel { text: qsTr("Alignment H") }
|
||||
|
||||
SecondColumnLayout {
|
||||
AligmentHorizontalButtons {
|
||||
id: horizontalAlignmentButtons
|
||||
backendValue: backendValues.%2_horizontalAlignment;
|
||||
}
|
||||
AlignmentHorizontalButtons {}
|
||||
|
||||
Spacer {
|
||||
implicitWidth: StudioTheme.Values.controlGap
|
||||
+ StudioTheme.Values.controlLabelWidth
|
||||
+ StudioTheme.Values.controlGap
|
||||
+ StudioTheme.Values.twoControlColumnWidth
|
||||
+ StudioTheme.Values.actionIndicatorWidth
|
||||
- horizontalAlignmentButtons.implicitWidth
|
||||
}
|
||||
ExpandingSpacer {}
|
||||
}
|
||||
|
||||
AligmentVerticalButtons {
|
||||
PropertyLabel { text: qsTr("Alignment V") }
|
||||
|
||||
SecondColumnLayout {
|
||||
AlignmentVerticalButtons {
|
||||
backendValue: backendValues.%2_verticalAlignment;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import QtQuick.Layouts 1.15
|
||||
import QtQuickDesignerTheme 1.0
|
||||
import HelperWidgets 2.0
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
import "../QtQuick" as Q
|
||||
|
||||
Rectangle {
|
||||
id: itemPane
|
||||
@@ -49,7 +48,7 @@ Rectangle {
|
||||
y: -1
|
||||
width: itemPane.width
|
||||
|
||||
Q.ComponentSection {}
|
||||
ComponentSection {}
|
||||
|
||||
Column {
|
||||
anchors.left: parent.left
|
||||
|
||||
@@ -29,8 +29,9 @@ import StudioControls 1.0 as StudioControls
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
|
||||
Row {
|
||||
id: alignmentHorizontalButtons
|
||||
id: root
|
||||
|
||||
property string scope: "Text"
|
||||
property bool blueHighlight: false
|
||||
property variant backendValue: backendValues.horizontalAlignment
|
||||
property variant value: backendValue.enumeration
|
||||
@@ -42,6 +43,7 @@ Row {
|
||||
buttonAlignLeft.checked = true
|
||||
buttonAlignHCenter.checked = false
|
||||
buttonAlignRight.checked = false
|
||||
buttonAlignJustify.checked = false
|
||||
|
||||
if (value !== undefined) {
|
||||
if (value === "AlignLeft")
|
||||
@@ -50,6 +52,8 @@ Row {
|
||||
buttonAlignHCenter.checked = true
|
||||
else if (value === "AlignRight")
|
||||
buttonAlignRight.checked = true
|
||||
else if (value === "AlignJustify")
|
||||
buttonAlignJustify.checked = true
|
||||
}
|
||||
evaluate()
|
||||
}
|
||||
@@ -75,7 +79,7 @@ Row {
|
||||
|
||||
ExtendedFunctionLogic {
|
||||
id: extFuncLogic
|
||||
backendValue: alignmentHorizontalButtons.backendValue
|
||||
backendValue: root.backendValue
|
||||
}
|
||||
|
||||
StudioControls.ButtonRow {
|
||||
@@ -98,7 +102,7 @@ Row {
|
||||
iconColor: __currentColor
|
||||
onClicked: {
|
||||
if (checked)
|
||||
backendValue.setEnumeration("Text", "AlignLeft")
|
||||
backendValue.setEnumeration(root.scope, "AlignLeft")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +115,7 @@ Row {
|
||||
iconColor: __currentColor
|
||||
onClicked: {
|
||||
if (checked)
|
||||
backendValue.setEnumeration("Text", "AlignHCenter")
|
||||
backendValue.setEnumeration(root.scope, "AlignHCenter")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +128,20 @@ Row {
|
||||
iconColor: __currentColor
|
||||
onClicked: {
|
||||
if (checked)
|
||||
backendValue.setEnumeration("Text", "AlignRight")
|
||||
backendValue.setEnumeration(root.scope, "AlignRight")
|
||||
}
|
||||
}
|
||||
|
||||
StudioControls.AbstractButton {
|
||||
id: buttonAlignJustify
|
||||
buttonIcon: StudioTheme.Constants.textAlignJustified
|
||||
checkable: true
|
||||
autoExclusive: true
|
||||
StudioControls.ButtonGroup.group: group
|
||||
iconColor: __currentColor
|
||||
onClicked: {
|
||||
if (checked)
|
||||
backendValue.setEnumeration(root.scope, "AlignJustify")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,8 +29,9 @@ import StudioControls 1.0 as StudioControls
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
|
||||
Row {
|
||||
id: alignmentVerticalButtons
|
||||
id: root
|
||||
|
||||
property string scope: "Text"
|
||||
property bool blueHighlight: false
|
||||
property variant backendValue: backendValues.verticalAlignment
|
||||
property variant value: backendValue.enumeration
|
||||
@@ -75,7 +76,7 @@ Row {
|
||||
|
||||
ExtendedFunctionLogic {
|
||||
id: extFuncLogic
|
||||
backendValue: alignmentVerticalButtons.backendValue
|
||||
backendValue: root.backendValue
|
||||
}
|
||||
|
||||
StudioControls.ButtonRow {
|
||||
@@ -100,7 +101,7 @@ Row {
|
||||
iconColor: __currentColor
|
||||
onClicked: {
|
||||
if (checked)
|
||||
backendValue.setEnumeration("Text", "AlignTop")
|
||||
backendValue.setEnumeration(root.scope, "AlignTop")
|
||||
}
|
||||
}
|
||||
StudioControls.AbstractButton {
|
||||
@@ -112,7 +113,7 @@ Row {
|
||||
iconColor: __currentColor
|
||||
onClicked: {
|
||||
if (checked)
|
||||
backendValue.setEnumeration("Text", "AlignVCenter")
|
||||
backendValue.setEnumeration(root.scope, "AlignVCenter")
|
||||
}
|
||||
}
|
||||
StudioControls.AbstractButton {
|
||||
@@ -124,7 +125,7 @@ Row {
|
||||
iconColor: __currentColor
|
||||
onClicked: {
|
||||
if (checked)
|
||||
backendValue.setEnumeration("Text", "AlignBottom")
|
||||
backendValue.setEnumeration(root.scope, "AlignBottom")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -277,22 +277,20 @@ Section {
|
||||
enabled: !styleNameComboBox.styleSet
|
||||
}
|
||||
|
||||
PropertyLabel { text: qsTr("Alignment") }
|
||||
PropertyLabel { text: qsTr("Alignment H") }
|
||||
|
||||
SecondColumnLayout {
|
||||
AligmentHorizontalButtons { id: horizontalAlignmentButtons }
|
||||
AlignmentHorizontalButtons {}
|
||||
|
||||
Spacer {
|
||||
visible: root.showVerticalAlignment
|
||||
implicitWidth: StudioTheme.Values.controlGap
|
||||
+ StudioTheme.Values.controlLabelWidth
|
||||
+ StudioTheme.Values.controlGap
|
||||
+ StudioTheme.Values.twoControlColumnWidth
|
||||
+ StudioTheme.Values.actionIndicatorWidth
|
||||
- horizontalAlignmentButtons.implicitWidth
|
||||
}
|
||||
ExpandingSpacer {}
|
||||
}
|
||||
|
||||
AligmentVerticalButtons { visible: root.showVerticalAlignment }
|
||||
PropertyLabel { text: qsTr("Alignment V") }
|
||||
|
||||
SecondColumnLayout {
|
||||
AlignmentVerticalButtons { visible: root.showVerticalAlignment }
|
||||
|
||||
ExpandingSpacer {}
|
||||
}
|
||||
|
||||
PropertyLabel {
|
||||
|
||||
@@ -29,7 +29,6 @@ import QtQuick.Layouts 1.15
|
||||
import QtQuickDesignerTheme 1.0
|
||||
import QtQuick.Templates 2.15 as T
|
||||
import HelperWidgets 2.0
|
||||
import StudioControls 1.0 as StudioControls
|
||||
import StudioTheme 1.0 as StudioTheme
|
||||
|
||||
Section {
|
||||
@@ -213,22 +212,24 @@ Section {
|
||||
onActiveFocusChanged: annotationEdit.z = activeFocus ? 10 : 0
|
||||
}
|
||||
|
||||
StudioControls.AbstractButton {
|
||||
AbstractButton {
|
||||
id: editAnnotationButton
|
||||
buttonIcon: StudioTheme.Constants.edit
|
||||
tooltip: qsTr("Edit annotation")
|
||||
onClicked: annotationEditor.showWidget()
|
||||
onHoveredChanged: annotationEditor.checkAux()
|
||||
}
|
||||
|
||||
StudioControls.AbstractButton {
|
||||
AbstractButton {
|
||||
id: removeAnnotationButton
|
||||
buttonIcon: StudioTheme.Constants.closeCross
|
||||
tooltip: qsTr("Remove annotation")
|
||||
onClicked: annotationEditor.removeFullAnnotation()
|
||||
onHoveredChanged: annotationEditor.checkAux()
|
||||
}
|
||||
}
|
||||
|
||||
StudioControls.AbstractButton {
|
||||
AbstractButton {
|
||||
id: addAnnotationButton
|
||||
implicitWidth: StudioTheme.Values.singleControlColumnWidth
|
||||
width: StudioTheme.Values.singleControlColumnWidth
|
||||
@@ -30,6 +30,12 @@ import StudioTheme 1.0 as StudioTheme
|
||||
ScrollBar {
|
||||
id: scrollBar
|
||||
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding)
|
||||
|
||||
|
||||
property bool scrollBarVisible: parent.childrenRect.width > parent.width
|
||||
|
||||
orientation: Qt.Horizontal
|
||||
@@ -40,6 +46,8 @@ ScrollBar {
|
||||
- (parent.bothVisible ? parent.verticalThickness : 0)
|
||||
padding: 0
|
||||
|
||||
minimumSize: orientation == Qt.Horizontal ? height / width : width / height
|
||||
|
||||
background: Rectangle {
|
||||
color: StudioTheme.Values.themeScrollBarTrack
|
||||
}
|
||||
|
||||
@@ -181,22 +181,20 @@ Section {
|
||||
ExpandingSpacer {}
|
||||
}
|
||||
|
||||
PropertyLabel { text: qsTr("Alignment") }
|
||||
PropertyLabel { text: qsTr("Alignment H") }
|
||||
|
||||
SecondColumnLayout {
|
||||
AligmentHorizontalButtons { id: horizontalAlignmentButtons }
|
||||
AlignmentHorizontalButtons {}
|
||||
|
||||
Spacer {
|
||||
visible: root.showVerticalAlignment
|
||||
implicitWidth: StudioTheme.Values.controlGap
|
||||
+ StudioTheme.Values.controlLabelWidth
|
||||
+ StudioTheme.Values.controlGap
|
||||
+ StudioTheme.Values.twoControlColumnWidth
|
||||
+ StudioTheme.Values.actionIndicatorWidth
|
||||
- horizontalAlignmentButtons.implicitWidth
|
||||
}
|
||||
ExpandingSpacer {}
|
||||
}
|
||||
|
||||
AligmentVerticalButtons { visible: root.showVerticalAlignment }
|
||||
PropertyLabel { text: qsTr("Alignment V") }
|
||||
|
||||
SecondColumnLayout {
|
||||
AlignmentVerticalButtons { visible: root.showVerticalAlignment }
|
||||
|
||||
ExpandingSpacer {}
|
||||
}
|
||||
|
||||
PropertyLabel {
|
||||
|
||||
@@ -30,8 +30,15 @@ import StudioTheme 1.0 as StudioTheme
|
||||
ScrollBar {
|
||||
id: scrollBar
|
||||
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding)
|
||||
|
||||
property bool scrollBarVisible: parent.childrenRect.height > parent.height
|
||||
|
||||
minimumSize: orientation == Qt.Horizontal ? height / width : width / height
|
||||
|
||||
orientation: Qt.Vertical
|
||||
policy: scrollBar.scrollBarVisible ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
|
||||
x: parent.width - width
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
AbstractButton 2.0 AbstractButton.qml
|
||||
ActionIndicator 2.0 ActionIndicator.qml
|
||||
AligmentHorizontalButtons 2.0 AligmentHorizontalButtons.qml
|
||||
AligmentVerticalButtons 2.0 AligmentVerticalButtons.qml
|
||||
AlignmentHorizontalButtons 2.0 AlignmentHorizontalButtons.qml
|
||||
AlignmentVerticalButtons 2.0 AlignmentVerticalButtons.qml
|
||||
AnchorButtons 2.0 AnchorButtons.qml
|
||||
BoolButtonRowButton 2.0 BoolButtonRowButton.qml
|
||||
Button 2.0 Button.qml
|
||||
@@ -16,6 +16,7 @@ ColorPalette 2.0 ColorPalette.qml
|
||||
ColorPicker 2.0 ColorPicker.qml
|
||||
ComboBox 2.0 ComboBox.qml
|
||||
ComponentButton 2.0 ComponentButton.qml
|
||||
ComponentSection 2.0 ComponentSection.qml
|
||||
ControlLabel 2.0 ControlLabel.qml
|
||||
singleton Controller 2.0 Controller.qml
|
||||
DoubleSpinBox 2.0 DoubleSpinBox.qml
|
||||
|
||||
@@ -126,43 +126,45 @@ QtObject {
|
||||
readonly property string play: "\u0079"
|
||||
readonly property string plus: "\u007A"
|
||||
readonly property string promote: "\u007B"
|
||||
readonly property string redo: "\u007C"
|
||||
readonly property string rotationFill: "\u007D"
|
||||
readonly property string rotationOutline: "\u007E"
|
||||
readonly property string search: "\u007F"
|
||||
readonly property string sectionToggle: "\u0080"
|
||||
readonly property string splitColumns: "\u0081"
|
||||
readonly property string splitRows: "\u0082"
|
||||
readonly property string startNode: "\u0083"
|
||||
readonly property string testIcon: "\u0084"
|
||||
readonly property string textAlignBottom: "\u0085"
|
||||
readonly property string textAlignCenter: "\u0086"
|
||||
readonly property string textAlignLeft: "\u0087"
|
||||
readonly property string textAlignMiddle: "\u0088"
|
||||
readonly property string textAlignRight: "\u0089"
|
||||
readonly property string textAlignTop: "\u008A"
|
||||
readonly property string textBulletList: "\u008B"
|
||||
readonly property string textFullJustification: "\u008C"
|
||||
readonly property string textNumberedList: "\u008D"
|
||||
readonly property string tickIcon: "\u008E"
|
||||
readonly property string transparent: "\u008F"
|
||||
readonly property string triState: "\u0090"
|
||||
readonly property string triangleArcA: "\u0091"
|
||||
readonly property string triangleArcB: "\u0092"
|
||||
readonly property string triangleCornerA: "\u0093"
|
||||
readonly property string triangleCornerB: "\u0094"
|
||||
readonly property string unLinked: "\u0095"
|
||||
readonly property string undo: "\u0096"
|
||||
readonly property string unpin: "\u0097"
|
||||
readonly property string upDownIcon: "\u0098"
|
||||
readonly property string upDownSquare2: "\u0099"
|
||||
readonly property string visibilityOff: "\u009A"
|
||||
readonly property string visibilityOn: "\u009B"
|
||||
readonly property string wildcard: "\u009C"
|
||||
readonly property string zoomAll: "\u009D"
|
||||
readonly property string zoomIn: "\u009E"
|
||||
readonly property string zoomOut: "\u009F"
|
||||
readonly property string zoomSelection: "\u00A0"
|
||||
readonly property string readOnly: "\u007C"
|
||||
readonly property string redo: "\u007D"
|
||||
readonly property string rotationFill: "\u007E"
|
||||
readonly property string rotationOutline: "\u007F"
|
||||
readonly property string search: "\u0080"
|
||||
readonly property string sectionToggle: "\u0081"
|
||||
readonly property string splitColumns: "\u0082"
|
||||
readonly property string splitRows: "\u0083"
|
||||
readonly property string startNode: "\u0084"
|
||||
readonly property string testIcon: "\u0085"
|
||||
readonly property string textAlignBottom: "\u0086"
|
||||
readonly property string textAlignCenter: "\u0087"
|
||||
readonly property string textAlignJustified: "\u0088"
|
||||
readonly property string textAlignLeft: "\u0089"
|
||||
readonly property string textAlignMiddle: "\u008A"
|
||||
readonly property string textAlignRight: "\u008B"
|
||||
readonly property string textAlignTop: "\u008C"
|
||||
readonly property string textBulletList: "\u008D"
|
||||
readonly property string textFullJustification: "\u008E"
|
||||
readonly property string textNumberedList: "\u008F"
|
||||
readonly property string tickIcon: "\u0090"
|
||||
readonly property string transparent: "\u0091"
|
||||
readonly property string triState: "\u0092"
|
||||
readonly property string triangleArcA: "\u0093"
|
||||
readonly property string triangleArcB: "\u0094"
|
||||
readonly property string triangleCornerA: "\u0095"
|
||||
readonly property string triangleCornerB: "\u0096"
|
||||
readonly property string unLinked: "\u0097"
|
||||
readonly property string undo: "\u0098"
|
||||
readonly property string unpin: "\u0099"
|
||||
readonly property string upDownIcon: "\u009A"
|
||||
readonly property string upDownSquare2: "\u009B"
|
||||
readonly property string visibilityOff: "\u009C"
|
||||
readonly property string visibilityOn: "\u009D"
|
||||
readonly property string wildcard: "\u009E"
|
||||
readonly property string zoomAll: "\u009F"
|
||||
readonly property string zoomIn: "\u00A0"
|
||||
readonly property string zoomOut: "\u00A1"
|
||||
readonly property string zoomSelection: "\u00A2"
|
||||
|
||||
readonly property font iconFont: Qt.font({
|
||||
"family": controlIcons.name,
|
||||
|
||||
Binary file not shown.
@@ -203,31 +203,6 @@ static inline int askMsgSendFailed()
|
||||
QMessageBox::Retry);
|
||||
}
|
||||
|
||||
// taken from utils/fileutils.cpp. We cannot use utils here since that depends app_version.h.
|
||||
static bool copyRecursively(const QString &srcFilePath, const QString &tgtFilePath)
|
||||
{
|
||||
QFileInfo srcFileInfo(srcFilePath);
|
||||
if (srcFileInfo.isDir()) {
|
||||
QDir targetDir(tgtFilePath);
|
||||
targetDir.cdUp();
|
||||
if (!targetDir.mkdir(Utils::FilePath::fromString(tgtFilePath).fileName()))
|
||||
return false;
|
||||
QDir sourceDir(srcFilePath);
|
||||
const QStringList fileNames = sourceDir.entryList
|
||||
(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System);
|
||||
for (const QString &fileName : fileNames) {
|
||||
const QString newSrcFilePath = srcFilePath + '/' + fileName;
|
||||
const QString newTgtFilePath = tgtFilePath + '/' + fileName;
|
||||
if (!copyRecursively(newSrcFilePath, newTgtFilePath))
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!QFile::copy(srcFilePath, tgtFilePath))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline QStringList getPluginPaths()
|
||||
{
|
||||
QStringList rc(QDir::cleanPath(QApplication::applicationDirPath()
|
||||
|
||||
@@ -774,15 +774,15 @@ bool QtcProcess::readDataFromProcess(int timeoutS,
|
||||
finished = waitForFinished(timeoutS > 0 ? timeoutS * 1000 : -1)
|
||||
|| state() == QProcess::NotRunning;
|
||||
// First check 'stdout'
|
||||
if (d->m_process->bytesAvailable()) { // applies to readChannel() only
|
||||
const QByteArray newStdOut = readAllStandardOutput();
|
||||
if (!newStdOut.isEmpty()) {
|
||||
hasData = true;
|
||||
const QByteArray newStdOut = d->m_process->readAllStandardOutput();
|
||||
if (stdOut)
|
||||
stdOut->append(newStdOut);
|
||||
}
|
||||
// Check 'stderr' separately. This is a special handling
|
||||
// for 'git pull' and the like which prints its progress on stderr.
|
||||
const QByteArray newStdErr = d->m_process->readAllStandardError();
|
||||
const QByteArray newStdErr = readAllStandardError();
|
||||
if (!newStdErr.isEmpty()) {
|
||||
hasData = true;
|
||||
if (stdErr)
|
||||
|
||||
@@ -682,6 +682,8 @@ public:
|
||||
Private(ClangdClient *q, Project *project)
|
||||
: q(q), settings(CppTools::ClangdProjectSettings(project).settings()) {}
|
||||
|
||||
void findUsages(TextEditor::TextDocument *document, const QTextCursor &cursor,
|
||||
const QString &searchTerm, const Utils::optional<QString> &replacement);
|
||||
void handleFindUsagesResult(quint64 key, const QList<Location> &locations);
|
||||
static void handleRenameRequest(const SearchResult *search,
|
||||
const ReplacementData &replacementData,
|
||||
@@ -868,69 +870,31 @@ void ClangdClient::closeExtraFile(const Utils::FilePath &filePath)
|
||||
void ClangdClient::findUsages(TextEditor::TextDocument *document, const QTextCursor &cursor,
|
||||
const Utils::optional<QString> &replacement)
|
||||
{
|
||||
// TODO: This will be wrong for e.g. operators. Use a Symbol info request to get the real symbol string.
|
||||
const QString searchTerm = d->searchTermFromCursor(cursor);
|
||||
if (searchTerm.isEmpty())
|
||||
// Quick check: Are we even on anything searchable?
|
||||
if (d->searchTermFromCursor(cursor).isEmpty())
|
||||
return;
|
||||
|
||||
ReferencesData refData;
|
||||
refData.key = d->nextJobId++;
|
||||
if (replacement) {
|
||||
ReplacementData replacementData;
|
||||
replacementData.oldSymbolName = searchTerm;
|
||||
replacementData.newSymbolName = *replacement;
|
||||
if (replacementData.newSymbolName.isEmpty())
|
||||
replacementData.newSymbolName = replacementData.oldSymbolName;
|
||||
refData.replacementData = replacementData;
|
||||
}
|
||||
refData.search = SearchResultWindow::instance()->startNewSearch(
|
||||
tr("C++ Usages:"),
|
||||
{},
|
||||
searchTerm,
|
||||
replacement ? SearchResultWindow::SearchAndReplace : SearchResultWindow::SearchOnly,
|
||||
SearchResultWindow::PreserveCaseDisabled,
|
||||
"CppEditor");
|
||||
if (refData.categorize)
|
||||
refData.search->setFilter(new CppTools::CppSearchResultFilter);
|
||||
if (refData.replacementData) {
|
||||
refData.search->setTextToReplace(refData.replacementData->newSymbolName);
|
||||
const auto renameFilesCheckBox = new QCheckBox;
|
||||
renameFilesCheckBox->setVisible(false);
|
||||
refData.search->setAdditionalReplaceWidget(renameFilesCheckBox);
|
||||
const auto renameHandler =
|
||||
[search = refData.search](const QString &newSymbolName,
|
||||
const QList<SearchResultItem> &checkedItems,
|
||||
bool preserveCase) {
|
||||
const auto replacementData = search->userData().value<ReplacementData>();
|
||||
Private::handleRenameRequest(search, replacementData, newSymbolName, checkedItems,
|
||||
preserveCase);
|
||||
};
|
||||
connect(refData.search, &SearchResult::replaceButtonClicked, renameHandler);
|
||||
}
|
||||
connect(refData.search, &SearchResult::activated, [](const SearchResultItem& item) {
|
||||
Core::EditorManager::openEditorAtSearchResult(item);
|
||||
});
|
||||
SearchResultWindow::instance()->popup(IOutputPane::ModeSwitch | IOutputPane::WithFocus);
|
||||
d->runningFindUsages.insert(refData.key, refData);
|
||||
|
||||
const Utils::optional<MessageId> requestId = symbolSupport().findUsages(
|
||||
document, cursor, [this, key = refData.key](const QList<Location> &locations) {
|
||||
d->handleFindUsagesResult(key, locations);
|
||||
});
|
||||
|
||||
if (!requestId) {
|
||||
d->finishSearch(refData, false);
|
||||
return;
|
||||
}
|
||||
connect(refData.search, &SearchResult::cancelled, this, [this, requestId, key = refData.key] {
|
||||
const auto refData = d->runningFindUsages.find(key);
|
||||
if (refData == d->runningFindUsages.end())
|
||||
// Get the proper spelling of the search term from clang, so we can put it into the
|
||||
// search widget.
|
||||
const TextDocumentIdentifier docId(DocumentUri::fromFilePath(document->filePath()));
|
||||
const TextDocumentPositionParams params(docId, Range(cursor).start());
|
||||
SymbolInfoRequest symReq(params);
|
||||
symReq.setResponseCallback([this, doc = QPointer(document), cursor, replacement]
|
||||
(const SymbolInfoRequest::Response &response) {
|
||||
if (!doc)
|
||||
return;
|
||||
cancelRequest(*requestId);
|
||||
refData->canceled = true;
|
||||
refData->search->disconnect(this);
|
||||
d->finishSearch(*refData, true);
|
||||
const auto result = response.result();
|
||||
if (!result)
|
||||
return;
|
||||
const auto list = Utils::get_if<QList<SymbolDetails>>(&result.value());
|
||||
if (!list || list->isEmpty())
|
||||
return;
|
||||
const SymbolDetails &sd = list->first();
|
||||
if (sd.name().isEmpty())
|
||||
return;
|
||||
d->findUsages(doc.data(), cursor, sd.name(), replacement);
|
||||
});
|
||||
sendContent(symReq);
|
||||
}
|
||||
|
||||
void ClangdClient::enableTesting() { d->isTesting = true; }
|
||||
@@ -971,6 +935,71 @@ QVersionNumber ClangdClient::versionNumber() const
|
||||
|
||||
CppTools::ClangdSettings::Data ClangdClient::settingsData() const { return d->settings; }
|
||||
|
||||
void ClangdClient::Private::findUsages(TextEditor::TextDocument *document,
|
||||
const QTextCursor &cursor, const QString &searchTerm,
|
||||
const Utils::optional<QString> &replacement)
|
||||
{
|
||||
ReferencesData refData;
|
||||
refData.key = nextJobId++;
|
||||
if (replacement) {
|
||||
ReplacementData replacementData;
|
||||
replacementData.oldSymbolName = searchTerm;
|
||||
replacementData.newSymbolName = *replacement;
|
||||
if (replacementData.newSymbolName.isEmpty())
|
||||
replacementData.newSymbolName = replacementData.oldSymbolName;
|
||||
refData.replacementData = replacementData;
|
||||
}
|
||||
|
||||
refData.search = SearchResultWindow::instance()->startNewSearch(
|
||||
tr("C++ Usages:"),
|
||||
{},
|
||||
searchTerm,
|
||||
replacement ? SearchResultWindow::SearchAndReplace : SearchResultWindow::SearchOnly,
|
||||
SearchResultWindow::PreserveCaseDisabled,
|
||||
"CppEditor");
|
||||
if (refData.categorize)
|
||||
refData.search->setFilter(new CppTools::CppSearchResultFilter);
|
||||
if (refData.replacementData) {
|
||||
refData.search->setTextToReplace(refData.replacementData->newSymbolName);
|
||||
const auto renameFilesCheckBox = new QCheckBox;
|
||||
renameFilesCheckBox->setVisible(false);
|
||||
refData.search->setAdditionalReplaceWidget(renameFilesCheckBox);
|
||||
const auto renameHandler =
|
||||
[search = refData.search](const QString &newSymbolName,
|
||||
const QList<SearchResultItem> &checkedItems,
|
||||
bool preserveCase) {
|
||||
const auto replacementData = search->userData().value<ReplacementData>();
|
||||
Private::handleRenameRequest(search, replacementData, newSymbolName, checkedItems,
|
||||
preserveCase);
|
||||
};
|
||||
connect(refData.search, &SearchResult::replaceButtonClicked, renameHandler);
|
||||
}
|
||||
connect(refData.search, &SearchResult::activated, [](const SearchResultItem& item) {
|
||||
Core::EditorManager::openEditorAtSearchResult(item);
|
||||
});
|
||||
SearchResultWindow::instance()->popup(IOutputPane::ModeSwitch | IOutputPane::WithFocus);
|
||||
runningFindUsages.insert(refData.key, refData);
|
||||
|
||||
const Utils::optional<MessageId> requestId = q->symbolSupport().findUsages(
|
||||
document, cursor, [this, key = refData.key](const QList<Location> &locations) {
|
||||
handleFindUsagesResult(key, locations);
|
||||
});
|
||||
|
||||
if (!requestId) {
|
||||
finishSearch(refData, false);
|
||||
return;
|
||||
}
|
||||
QObject::connect(refData.search, &SearchResult::cancelled, q, [this, requestId, key = refData.key] {
|
||||
const auto refData = runningFindUsages.find(key);
|
||||
if (refData == runningFindUsages.end())
|
||||
return;
|
||||
q->cancelRequest(*requestId);
|
||||
refData->canceled = true;
|
||||
refData->search->disconnect(q);
|
||||
finishSearch(*refData, true);
|
||||
});
|
||||
}
|
||||
|
||||
void ClangdClient::Private::handleFindUsagesResult(quint64 key, const QList<Location> &locations)
|
||||
{
|
||||
const auto refData = runningFindUsages.find(key);
|
||||
@@ -2217,7 +2246,7 @@ static void cleanupDisabledCode(TextEditor::HighlightingResults &results, QTextD
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wasInDisabled && (it == results.end()
|
||||
if (wasInDisabled && (it + 1 == results.end()
|
||||
|| (it + 1)->textStyles.mainStyle != TextEditor::C_DISABLED_CODE)) {
|
||||
// The #else or #endif that ends disabled code should not be disabled.
|
||||
it = results.erase(it);
|
||||
|
||||
@@ -358,9 +358,12 @@ ClangdTextMark::ClangdTextMark(const FilePath &filePath,
|
||||
setPriority(isError ? TextEditor::TextMark::HighPriority
|
||||
: TextEditor::TextMark::NormalPriority);
|
||||
setIcon(isError ? Icons::CODEMODEL_ERROR.icon() : Icons::CODEMODEL_WARNING.icon());
|
||||
setLineAnnotation(diagnostic.message());
|
||||
setColor(isError ? Theme::CodeModel_Error_TextMarkColor
|
||||
: Theme::CodeModel_Warning_TextMarkColor);
|
||||
if (client->project()) {
|
||||
setLineAnnotation(diagnostic.message());
|
||||
setColor(isError ? Theme::CodeModel_Error_TextMarkColor
|
||||
: Theme::CodeModel_Warning_TextMarkColor);
|
||||
ClangDiagnosticManager::addTask(m_diagnostic);
|
||||
}
|
||||
|
||||
// Copy to clipboard action
|
||||
QVector<QAction *> actions;
|
||||
@@ -387,8 +390,6 @@ ClangdTextMark::ClangdTextMark(const FilePath &filePath,
|
||||
}
|
||||
|
||||
setActions(actions);
|
||||
|
||||
ClangDiagnosticManager::addTask(m_diagnostic);
|
||||
}
|
||||
|
||||
bool ClangdTextMark::addToolTipContent(QLayout *target) const
|
||||
|
||||
@@ -947,7 +947,7 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
|
||||
QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(k);
|
||||
auto sdkLocation = bs->data(Android::Constants::SdkLocation).value<FilePath>();
|
||||
|
||||
if (qt->qtVersion() >= QtSupport::QtVersionNumber{6, 0, 0}) {
|
||||
if (qt && qt->qtVersion() >= QtSupport::QtVersionNumber{6, 0, 0}) {
|
||||
initialArgs.append("-DQT_HOST_PATH:PATH=%{Qt:QT_HOST_PREFIX}");
|
||||
initialArgs.append("-DANDROID_SDK_ROOT:PATH=" + sdkLocation.path());
|
||||
} else {
|
||||
@@ -956,7 +956,7 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id)
|
||||
}
|
||||
|
||||
const IDevice::ConstPtr device = DeviceKitAspect::device(k);
|
||||
if (device->osType() == Utils::OsTypeMac) {
|
||||
if (device && device->osType() == Utils::OsTypeMac) {
|
||||
if (isIos(k)) {
|
||||
QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(k);
|
||||
if (qt && qt->qtVersion().majorVersion >= 6) {
|
||||
|
||||
@@ -110,7 +110,8 @@ void ExecuteFilter::accept(LocatorFilterEntry selection,
|
||||
d.executable = value;
|
||||
} else {
|
||||
d.executable = value.left(pos);
|
||||
d.arguments = value.right(value.length() - pos - 1);
|
||||
d.arguments = Utils::globalMacroExpander()->expand(
|
||||
value.right(value.length() - pos - 1));
|
||||
}
|
||||
|
||||
if (m_process->state() != QProcess::NotRunning) {
|
||||
|
||||
@@ -253,6 +253,8 @@ QuickFixOperationTest::QuickFixOperationTest(const QList<QuickFixTestDocument::P
|
||||
// Check
|
||||
QString result = testDocument->m_editorWidget->document()->toPlainText();
|
||||
removeTrailingWhitespace(result);
|
||||
QEXPECT_FAIL("escape string literal: raw string literal", "FIXME", Continue);
|
||||
QEXPECT_FAIL("escape string literal: unescape adjacent literals", "FIXME", Continue);
|
||||
if (!expectedFailMessage.isEmpty())
|
||||
QEXPECT_FAIL("", expectedFailMessage.data(), Continue);
|
||||
else if (result != testDocument->m_expectedSource) {
|
||||
@@ -1750,6 +1752,26 @@ void CppEditorPlugin::test_quickfix_data()
|
||||
<< CppQuickFixFactoryPtr(new ConvertToCamelCase(true))
|
||||
<< _("void @WhAt_TODO_hErE();\n")
|
||||
<< _("void WhAtTODOHErE();\n");
|
||||
QTest::newRow("escape string literal: simple case")
|
||||
<< CppQuickFixFactoryPtr(new EscapeStringLiteral)
|
||||
<< _(R"(const char *str = @"àxyz";)")
|
||||
<< _(R"(const char *str = "\xc3\xa0xyz";)");
|
||||
QTest::newRow("escape string literal: simple case reverse")
|
||||
<< CppQuickFixFactoryPtr(new EscapeStringLiteral)
|
||||
<< _(R"(const char *str = @"\xc3\xa0xyz";)")
|
||||
<< _(R"(const char *str = "àxyz";)");
|
||||
QTest::newRow("escape string literal: raw string literal")
|
||||
<< CppQuickFixFactoryPtr(new EscapeStringLiteral)
|
||||
<< _(R"x(const char *str = @R"(àxyz)";)x")
|
||||
<< _(R"x(const char *str = R"(\xc3\xa0xyz)";)x");
|
||||
QTest::newRow("escape string literal: splitting required")
|
||||
<< CppQuickFixFactoryPtr(new EscapeStringLiteral)
|
||||
<< _(R"(const char *str = @"àf23бgб1";)")
|
||||
<< _(R"(const char *str = "\xc3\xa0""f23\xd0\xb1g\xd0\xb1""1";)");
|
||||
QTest::newRow("escape string literal: unescape adjacent literals")
|
||||
<< CppQuickFixFactoryPtr(new EscapeStringLiteral)
|
||||
<< _(R"(const char *str = @"\xc3\xa0""f23\xd0\xb1g\xd0\xb1""1";)")
|
||||
<< _(R"(const char *str = "àf23бgб1";)");
|
||||
}
|
||||
|
||||
void CppEditorPlugin::test_quickfix()
|
||||
|
||||
@@ -7079,17 +7079,25 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
static QByteArray escapeString(const QByteArray &contents)
|
||||
static QByteArrayList escapeString(const QByteArray &contents)
|
||||
{
|
||||
QByteArray newContents;
|
||||
QByteArrayList newContents;
|
||||
QByteArray chunk;
|
||||
bool wasEscaped = false;
|
||||
for (const quint8 c : contents) {
|
||||
if (isascii(c) && isprint(c)) {
|
||||
newContents += c;
|
||||
} else {
|
||||
newContents += QByteArray("\\x") +
|
||||
QByteArray::number(c, 16).rightJustified(2, '0');
|
||||
const bool needsEscape = !isascii(c) || !isprint(c);
|
||||
if (!needsEscape && wasEscaped && std::isxdigit(c) && !chunk.isEmpty()) {
|
||||
newContents << chunk;
|
||||
chunk.clear();
|
||||
}
|
||||
if (needsEscape)
|
||||
chunk += QByteArray("\\x") + QByteArray::number(c, 16).rightJustified(2, '0');
|
||||
else
|
||||
chunk += c;
|
||||
wasEscaped = needsEscape;
|
||||
}
|
||||
if (!chunk.isEmpty())
|
||||
newContents << chunk;
|
||||
return newContents;
|
||||
}
|
||||
|
||||
@@ -7154,25 +7162,35 @@ public:
|
||||
QTC_ASSERT(stringLiteral, return);
|
||||
const QByteArray oldContents(currentFile->tokenAt(stringLiteral->literal_token).
|
||||
identifier->chars());
|
||||
QByteArray newContents;
|
||||
QByteArrayList newContents;
|
||||
if (m_escape)
|
||||
newContents = escapeString(oldContents);
|
||||
else
|
||||
newContents = unescapeString(oldContents);
|
||||
newContents = {unescapeString(oldContents)};
|
||||
|
||||
if (oldContents != newContents) {
|
||||
// Check UTF-8 byte array is correct or not.
|
||||
QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8");
|
||||
QScopedPointer<QTextDecoder> decoder(utf8codec->makeDecoder());
|
||||
const QString str = decoder->toUnicode(newContents);
|
||||
const QByteArray utf8buf = str.toUtf8();
|
||||
if (utf8codec->canEncode(str) && newContents == utf8buf) {
|
||||
ChangeSet changes;
|
||||
changes.replace(startPos + 1, endPos - 1, str);
|
||||
currentFile->setChangeSet(changes);
|
||||
currentFile->apply();
|
||||
}
|
||||
if (newContents.isEmpty()
|
||||
|| (newContents.size() == 1 && newContents.first() == oldContents)) {
|
||||
return;
|
||||
}
|
||||
|
||||
QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8");
|
||||
QScopedPointer<QTextDecoder> decoder(utf8codec->makeDecoder());
|
||||
ChangeSet changes;
|
||||
|
||||
bool replace = true;
|
||||
for (const QByteArray &chunk : qAsConst(newContents)) {
|
||||
const QString str = decoder->toUnicode(chunk);
|
||||
const QByteArray utf8buf = str.toUtf8();
|
||||
if (!utf8codec->canEncode(str) || chunk != utf8buf)
|
||||
return;
|
||||
if (replace)
|
||||
changes.replace(startPos + 1, endPos - 1, str);
|
||||
else
|
||||
changes.insert(endPos, "\"" + str + "\"");
|
||||
replace = false;
|
||||
}
|
||||
currentFile->setChangeSet(changes);
|
||||
currentFile->apply();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -210,7 +210,13 @@ void SemanticHighlighter::onHighlighterResultAvailable(int from, int to)
|
||||
}
|
||||
QTC_ASSERT(paren.pos != -1, continue);
|
||||
paren.source = parenSource();
|
||||
parentheses.second << paren;
|
||||
|
||||
static const auto posCmp = [](const Parenthesis &p1, const Parenthesis &p2) {
|
||||
return p1.pos < p2.pos;
|
||||
};
|
||||
const auto it = std::lower_bound(parentheses.second.begin(), parentheses.second.end(),
|
||||
paren, posCmp);
|
||||
parentheses.second.insert(it, paren);
|
||||
}
|
||||
if (parentheses.first.isValid())
|
||||
TextDocumentLayout::setParentheses(parentheses.first, parentheses.second);
|
||||
|
||||
@@ -84,13 +84,26 @@ public:
|
||||
}.attachTo(this);
|
||||
}
|
||||
|
||||
void apply() final { m_group.apply(); m_group.writeSettings(ICore::settings()); }
|
||||
void apply() final;
|
||||
void finish() final { m_group.finish(); }
|
||||
|
||||
private:
|
||||
AspectContainer &m_group = debuggerSettings()->page1;
|
||||
};
|
||||
|
||||
void CommonOptionsPageWidget::apply()
|
||||
{
|
||||
const DebuggerSettings *s = debuggerSettings();
|
||||
const bool originalPostMortem = s->registerForPostMortem->value();
|
||||
const bool currentPostMortem = s->registerForPostMortem->volatileValue().toBool();
|
||||
// explicitly trigger setValue() to override the setValueSilently() and trigger the registration
|
||||
if (originalPostMortem != currentPostMortem)
|
||||
s->registerForPostMortem->setValue(currentPostMortem);
|
||||
|
||||
m_group.apply();
|
||||
m_group.writeSettings(ICore::settings());
|
||||
}
|
||||
|
||||
CommonOptionsPage::CommonOptionsPage()
|
||||
{
|
||||
setId(DEBUGGER_COMMON_SETTINGS_ID);
|
||||
|
||||
@@ -161,7 +161,7 @@ static QMap<qint64, QString> getLocalProcessDataUsingPs(const QString &column)
|
||||
psProcess.start();
|
||||
if (psProcess.waitForStarted()) {
|
||||
QByteArray output;
|
||||
if (psProcess.readDataFromProcess(30000, &output, nullptr, false)) {
|
||||
if (psProcess.readDataFromProcess(30, &output, nullptr, false)) {
|
||||
// Split "457 /Users/foo.app arg1 arg2"
|
||||
const QStringList lines = QString::fromLocal8Bit(output).split(QLatin1Char('\n'));
|
||||
const int lineCount = lines.size();
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>373</width>
|
||||
<height>282</height>
|
||||
<width>550</width>
|
||||
<height>400</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
||||
@@ -134,6 +134,7 @@ public:
|
||||
play,
|
||||
plus,
|
||||
promote,
|
||||
readOnly,
|
||||
redo,
|
||||
rotationFill,
|
||||
rotationOutline,
|
||||
@@ -145,6 +146,7 @@ public:
|
||||
testIcon,
|
||||
textAlignBottom,
|
||||
textAlignCenter,
|
||||
textAlignJustified,
|
||||
textAlignLeft,
|
||||
textAlignMiddle,
|
||||
textAlignRight,
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
#include <synchronousimagecache.h>
|
||||
#include <theme.h>
|
||||
#include <hdrimage.h>
|
||||
#include <designersettings.h>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
@@ -39,6 +42,8 @@
|
||||
#include <QMetaProperty>
|
||||
#include <QPainter>
|
||||
#include <QRawFont>
|
||||
#include <QMessageBox>
|
||||
#include <QCheckBox>
|
||||
#include <utils/stylehelper.h>
|
||||
#include <utils/filesystemwatcher.h>
|
||||
|
||||
@@ -94,6 +99,41 @@ void ItemLibraryAssetsModel::toggleExpandAll(bool expand)
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void ItemLibraryAssetsModel::removeFile(const QString &filePath)
|
||||
{
|
||||
bool askBeforeDelete = DesignerSettings::getValue(
|
||||
DesignerSettingsKey::ASK_BEFORE_DELETING_ASSET).toBool();
|
||||
bool assetDelete = true;
|
||||
|
||||
if (askBeforeDelete) {
|
||||
QMessageBox msg(QMessageBox::Question, tr("Confirm Delete File"),
|
||||
tr("\"%1\" might be in use. Delete anyway?").arg(filePath),
|
||||
QMessageBox::No | QMessageBox::Yes);
|
||||
QCheckBox cb;
|
||||
cb.setText(tr("Do not ask this again"));
|
||||
msg.setCheckBox(&cb);
|
||||
int ret = msg.exec();
|
||||
|
||||
if (ret == QMessageBox::No)
|
||||
assetDelete = false;
|
||||
|
||||
if (cb.isChecked())
|
||||
DesignerSettings::setValue(DesignerSettingsKey::ASK_BEFORE_DELETING_ASSET, false);
|
||||
}
|
||||
|
||||
if (assetDelete) {
|
||||
if (!QFile::exists(filePath)) {
|
||||
QMessageBox::warning(Core::ICore::dialogParent(),
|
||||
tr("Failed to Locate File"),
|
||||
tr("Could not find \"%1\".").arg(filePath));
|
||||
} else if (!QFile::remove(filePath)) {
|
||||
QMessageBox::warning(Core::ICore::dialogParent(),
|
||||
tr("Failed to Delete File"),
|
||||
tr("Could not delete \"%1\".").arg(filePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QStringList &ItemLibraryAssetsModel::supportedImageSuffixes()
|
||||
{
|
||||
static QStringList retList;
|
||||
|
||||
@@ -81,6 +81,7 @@ public:
|
||||
|
||||
Q_INVOKABLE void toggleExpandAll(bool expand);
|
||||
Q_INVOKABLE DirExpandState getAllExpandedState() const;
|
||||
Q_INVOKABLE void removeFile(const QString &filePath);
|
||||
|
||||
private:
|
||||
SynchronousImageCache &m_fontImageCache;
|
||||
|
||||
@@ -81,6 +81,7 @@ void DesignerSettings::fromSettings(QSettings *settings)
|
||||
restoreValue(settings, DesignerSettingsKey::COLOR_PALETTE_FAVORITE, QStringList());
|
||||
restoreValue(settings, DesignerSettingsKey::ALWAYS_DESIGN_MODE, true);
|
||||
restoreValue(settings, DesignerSettingsKey::DISABLE_ITEM_LIBRARY_UPDATE_TIMER, true);
|
||||
restoreValue(settings, DesignerSettingsKey::ASK_BEFORE_DELETING_ASSET, true);
|
||||
|
||||
settings->endGroup();
|
||||
settings->endGroup();
|
||||
|
||||
@@ -71,6 +71,7 @@ const char COLOR_PALETTE_RECENT[] = "ColorPaletteRecent";
|
||||
const char COLOR_PALETTE_FAVORITE[] = "ColorPaletteFavorite";
|
||||
const char ALWAYS_DESIGN_MODE[] = "AlwaysDesignMode";
|
||||
const char DISABLE_ITEM_LIBRARY_UPDATE_TIMER[] = "DisableItemLibraryUpdateTimer";
|
||||
const char ASK_BEFORE_DELETING_ASSET[] = "AskBeforeDeletingAsset";
|
||||
}
|
||||
|
||||
class QMLDESIGNERCORE_EXPORT DesignerSettings : public QHash<QByteArray, QVariant>
|
||||
|
||||
@@ -178,6 +178,8 @@ DesignerSettings SettingsPageWidget::settings() const
|
||||
m_ui.featureTimelineEditorCheckBox->isChecked());
|
||||
settings.insert(DesignerSettingsKey::ALWAYS_DESIGN_MODE,
|
||||
m_ui.designerAlwaysDesignModeCheckBox->isChecked());
|
||||
settings.insert(DesignerSettingsKey::ASK_BEFORE_DELETING_ASSET,
|
||||
m_ui.askBeforeDeletingAssetCheckBox->isChecked());
|
||||
|
||||
return settings;
|
||||
}
|
||||
@@ -247,6 +249,8 @@ void SettingsPageWidget::setSettings(const DesignerSettings &settings)
|
||||
DesignerSettingsKey::ALWAYS_DESIGN_MODE).toBool());
|
||||
m_ui.featureTimelineEditorCheckBox->setChecked(settings.value(
|
||||
DesignerSettingsKey::ENABLE_TIMELINEVIEW).toBool());
|
||||
m_ui.askBeforeDeletingAssetCheckBox->setChecked(settings.value(
|
||||
DesignerSettingsKey::ASK_BEFORE_DELETING_ASSET).toBool());
|
||||
|
||||
if (settings.value(DesignerSettingsKey::STANDALONE_MODE).toBool()) {
|
||||
m_ui.debugGroupBox->hide();
|
||||
|
||||
@@ -416,6 +416,13 @@
|
||||
<string>Features</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="featureTimelineEditorCheckBox">
|
||||
<property name="text">
|
||||
<string>Enable Timeline editor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="designerAlwaysDesignModeCheckBox">
|
||||
<property name="text">
|
||||
@@ -423,10 +430,10 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="featureTimelineEditorCheckBox">
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="askBeforeDeletingAssetCheckBox">
|
||||
<property name="text">
|
||||
<string>Enable Timeline editor</string>
|
||||
<string>Ask for confirmation before deleting asset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -157,6 +157,7 @@ void FileDownloader::start()
|
||||
m_url = reply->url();
|
||||
start();
|
||||
} else {
|
||||
qDebug() << Q_FUNC_INFO << m_url << reply->errorString();
|
||||
emit downloadFailed();
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
#
|
||||
# Internal Qt Creator variable reference
|
||||
#
|
||||
set(__just_reference_QT_QMAKE_EXECUTABLE ${QT_QMAKE_EXECUTABLE})
|
||||
|
||||
if (EXISTS "${CMAKE_SOURCE_DIR}/QtCreatorPackageManager.cmake")
|
||||
include("${CMAKE_SOURCE_DIR}/QtCreatorPackageManager.cmake")
|
||||
endif()
|
||||
|
||||
Submodule src/shared/qbs updated: ea0e25b4ca...80952f4f23
@@ -178,6 +178,14 @@ def substituteTildeWithinToolchains(settingsDir):
|
||||
__substitute__(toolchains, "~", home)
|
||||
test.log("Substituted all tildes with '%s' inside toolchains.xml..." % home)
|
||||
|
||||
|
||||
def substituteTildeWithinQtVersion(settingsDir):
|
||||
toolchains = os.path.join(settingsDir, "QtProject", 'qtcreator', 'qtversion.xml')
|
||||
home = os.path.expanduser("~")
|
||||
__substitute__(toolchains, "~", home)
|
||||
test.log("Substituted all tildes with '%s' inside qtversion.xml..." % home)
|
||||
|
||||
|
||||
def substituteDefaultCompiler(settingsDir):
|
||||
compiler = None
|
||||
if platform.system() == 'Darwin':
|
||||
@@ -309,6 +317,7 @@ def copySettingsToTmpDir(destination=None, omitFiles=[]):
|
||||
shutil.copy(os.path.join(r, ff), currentPath)
|
||||
if platform.system() in ('Linux', 'Darwin'):
|
||||
substituteTildeWithinToolchains(tmpSettingsDir)
|
||||
substituteTildeWithinQtVersion(tmpSettingsDir)
|
||||
substituteDefaultCompiler(tmpSettingsDir)
|
||||
elif platform.system() in ('Windows', 'Microsoft'):
|
||||
substituteCdb(tmpSettingsDir)
|
||||
|
||||
@@ -64,11 +64,11 @@ def performTest(workingDir, projectName, availableConfigs):
|
||||
for kit, config in availableConfigs:
|
||||
# switching from MSVC to MinGW build will fail on the clean step of 'Rebuild All Projects'
|
||||
# because of differences between MSVC's and MinGW's Makefile (so clean before changing kit)
|
||||
invokeMenuItem('Build', 'Clean Project "%s"' % projectName)
|
||||
selectFromLocator("t clean", "Clean (Clean Project)")
|
||||
verifyBuildConfig(kit, config, True, True, True)
|
||||
test.log("Selected kit '%s'" % Targets.getStringForTarget(kit))
|
||||
# explicitly build before start debugging for adding the executable as allowed program to WinFW
|
||||
invokeMenuItem("Build", "Rebuild All Projects")
|
||||
selectFromLocator("t rebuild", "Rebuild (Rebuild All Projects)")
|
||||
waitForCompile()
|
||||
if not checkCompile():
|
||||
test.fatal("Compile had errors... Skipping current build config")
|
||||
|
||||
Reference in New Issue
Block a user