forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/7.0'
Conflicts: cmake/QtCreatorIDEBranding.cmake qbs/modules/qtc/qtc.qbs qtcreator_ide_branding.pri src/plugins/studiowelcome/recentpresets.h src/plugins/studiowelcome/userpresets.h Change-Id: Ie573b945eb28347a36ee1b3582fbd6ab0c0f866c
This commit is contained in:
2
dist/changes-7.0.0.md
vendored
2
dist/changes-7.0.0.md
vendored
@@ -190,6 +190,8 @@ Platforms
|
|||||||
|
|
||||||
### Android
|
### Android
|
||||||
|
|
||||||
|
* Improved monitoring for connected devices by using `track-devices` command and
|
||||||
|
file watching instead of polling (QTCREATORBUG-23991)
|
||||||
* Added option for default NDK (QTCREATORBUG-21755, QTCREATORBUG-22389,
|
* Added option for default NDK (QTCREATORBUG-21755, QTCREATORBUG-22389,
|
||||||
QTCREATORBUG-24248, QTCREATORBUG-26281)
|
QTCREATORBUG-24248, QTCREATORBUG-26281)
|
||||||
* Fixed that `Include prebuilt OpenSSL libraries` could add it to the wrong
|
* Fixed that `Include prebuilt OpenSSL libraries` could add it to the wrong
|
||||||
|
@@ -185,13 +185,13 @@ void registerNodeInstanceMetaObject(QObject *object, QQmlEngine *engine)
|
|||||||
QQuickDesignerSupportProperties::registerNodeInstanceMetaObject(object, engine);
|
QQuickDesignerSupportProperties::registerNodeInstanceMetaObject(object, engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isQuickStyleItemMetaObject(const QMetaObject *metaObject)
|
static bool isMetaObjectofType(const QMetaObject *metaObject, const QByteArray &type)
|
||||||
{
|
{
|
||||||
if (metaObject) {
|
if (metaObject) {
|
||||||
if (metaObject->className() == QByteArrayLiteral("QQuickStyleItem"))
|
if (metaObject->className() == type)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return isQuickStyleItemMetaObject(metaObject->superClass());
|
return isMetaObjectofType(metaObject->superClass(), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -200,7 +200,15 @@ static bool isQuickStyleItemMetaObject(const QMetaObject *metaObject)
|
|||||||
static bool isQuickStyleItem(QObject *object)
|
static bool isQuickStyleItem(QObject *object)
|
||||||
{
|
{
|
||||||
if (object)
|
if (object)
|
||||||
return isQuickStyleItemMetaObject(object->metaObject());
|
return isMetaObjectofType(object->metaObject(), "QQuickStyleItem");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isDelegateModel(QObject *object)
|
||||||
|
{
|
||||||
|
if (object)
|
||||||
|
return isMetaObjectofType(object->metaObject(), "QQmlDelegateModel");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -400,7 +408,7 @@ void doComponentCompleteRecursive(QObject *object, NodeInstanceServer *nodeInsta
|
|||||||
doComponentCompleteRecursive(child, nodeInstanceServer);
|
doComponentCompleteRecursive(child, nodeInstanceServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isQuickStyleItem(item)) {
|
if (!isQuickStyleItem(object) && !isDelegateModel(object)) {
|
||||||
if (item) {
|
if (item) {
|
||||||
static_cast<QQmlParserStatus *>(item)->componentComplete();
|
static_cast<QQmlParserStatus *>(item)->componentComplete();
|
||||||
} else {
|
} else {
|
||||||
|
@@ -665,15 +665,23 @@ Item {
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
|
|
||||||
|
property bool allowTooltip: true
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
|
||||||
onExited: tooltipBackend.hideTooltip()
|
onExited: tooltipBackend.hideTooltip()
|
||||||
onCanceled: tooltipBackend.hideTooltip()
|
onEntered: allowTooltip = true
|
||||||
|
onCanceled: {
|
||||||
|
tooltipBackend.hideTooltip()
|
||||||
|
allowTooltip = true
|
||||||
|
}
|
||||||
onPositionChanged: tooltipBackend.reposition()
|
onPositionChanged: tooltipBackend.reposition()
|
||||||
onPressed: (mouse)=> {
|
onPressed: (mouse)=> {
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
|
allowTooltip = false
|
||||||
|
tooltipBackend.hideTooltip()
|
||||||
var ctrlDown = mouse.modifiers & Qt.ControlModifier
|
var ctrlDown = mouse.modifiers & Qt.ControlModifier
|
||||||
if (mouse.button === Qt.LeftButton) {
|
if (mouse.button === Qt.LeftButton) {
|
||||||
if (!root.selectedAssets[filePath] && !ctrlDown)
|
if (!root.selectedAssets[filePath] && !ctrlDown)
|
||||||
@@ -698,12 +706,12 @@ Item {
|
|||||||
root.contextDir = model.fileDir
|
root.contextDir = model.fileDir
|
||||||
root.isDirContextMenu = false
|
root.isDirContextMenu = false
|
||||||
|
|
||||||
tooltipBackend.hideTooltip()
|
|
||||||
contextMenu.popup()
|
contextMenu.popup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onReleased: (mouse)=> {
|
onReleased: (mouse)=> {
|
||||||
|
allowTooltip = true
|
||||||
if (mouse.button === Qt.LeftButton) {
|
if (mouse.button === Qt.LeftButton) {
|
||||||
if (!(mouse.modifiers & Qt.ControlModifier))
|
if (!(mouse.modifiers & Qt.ControlModifier))
|
||||||
root.selectedAssets = {}
|
root.selectedAssets = {}
|
||||||
@@ -720,7 +728,7 @@ Item {
|
|||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
interval: 1000
|
interval: 1000
|
||||||
running: mouseArea.containsMouse
|
running: mouseArea.containsMouse && mouseArea.allowTooltip
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (suffix === ".ttf" || suffix === ".otf") {
|
if (suffix === ".ttf" || suffix === ".otf") {
|
||||||
tooltipBackend.name = fileName
|
tooltipBackend.name = fileName
|
||||||
|
@@ -88,6 +88,8 @@ Item {
|
|||||||
|
|
||||||
onShowContextMenu: delegateRoot.showContextMenu()
|
onShowContextMenu: delegateRoot.showContextMenu()
|
||||||
onPressed: (mouse)=> {
|
onPressed: (mouse)=> {
|
||||||
|
allowTooltip = false
|
||||||
|
hide()
|
||||||
if (mouse.button === Qt.LeftButton)
|
if (mouse.button === Qt.LeftButton)
|
||||||
rootView.startDragAndDrop(itemLibraryEntry, mapToGlobal(mouse.x, mouse.y))
|
rootView.startDragAndDrop(itemLibraryEntry, mapToGlobal(mouse.x, mouse.y))
|
||||||
}
|
}
|
||||||
|
@@ -222,6 +222,8 @@ ScrollView {
|
|||||||
: Qt.ArrowCursor
|
: Qt.ArrowCursor
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
delegate.GridView.view.currentIndex = index
|
||||||
|
|
||||||
removePresetDialog.presetName = presetName.text
|
removePresetDialog.presetName = presetName.text
|
||||||
removePresetDialog.open()
|
removePresetDialog.open()
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,8 @@ import HelperWidgets 2.0
|
|||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
|
|
||||||
|
property bool allowTooltip: true
|
||||||
|
|
||||||
signal showContextMenu()
|
signal showContextMenu()
|
||||||
|
|
||||||
function hide()
|
function hide()
|
||||||
@@ -38,7 +40,12 @@ MouseArea {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onExited: tooltipBackend.hideTooltip()
|
onExited: tooltipBackend.hideTooltip()
|
||||||
onCanceled: tooltipBackend.hideTooltip()
|
onEntered: allowTooltip = true
|
||||||
|
onCanceled: {
|
||||||
|
tooltipBackend.hideTooltip()
|
||||||
|
allowTooltip = true
|
||||||
|
}
|
||||||
|
onReleased: allowTooltip = true
|
||||||
onPositionChanged: tooltipBackend.reposition()
|
onPositionChanged: tooltipBackend.reposition()
|
||||||
onClicked: function(mouse) {
|
onClicked: function(mouse) {
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
@@ -51,7 +58,7 @@ MouseArea {
|
|||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
interval: 1000
|
interval: 1000
|
||||||
running: mouseArea.containsMouse
|
running: mouseArea.containsMouse && mouseArea.allowTooltip
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
tooltipBackend.name = itemName
|
tooltipBackend.name = itemName
|
||||||
tooltipBackend.path = componentPath
|
tooltipBackend.path = componentPath
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
Metadata {
|
Metadata {
|
||||||
id: metadataFile
|
id: metadataFile
|
||||||
|
|
||||||
defaultVersion: v20
|
defaultVersion: v21
|
||||||
|
|
||||||
VersionData {
|
VersionData {
|
||||||
id: v14
|
id: v14
|
||||||
@@ -58,4 +58,10 @@ Metadata {
|
|||||||
name: "Qt for MCUs 2.0"
|
name: "Qt for MCUs 2.0"
|
||||||
path: "qul-20.qml"
|
path: "qul-20.qml"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VersionData {
|
||||||
|
id: v21
|
||||||
|
name: "Qt for MCUs 2.1"
|
||||||
|
path: "qul-21.qml"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
224
share/qtcreator/qmldesigner/qt4mcu/qul-21.qml
Normal file
224
share/qtcreator/qmldesigner/qt4mcu/qul-21.qml
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
//differences from 2.0:
|
||||||
|
//text.elide is introduced in QUL
|
||||||
|
|
||||||
|
VersionData {
|
||||||
|
name: "Qt for MCUs 2.1"
|
||||||
|
|
||||||
|
bannedItems: ["QtQuick.AnimatedImage",
|
||||||
|
"QtQuick.FocusScope",
|
||||||
|
"QtQuick.TextInput",
|
||||||
|
"QtQuick.TextEdit",
|
||||||
|
"QtQuick.Flow",
|
||||||
|
"QtQuick.Grid",
|
||||||
|
"QtQuick.GridView",
|
||||||
|
"QtQuick.PathView",
|
||||||
|
"QtQuick.Loader",
|
||||||
|
"QtQuick.Controls",
|
||||||
|
"QtQuick.Controls.BusyIndicator",
|
||||||
|
"QtQuick.Controls.ButtonGroup",
|
||||||
|
"QtQuick.Controls.CheckDelegate",
|
||||||
|
"QtQuick.Controls.Container",
|
||||||
|
"QtQuick.Controls.ComboBox",
|
||||||
|
"QtQuick.Controls.DelayButton",
|
||||||
|
"QtQuick.Controls.Frame",
|
||||||
|
"QtQuick.Controls.GroupBox",
|
||||||
|
"QtQuick.Controls.ItemDelegate",
|
||||||
|
"QtQuick.Controls.Label",
|
||||||
|
"QtQuick.Controls.Page",
|
||||||
|
"QtQuick.Controls.PageIndicator",
|
||||||
|
"QtQuick.Controls.Pane",
|
||||||
|
"QtQuick.Controls.RadioDelegate",
|
||||||
|
"QtQuick.Controls.RangeSlider",
|
||||||
|
"QtQuick.Controls.RoundButton",
|
||||||
|
"QtQuick.Controls.ScrollView",
|
||||||
|
"QtQuick.Controls.SpinBox",
|
||||||
|
"QtQuick.Controls.StackView",
|
||||||
|
"QtQuick.Controls.SwipeDelegate",
|
||||||
|
"QtQuick.Controls.SwitchDelegate",
|
||||||
|
"QtQuick.Controls.ToolBar",
|
||||||
|
"QtQuick.Controls.ToolButton",
|
||||||
|
"QtQuick.Controls.TabBar",
|
||||||
|
"QtQuick.Controls.TabButton",
|
||||||
|
"QtQuick.Controls.TextArea",
|
||||||
|
"QtQuick.Controls.TextField",
|
||||||
|
"QtQuick.Controls.ToolSeparator",
|
||||||
|
"QtQuick.Controls.Tumbler",
|
||||||
|
"QtQuick.Shapes.ConicalGradient",
|
||||||
|
"QtQuick.Shapes.LinearGradient",
|
||||||
|
"QtQuick.Shapes.RadialGradient",
|
||||||
|
"QtQuick.Shapes.ShapeGradient"]
|
||||||
|
|
||||||
|
allowedImports: ["QtQuick",
|
||||||
|
"QtQuick.Shapes",
|
||||||
|
"QtQuick.Controls",
|
||||||
|
"QtQuick.Timeline",
|
||||||
|
"QtQuickUltralite.Extras",
|
||||||
|
"QtQuickUltralite.Layers"]
|
||||||
|
|
||||||
|
bannedImports: ["FlowView"]
|
||||||
|
|
||||||
|
//ComplexProperty is not a type, it's just a way to handle bigger props
|
||||||
|
ComplexProperty {
|
||||||
|
prefix: "font"
|
||||||
|
bannedProperties: ["wordSpacing", "letterSpacing", "hintingPreference",
|
||||||
|
"kerning", "preferShaping", "capitalization",
|
||||||
|
"strikeout", "underline", "styleName"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.Item {
|
||||||
|
bannedProperties: ["layer", "opacity", "smooth", "antialiasing",
|
||||||
|
"baselineOffset", "focus", "activeFocusOnTab",
|
||||||
|
"rotation", "scale", "transformOrigin"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.Rectangle {
|
||||||
|
bannedProperties: ["gradient", "border"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.Flickable {
|
||||||
|
bannedProperties: ["boundsBehavior", "boundsMovement", "flickDeceleration",
|
||||||
|
"flickableDirection", "leftMargin", "rightMargin", "bottomMargin", "topMargin",
|
||||||
|
"originX", "originY", "pixelAligned", "pressDelay", "synchronousDrag"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.MouseArea {
|
||||||
|
bannedProperties: ["propagateComposedEvents", "preventStealing", "cursorShape",
|
||||||
|
"scrollGestureEnabled", "drag", "acceptedButtons", "hoverEnabled"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.Image {
|
||||||
|
allowChildren: false
|
||||||
|
allowedProperties: ["rotation", "scale", "transformOrigin"]
|
||||||
|
bannedProperties: ["mirror", "mipmap", "cache", "autoTransform", "asynchronous",
|
||||||
|
"sourceSize", "smooth"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.BorderImage {
|
||||||
|
bannedProperties: ["asynchronous", "cache", "currentFrame", "frameCount",
|
||||||
|
"horizontalTileMode", "mirror", "progress", "smooth", "sourceSize",
|
||||||
|
"status", "verticalTileMode"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.Text {
|
||||||
|
allowChildren: false
|
||||||
|
allowedProperties: ["rotation", "scale", "transformOrigin"]
|
||||||
|
bannedProperties: ["lineHeight", "lineHeightMode", "wrapMode", "style",
|
||||||
|
"styleColor", "minimumPointSize", "minimumPixelSize",
|
||||||
|
"fontSizeMode", "renderType", "renderTypeQuality", "textFormat", "maximumLineCount"]
|
||||||
|
}
|
||||||
|
|
||||||
|
//Padding is not an actual item, but rather set of properties in Text
|
||||||
|
Padding {
|
||||||
|
bannedProperties: ["bottomPadding", "topPadding", "leftPadding", "rightPadding"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.Column {
|
||||||
|
bannedProperties: ["bottomPadding", "leftPadding", "rightPadding", "topPadding"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.Row {
|
||||||
|
bannedProperties: ["bottomPadding", "leftPadding", "rightPadding", "topPadding",
|
||||||
|
"effectiveLayoutDirection", "layoutDirection"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.ListView {
|
||||||
|
bannedProperties: ["cacheBuffer", "highlightRangeMode", "highlightMoveDuration",
|
||||||
|
"highlightResizeDuration", "preferredHighlightBegin", "layoutDirection",
|
||||||
|
"preferredHighlightEnd", "highlightFollowsCurrentItem", "keyNavigationWraps",
|
||||||
|
"snapMode", "highlightMoveVelocity", "highlightResizeVelocity"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.Animation {
|
||||||
|
bannedProperties: ["paused"]
|
||||||
|
}
|
||||||
|
|
||||||
|
//Quick Controls2 Items and properties:
|
||||||
|
|
||||||
|
QtQuick.Controls.Control {
|
||||||
|
bannedProperties: ["focusPolicy", "hoverEnabled", "wheelEnabled"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.Controls.AbstractButton {
|
||||||
|
bannedProperties: ["display", "autoExclusive"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.Controls.ProgressBar {
|
||||||
|
bannedProperties: ["indeterminate"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.Controls.Slider {
|
||||||
|
bannedProperties: ["live", "snapMode", "touchDragThreshold"]
|
||||||
|
}
|
||||||
|
|
||||||
|
//Path and Shapes related:
|
||||||
|
|
||||||
|
QtQuick.Path {
|
||||||
|
bannedProperties: ["scale", "pathElements"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.PathArc {
|
||||||
|
bannedProperties: ["relativeX", "relativeY"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.PathLine {
|
||||||
|
bannedProperties: ["relativeX", "relativeY"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.PathMove {
|
||||||
|
bannedProperties: ["relativeX", "relativeY"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.PathQuad {
|
||||||
|
bannedProperties: ["relativeX", "relativeY",
|
||||||
|
"relativeControlX", "relativeControlY"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.PathCubic {
|
||||||
|
bannedProperties: ["relativeX", "relativeY",
|
||||||
|
"relativeControl1X", "relativeControl1Y",
|
||||||
|
"relativeControl2X", "relativeControl2Y"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.PathElement {
|
||||||
|
//nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.PathSvg {
|
||||||
|
//nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.Shapes.Shape {
|
||||||
|
bannedProperties: ["asynchronous", "containsMode", "data",
|
||||||
|
"renderType", "status", "vendorExtensionsEnabled"]
|
||||||
|
}
|
||||||
|
|
||||||
|
QtQuick.Shapes.ShapePath {
|
||||||
|
bannedProperties: ["dashOffset", "dashPattern",
|
||||||
|
"fillGradient", "strokeStyle"]
|
||||||
|
}
|
||||||
|
}
|
@@ -161,7 +161,7 @@ FocusScope {
|
|||||||
Text {
|
Text {
|
||||||
text: "+"
|
text: "+"
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
anchors.verticalCenterOffset: -16
|
anchors.verticalCenterOffset: -(5 + (font.pixelSize - 35) / 9)
|
||||||
font.pixelSize: parent.height * .5
|
font.pixelSize: parent.height * .5
|
||||||
color: Qt.lighter(StudioTheme.Values.themeControlBackgroundInteraction, addState.containsMouse ? 1.5 : 1)
|
color: Qt.lighter(StudioTheme.Values.themeControlBackgroundInteraction, addState.containsMouse ? 1.5 : 1)
|
||||||
}
|
}
|
||||||
|
@@ -570,7 +570,8 @@ public:
|
|||||||
"x", "y", "opacity", "parent", "item", "flow",
|
"x", "y", "opacity", "parent", "item", "flow",
|
||||||
"color", "margin", "padding", "print", "border", "font",
|
"color", "margin", "padding", "print", "border", "font",
|
||||||
"text", "source", "state", "visible", "focus", "data",
|
"text", "source", "state", "visible", "focus", "data",
|
||||||
"clip", "layer", "scale", "enabled", "anchors"})
|
"clip", "layer", "scale", "enabled", "anchors",
|
||||||
|
"texture", "shaderInfo", "sprite", "spriteSequence", "baseState"})
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -53,7 +53,10 @@ clang::format::FormatStyle qtcStyle()
|
|||||||
style.Language = FormatStyle::LK_Cpp;
|
style.Language = FormatStyle::LK_Cpp;
|
||||||
style.AccessModifierOffset = -4;
|
style.AccessModifierOffset = -4;
|
||||||
style.AlignAfterOpenBracket = FormatStyle::BAS_Align;
|
style.AlignAfterOpenBracket = FormatStyle::BAS_Align;
|
||||||
#if LLVM_VERSION_MAJOR >= 12
|
#if LLVM_VERSION_MAJOR >= 15
|
||||||
|
style.AlignConsecutiveAssignments = {false};
|
||||||
|
style.AlignConsecutiveDeclarations = {false};
|
||||||
|
#elif LLVM_VERSION_MAJOR >= 12
|
||||||
style.AlignConsecutiveAssignments = FormatStyle::ACS_None;
|
style.AlignConsecutiveAssignments = FormatStyle::ACS_None;
|
||||||
style.AlignConsecutiveDeclarations = FormatStyle::ACS_None;
|
style.AlignConsecutiveDeclarations = FormatStyle::ACS_None;
|
||||||
#else
|
#else
|
||||||
|
@@ -253,7 +253,7 @@ public:
|
|||||||
{
|
{
|
||||||
const QByteArray ba = QByteArray::fromHex(rawData.toUtf8());
|
const QByteArray ba = QByteArray::fromHex(rawData.toUtf8());
|
||||||
const auto p = (const T*)ba.data();
|
const auto p = (const T*)ba.data();
|
||||||
for (int i = 0, n = ba.size() / sizeof(T); i < n; ++i) {
|
for (int i = 0, n = int(ba.size() / sizeof(T)); i < n; ++i) {
|
||||||
auto child = new WatchItem;
|
auto child = new WatchItem;
|
||||||
child->arrayIndex = i;
|
child->arrayIndex = i;
|
||||||
child->value = decodeItemHelper(p[i]);
|
child->value = decodeItemHelper(p[i]);
|
||||||
|
@@ -276,6 +276,7 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
nameitemdelegate.cpp nameitemdelegate.h
|
nameitemdelegate.cpp nameitemdelegate.h
|
||||||
navigator.qrc
|
navigator.qrc
|
||||||
navigatormodelinterface.h
|
navigatormodelinterface.h
|
||||||
|
navigatorsearchwidget.cpp navigatorsearchwidget.h
|
||||||
navigatortreemodel.cpp navigatortreemodel.h
|
navigatortreemodel.cpp navigatortreemodel.h
|
||||||
navigatortreeview.cpp navigatortreeview.h
|
navigatortreeview.cpp navigatortreeview.h
|
||||||
navigatorview.cpp navigatorview.h
|
navigatorview.cpp navigatorview.h
|
||||||
|
@@ -253,11 +253,8 @@ const QStringList &AssetsLibraryModel::supportedTexture3DSuffixes()
|
|||||||
return retList;
|
return retList;
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetsLibraryModel::AssetsLibraryModel(SynchronousImageCache &fontImageCache,
|
AssetsLibraryModel::AssetsLibraryModel(Utils::FileSystemWatcher *fileSystemWatcher, QObject *parent)
|
||||||
Utils::FileSystemWatcher *fileSystemWatcher,
|
|
||||||
QObject *parent)
|
|
||||||
: QAbstractListModel(parent)
|
: QAbstractListModel(parent)
|
||||||
, m_fontImageCache(fontImageCache)
|
|
||||||
, m_fileSystemWatcher(fileSystemWatcher)
|
, m_fileSystemWatcher(fileSystemWatcher)
|
||||||
{
|
{
|
||||||
// add role names
|
// add role names
|
||||||
|
@@ -47,9 +47,7 @@ class AssetsLibraryModel : public QAbstractListModel
|
|||||||
Q_PROPERTY(bool isEmpty READ isEmpty WRITE setIsEmpty NOTIFY isEmptyChanged)
|
Q_PROPERTY(bool isEmpty READ isEmpty WRITE setIsEmpty NOTIFY isEmptyChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AssetsLibraryModel(QmlDesigner::SynchronousImageCache &fontImageCache,
|
AssetsLibraryModel(Utils::FileSystemWatcher *fileSystemWatcher, QObject *parent = nullptr);
|
||||||
Utils::FileSystemWatcher *fileSystemWatcher,
|
|
||||||
QObject *parent = nullptr);
|
|
||||||
|
|
||||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
@@ -97,7 +95,6 @@ private:
|
|||||||
|
|
||||||
void setIsEmpty(bool empty);
|
void setIsEmpty(bool empty);
|
||||||
|
|
||||||
SynchronousImageCache &m_fontImageCache;
|
|
||||||
QHash<QString, QPair<QDateTime, QIcon>> m_iconCache;
|
QHash<QString, QPair<QDateTime, QIcon>> m_iconCache;
|
||||||
|
|
||||||
QString m_searchText;
|
QString m_searchText;
|
||||||
|
@@ -117,7 +117,7 @@ AssetsLibraryWidget::AssetsLibraryWidget(AsynchronousImageCache &imageCache,
|
|||||||
, m_fontImageCache(synchronousFontImageCache)
|
, m_fontImageCache(synchronousFontImageCache)
|
||||||
, m_assetsIconProvider(new AssetsLibraryIconProvider(synchronousFontImageCache))
|
, m_assetsIconProvider(new AssetsLibraryIconProvider(synchronousFontImageCache))
|
||||||
, m_fileSystemWatcher(new Utils::FileSystemWatcher(this))
|
, m_fileSystemWatcher(new Utils::FileSystemWatcher(this))
|
||||||
, m_assetsModel(new AssetsLibraryModel(synchronousFontImageCache, m_fileSystemWatcher, this))
|
, m_assetsModel(new AssetsLibraryModel(m_fileSystemWatcher, this))
|
||||||
, m_assetsWidget(new QQuickWidget(this))
|
, m_assetsWidget(new QQuickWidget(this))
|
||||||
, m_imageCache{imageCache}
|
, m_imageCache{imageCache}
|
||||||
{
|
{
|
||||||
@@ -130,11 +130,13 @@ AssetsLibraryWidget::AssetsLibraryWidget(AsynchronousImageCache &imageCache,
|
|||||||
m_assetsWidget->installEventFilter(this);
|
m_assetsWidget->installEventFilter(this);
|
||||||
|
|
||||||
m_fontPreviewTooltipBackend = std::make_unique<PreviewTooltipBackend>(asynchronousFontImageCache);
|
m_fontPreviewTooltipBackend = std::make_unique<PreviewTooltipBackend>(asynchronousFontImageCache);
|
||||||
|
// We want font images to have custom size, so don't scale them in the tooltip
|
||||||
|
m_fontPreviewTooltipBackend->setScaleImage(false);
|
||||||
// Note: Though the text specified here appears in UI, it shouldn't be translated, as it's
|
// Note: Though the text specified here appears in UI, it shouldn't be translated, as it's
|
||||||
// a commonly used sentence to preview the font glyphs in latin fonts.
|
// a commonly used sentence to preview the font glyphs in latin fonts.
|
||||||
// For fonts that do not have latin glyphs, the font family name will have to suffice for preview.
|
// For fonts that do not have latin glyphs, the font family name will have to suffice for preview.
|
||||||
m_fontPreviewTooltipBackend->setAuxiliaryData(
|
m_fontPreviewTooltipBackend->setAuxiliaryData(
|
||||||
ImageCache::FontCollectorSizeAuxiliaryData{QSize{300, 300},
|
ImageCache::FontCollectorSizeAuxiliaryData{QSize{300, 150},
|
||||||
Theme::getColor(Theme::DStextColor).name(),
|
Theme::getColor(Theme::DStextColor).name(),
|
||||||
QStringLiteral("The quick brown fox jumps\n"
|
QStringLiteral("The quick brown fox jumps\n"
|
||||||
"over the lazy dog\n"
|
"over the lazy dog\n"
|
||||||
|
@@ -126,7 +126,6 @@ QString AddImagesDialog::getDirectory(const QStringList &fileNames, const QStrin
|
|||||||
setDirectoryForComboBox(newDir);
|
setDirectoryForComboBox(newDir);
|
||||||
});
|
});
|
||||||
|
|
||||||
mainLayout->addWidget(new QLabel(QCoreApplication::translate("AddImageToResources", "In directory:")), 1, 0);
|
|
||||||
mainLayout->addWidget(directoryComboBox, 1, 0, 1, 3);
|
mainLayout->addWidget(directoryComboBox, 1, 0, 1, 3);
|
||||||
mainLayout->addWidget(browseButton, 1, 3, 1 , 1);
|
mainLayout->addWidget(browseButton, 1, 3, 1 , 1);
|
||||||
|
|
||||||
|
@@ -45,6 +45,7 @@ public:
|
|||||||
virtual void notifyModelNodesMoved(const QList<ModelNode> &modelNodes) = 0;
|
virtual void notifyModelNodesMoved(const QList<ModelNode> &modelNodes) = 0;
|
||||||
virtual void notifyIconsChanged() = 0;
|
virtual void notifyIconsChanged() = 0;
|
||||||
virtual void setFilter(bool showObjects) = 0;
|
virtual void setFilter(bool showObjects) = 0;
|
||||||
|
virtual void setNameFilter(const QString &filter) = 0;
|
||||||
virtual void setOrder(bool reverse) = 0;
|
virtual void setOrder(bool reverse) = 0;
|
||||||
virtual void resetModel() = 0;
|
virtual void resetModel() = 0;
|
||||||
};
|
};
|
||||||
|
@@ -0,0 +1,66 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "navigatorsearchwidget.h"
|
||||||
|
|
||||||
|
#include <utils/stylehelper.h>
|
||||||
|
#include <theme.h>
|
||||||
|
|
||||||
|
#include <QBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
NavigatorSearchWidget::NavigatorSearchWidget(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
auto layout = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||||
|
const int iconSize = 15;
|
||||||
|
const QColor iconColor(QmlDesigner::Theme::getColor(QmlDesigner::Theme::IconsBaseColor));
|
||||||
|
const QIcon searchIcon = Utils::StyleHelper::getIconFromIconFont(
|
||||||
|
fontName, QmlDesigner::Theme::getIconUnicode(QmlDesigner::Theme::Icon::search),
|
||||||
|
iconSize, iconSize, iconColor);
|
||||||
|
|
||||||
|
m_textField = new QLineEdit;
|
||||||
|
m_textField->setPlaceholderText(tr("Filter"));
|
||||||
|
m_textField->setFrame(false);
|
||||||
|
m_textField->setClearButtonEnabled(true);
|
||||||
|
m_textField->addAction(searchIcon, QLineEdit::LeadingPosition);
|
||||||
|
|
||||||
|
connect(m_textField, &QLineEdit::textChanged, this, &NavigatorSearchWidget::textChanged);
|
||||||
|
|
||||||
|
layout->addWidget(m_textField);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavigatorSearchWidget::clear()
|
||||||
|
{
|
||||||
|
m_textField->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // QmlDesigner
|
@@ -0,0 +1,49 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QLineEdit>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class NavigatorSearchWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
NavigatorSearchWidget(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void textChanged(const QString &text);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QLineEdit *m_textField;
|
||||||
|
};
|
||||||
|
|
||||||
|
} //QmlDesigner
|
@@ -324,14 +324,25 @@ QList<ModelNode> NavigatorTreeModel::filteredList(const NodeListProperty &proper
|
|||||||
return it.value();
|
return it.value();
|
||||||
|
|
||||||
QList<ModelNode> list;
|
QList<ModelNode> list;
|
||||||
|
QList<ModelNode> propertyNodes = property.toModelNodeList();
|
||||||
|
QList<ModelNode> nameFilteredList;
|
||||||
|
|
||||||
|
if (m_nameFilter.isEmpty()) {
|
||||||
|
nameFilteredList = propertyNodes;
|
||||||
|
} else {
|
||||||
|
nameFilteredList.append(Utils::filtered(propertyNodes, [&] (const ModelNode &arg){
|
||||||
|
const bool value = m_nameFilteredList.contains(arg);
|
||||||
|
return value;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
if (filter) {
|
if (filter) {
|
||||||
list.append(Utils::filtered(property.toModelNodeList(), [] (const ModelNode &arg) {
|
list.append(Utils::filtered(nameFilteredList, [] (const ModelNode &arg) {
|
||||||
const bool value = QmlItemNode::isValidQmlItemNode(arg) || NodeHints::fromModelNode(arg).visibleInNavigator();
|
const bool value = QmlItemNode::isValidQmlItemNode(arg) || NodeHints::fromModelNode(arg).visibleInNavigator();
|
||||||
return value;
|
return value;
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
list = property.toModelNodeList();
|
list = nameFilteredList;
|
||||||
}
|
}
|
||||||
|
|
||||||
appendForcedNodes(property, list);
|
appendForcedNodes(property, list);
|
||||||
@@ -1222,6 +1233,35 @@ void NavigatorTreeModel::setFilter(bool showOnlyVisibleItems)
|
|||||||
resetModel();
|
resetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavigatorTreeModel::setNameFilter(const QString &filter)
|
||||||
|
{
|
||||||
|
m_nameFilter = filter;
|
||||||
|
m_rowCache.clear();
|
||||||
|
|
||||||
|
ModelNode rootNode = m_view->rootModelNode();
|
||||||
|
QList<ModelNode> allNodes = rootNode.allSubModelNodes();
|
||||||
|
m_nameFilteredList.clear();
|
||||||
|
|
||||||
|
if (filter.isEmpty()) {
|
||||||
|
m_nameFilteredList = allNodes;
|
||||||
|
} else {
|
||||||
|
for (ModelNode &node : rootNode.allSubModelNodes()) {
|
||||||
|
if (node.displayName().contains(filter, Qt::CaseSensitivity::CaseInsensitive)) {
|
||||||
|
m_nameFilteredList.append(node);
|
||||||
|
ModelNode n = node;
|
||||||
|
while (n.hasParentProperty()) {
|
||||||
|
n = n.parentProperty().parentModelNode();
|
||||||
|
if (n.isRootNode() || m_nameFilteredList.contains(n))
|
||||||
|
break;
|
||||||
|
m_nameFilteredList.append(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resetModel();
|
||||||
|
}
|
||||||
|
|
||||||
void NavigatorTreeModel::setOrder(bool reverseItemOrder)
|
void NavigatorTreeModel::setOrder(bool reverseItemOrder)
|
||||||
{
|
{
|
||||||
m_reverseItemOrder = reverseItemOrder;
|
m_reverseItemOrder = reverseItemOrder;
|
||||||
|
@@ -101,6 +101,7 @@ public:
|
|||||||
void notifyModelNodesMoved(const QList<ModelNode> &modelNodes) override;
|
void notifyModelNodesMoved(const QList<ModelNode> &modelNodes) override;
|
||||||
void notifyIconsChanged() override;
|
void notifyIconsChanged() override;
|
||||||
void setFilter(bool showOnlyVisibleItems) override;
|
void setFilter(bool showOnlyVisibleItems) override;
|
||||||
|
void setNameFilter(const QString &filter) override;
|
||||||
void setOrder(bool reverseItemOrder) override;
|
void setOrder(bool reverseItemOrder) override;
|
||||||
void resetModel() override;
|
void resetModel() override;
|
||||||
|
|
||||||
@@ -140,6 +141,8 @@ private:
|
|||||||
bool m_showOnlyVisibleItems = true;
|
bool m_showOnlyVisibleItems = true;
|
||||||
bool m_reverseItemOrder = false;
|
bool m_reverseItemOrder = false;
|
||||||
DesignerActionManager *m_actionManager = nullptr;
|
DesignerActionManager *m_actionManager = nullptr;
|
||||||
|
QString m_nameFilter;
|
||||||
|
QList<ModelNode> m_nameFilteredList;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -293,8 +293,15 @@ void NavigatorTreeView::mousePressEvent(QMouseEvent *event)
|
|||||||
|
|
||||||
void NavigatorTreeView::startDrag(Qt::DropActions supportedActions)
|
void NavigatorTreeView::startDrag(Qt::DropActions supportedActions)
|
||||||
{
|
{
|
||||||
if (m_dragAllowed)
|
if (m_dragAllowed) {
|
||||||
|
if (m_previewToolTip) {
|
||||||
|
// Workaround to ensure tooltip doesn't linger during drag, as drag grabs all mouse
|
||||||
|
// events on some platforms (e.g. mac)
|
||||||
|
m_previewToolTip->hide();
|
||||||
|
m_previewToolTipNodeId = -1;
|
||||||
|
}
|
||||||
QTreeView::startDrag(supportedActions);
|
QTreeView::startDrag(supportedActions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -151,6 +151,8 @@ void NavigatorView::modelAttached(Model *model)
|
|||||||
treeView->setIndentation(20);
|
treeView->setIndentation(20);
|
||||||
|
|
||||||
m_currentModelInterface->setFilter(false);
|
m_currentModelInterface->setFilter(false);
|
||||||
|
m_currentModelInterface->setNameFilter("");
|
||||||
|
m_widget->clearSearch();
|
||||||
|
|
||||||
QTimer::singleShot(0, this, [this, treeView]() {
|
QTimer::singleShot(0, this, [this, treeView]() {
|
||||||
m_currentModelInterface->setFilter(
|
m_currentModelInterface->setFilter(
|
||||||
@@ -575,6 +577,12 @@ void NavigatorView::reverseOrderToggled(bool flag)
|
|||||||
DesignerSettings::setValue(DesignerSettingsKey::NAVIGATOR_REVERSE_ITEM_ORDER, flag);
|
DesignerSettings::setValue(DesignerSettingsKey::NAVIGATOR_REVERSE_ITEM_ORDER, flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavigatorView::textFilterChanged(const QString &text)
|
||||||
|
{
|
||||||
|
m_treeModel->setNameFilter(text);
|
||||||
|
treeWidget()->expandAll();
|
||||||
|
}
|
||||||
|
|
||||||
void NavigatorView::changeSelection(const QItemSelection & /*newSelection*/, const QItemSelection &/*deselected*/)
|
void NavigatorView::changeSelection(const QItemSelection & /*newSelection*/, const QItemSelection &/*deselected*/)
|
||||||
{
|
{
|
||||||
if (m_blockSelectionChangedSignal)
|
if (m_blockSelectionChangedSignal)
|
||||||
@@ -703,6 +711,8 @@ void NavigatorView::setupWidget()
|
|||||||
connect(m_widget.data(), &NavigatorWidget::filterToggled, this, &NavigatorView::filterToggled);
|
connect(m_widget.data(), &NavigatorWidget::filterToggled, this, &NavigatorView::filterToggled);
|
||||||
connect(m_widget.data(), &NavigatorWidget::reverseOrderToggled, this, &NavigatorView::reverseOrderToggled);
|
connect(m_widget.data(), &NavigatorWidget::reverseOrderToggled, this, &NavigatorView::reverseOrderToggled);
|
||||||
|
|
||||||
|
connect(m_widget.data(), &NavigatorWidget::textFilterChanged, this, &NavigatorView::textFilterChanged);
|
||||||
|
|
||||||
#ifndef QMLDESIGNER_TEST
|
#ifndef QMLDESIGNER_TEST
|
||||||
const QString fontName = "qtds_propertyIconFont.ttf";
|
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||||
const QSize size = QSize(28, 28);
|
const QSize size = QSize(28, 28);
|
||||||
|
@@ -118,6 +118,8 @@ private:
|
|||||||
void filterToggled(bool);
|
void filterToggled(bool);
|
||||||
void reverseOrderToggled(bool);
|
void reverseOrderToggled(bool);
|
||||||
|
|
||||||
|
void textFilterChanged(const QString &text);
|
||||||
|
|
||||||
protected: //functions
|
protected: //functions
|
||||||
QTreeView *treeWidget() const;
|
QTreeView *treeWidget() const;
|
||||||
NavigatorTreeModel *treeModel();
|
NavigatorTreeModel *treeModel();
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "navigatorsearchwidget.h"
|
||||||
#include "navigatorwidget.h"
|
#include "navigatorwidget.h"
|
||||||
#include "navigatorview.h"
|
#include "navigatorview.h"
|
||||||
|
|
||||||
@@ -160,6 +161,10 @@ QToolBar *NavigatorWidget::createToolBar()
|
|||||||
for (auto toolButton : buttons)
|
for (auto toolButton : buttons)
|
||||||
toolBar->addWidget(toolButton);
|
toolBar->addWidget(toolButton);
|
||||||
|
|
||||||
|
m_searchWidget = new NavigatorSearchWidget();
|
||||||
|
connect(m_searchWidget, &NavigatorSearchWidget::textChanged, this, &NavigatorWidget::textFilterChanged);
|
||||||
|
toolBar->addWidget(m_searchWidget);
|
||||||
|
|
||||||
return toolBar;
|
return toolBar;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,4 +216,9 @@ QByteArray NavigatorWidget::dragType() const
|
|||||||
return m_dragType;
|
return m_dragType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavigatorWidget::clearSearch()
|
||||||
|
{
|
||||||
|
m_searchWidget->clear();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -39,6 +39,7 @@ QT_FORWARD_DECLARE_CLASS(QAbstractItemModel)
|
|||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
class NavigatorView;
|
class NavigatorView;
|
||||||
|
class NavigatorSearchWidget;
|
||||||
|
|
||||||
class NavigatorWidget: public QFrame
|
class NavigatorWidget: public QFrame
|
||||||
{
|
{
|
||||||
@@ -59,6 +60,8 @@ public:
|
|||||||
void setDragType(const QByteArray &type);
|
void setDragType(const QByteArray &type);
|
||||||
QByteArray dragType() const;
|
QByteArray dragType() const;
|
||||||
|
|
||||||
|
void clearSearch();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void leftButtonClicked();
|
void leftButtonClicked();
|
||||||
void rightButtonClicked();
|
void rightButtonClicked();
|
||||||
@@ -66,6 +69,7 @@ signals:
|
|||||||
void downButtonClicked();
|
void downButtonClicked();
|
||||||
void filterToggled(bool);
|
void filterToggled(bool);
|
||||||
void reverseOrderToggled(bool);
|
void reverseOrderToggled(bool);
|
||||||
|
void textFilterChanged(const QString &name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void dragEnterEvent(QDragEnterEvent *dragEnterEvent) override;
|
void dragEnterEvent(QDragEnterEvent *dragEnterEvent) override;
|
||||||
@@ -77,6 +81,7 @@ private:
|
|||||||
NavigatorTreeView *m_treeView;
|
NavigatorTreeView *m_treeView;
|
||||||
QPointer<NavigatorView> m_navigatorView;
|
QPointer<NavigatorView> m_navigatorView;
|
||||||
QByteArray m_dragType;
|
QByteArray m_dragType;
|
||||||
|
NavigatorSearchWidget *m_searchWidget;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -62,10 +62,16 @@ void PreviewImageTooltip::setInfo(const QString &info)
|
|||||||
m_ui->infoLabel->setText(info);
|
m_ui->infoLabel->setText(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreviewImageTooltip::setImage(const QImage &image)
|
void PreviewImageTooltip::setImage(const QImage &image, bool scale)
|
||||||
{
|
{
|
||||||
m_ui->imageLabel->setPixmap(QPixmap::fromImage({image}).scaled(m_ui->imageLabel->width(),
|
QPixmap pm = QPixmap::fromImage({image});
|
||||||
m_ui->imageLabel->height(),
|
if (scale) {
|
||||||
Qt::KeepAspectRatio));
|
m_ui->imageLabel->setPixmap(pm.scaled(m_ui->imageLabel->width(),
|
||||||
|
m_ui->imageLabel->height(),
|
||||||
|
Qt::KeepAspectRatio));
|
||||||
|
} else {
|
||||||
|
m_ui->imageLabel->setPixmap(pm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -46,7 +46,7 @@ public:
|
|||||||
void setName(const QString &name);
|
void setName(const QString &name);
|
||||||
void setPath(const QString &path);
|
void setPath(const QString &path);
|
||||||
void setInfo(const QString &info);
|
void setInfo(const QString &info);
|
||||||
void setImage(const QImage &pixmap);
|
void setImage(const QImage &image, bool scale = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Ui::PreviewImageTooltip> m_ui;
|
std::unique_ptr<Ui::PreviewImageTooltip> m_ui;
|
||||||
|
@@ -55,10 +55,10 @@ void PreviewTooltipBackend::showTooltip()
|
|||||||
|
|
||||||
m_cache.requestImage(
|
m_cache.requestImage(
|
||||||
m_path,
|
m_path,
|
||||||
[tooltip = QPointer<PreviewImageTooltip>(m_tooltip.get())](const QImage &image) {
|
[tooltip = QPointer<PreviewImageTooltip>(m_tooltip.get()), scaleImage = m_scaleImage](const QImage &image) {
|
||||||
QMetaObject::invokeMethod(tooltip, [tooltip, image] {
|
QMetaObject::invokeMethod(tooltip, [tooltip, image, scaleImage] {
|
||||||
if (tooltip) {
|
if (tooltip) {
|
||||||
tooltip->setImage(image);
|
tooltip->setImage(image, scaleImage);
|
||||||
tooltip->show();
|
tooltip->show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -126,9 +126,10 @@ QString PreviewTooltipBackend::name() const
|
|||||||
|
|
||||||
void PreviewTooltipBackend::setName(const QString &name)
|
void PreviewTooltipBackend::setName(const QString &name)
|
||||||
{
|
{
|
||||||
m_name = name;
|
if (m_name != name) {
|
||||||
if (m_name != name)
|
m_name = name;
|
||||||
emit nameChanged();
|
emit nameChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PreviewTooltipBackend::path() const
|
QString PreviewTooltipBackend::path() const
|
||||||
@@ -138,9 +139,10 @@ QString PreviewTooltipBackend::path() const
|
|||||||
|
|
||||||
void PreviewTooltipBackend::setPath(const QString &path)
|
void PreviewTooltipBackend::setPath(const QString &path)
|
||||||
{
|
{
|
||||||
m_path = path;
|
if (m_path != path) {
|
||||||
if (m_path != path)
|
m_path = path;
|
||||||
emit pathChanged();
|
emit pathChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PreviewTooltipBackend::info() const
|
QString PreviewTooltipBackend::info() const
|
||||||
@@ -150,9 +152,10 @@ QString PreviewTooltipBackend::info() const
|
|||||||
|
|
||||||
void PreviewTooltipBackend::setInfo(const QString &info)
|
void PreviewTooltipBackend::setInfo(const QString &info)
|
||||||
{
|
{
|
||||||
m_info = info;
|
if (m_info != info) {
|
||||||
if (m_info != info)
|
m_info = info;
|
||||||
emit infoChanged();
|
emit infoChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PreviewTooltipBackend::extraId() const
|
QString PreviewTooltipBackend::extraId() const
|
||||||
@@ -163,9 +166,23 @@ QString PreviewTooltipBackend::extraId() const
|
|||||||
// Sets the imageCache extraId hint. Valid content depends on image cache collector used.
|
// Sets the imageCache extraId hint. Valid content depends on image cache collector used.
|
||||||
void PreviewTooltipBackend::setExtraId(const QString &extraId)
|
void PreviewTooltipBackend::setExtraId(const QString &extraId)
|
||||||
{
|
{
|
||||||
m_extraId = extraId;
|
if (m_extraId != extraId) {
|
||||||
if (m_extraId != extraId)
|
m_extraId = extraId;
|
||||||
emit extraIdChanged();
|
emit extraIdChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PreviewTooltipBackend::scaleImage() const
|
||||||
|
{
|
||||||
|
return m_scaleImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreviewTooltipBackend::setScaleImage(bool scale)
|
||||||
|
{
|
||||||
|
if (m_scaleImage != scale) {
|
||||||
|
m_scaleImage = scale;
|
||||||
|
emit scaleImageChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -45,6 +45,7 @@ class PreviewTooltipBackend : public QObject
|
|||||||
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
|
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged)
|
||||||
Q_PROPERTY(QString info READ info WRITE setInfo NOTIFY infoChanged)
|
Q_PROPERTY(QString info READ info WRITE setInfo NOTIFY infoChanged)
|
||||||
Q_PROPERTY(QString extraId READ extraId WRITE setExtraId NOTIFY extraIdChanged)
|
Q_PROPERTY(QString extraId READ extraId WRITE setExtraId NOTIFY extraIdChanged)
|
||||||
|
Q_PROPERTY(bool scaleImage READ scaleImage WRITE setScaleImage NOTIFY scaleImageChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PreviewTooltipBackend(AsynchronousImageCache &cache);
|
PreviewTooltipBackend(AsynchronousImageCache &cache);
|
||||||
@@ -62,6 +63,8 @@ public:
|
|||||||
void setInfo(const QString &info);
|
void setInfo(const QString &info);
|
||||||
QString extraId() const;
|
QString extraId() const;
|
||||||
void setExtraId(const QString &extraId);
|
void setExtraId(const QString &extraId);
|
||||||
|
bool scaleImage() const;
|
||||||
|
void setScaleImage(bool scale);
|
||||||
|
|
||||||
bool isVisible() const;
|
bool isVisible() const;
|
||||||
|
|
||||||
@@ -75,12 +78,14 @@ signals:
|
|||||||
void pathChanged();
|
void pathChanged();
|
||||||
void infoChanged();
|
void infoChanged();
|
||||||
void extraIdChanged();
|
void extraIdChanged();
|
||||||
|
void scaleImageChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_name;
|
QString m_name;
|
||||||
QString m_path;
|
QString m_path;
|
||||||
QString m_info;
|
QString m_info;
|
||||||
QString m_extraId;
|
QString m_extraId;
|
||||||
|
bool m_scaleImage = true;
|
||||||
std::unique_ptr<PreviewImageTooltip> m_tooltip;
|
std::unique_ptr<PreviewImageTooltip> m_tooltip;
|
||||||
ImageCache::AuxiliaryData m_auxiliaryData;
|
ImageCache::AuxiliaryData m_auxiliaryData;
|
||||||
AsynchronousImageCache &m_cache;
|
AsynchronousImageCache &m_cache;
|
||||||
|
@@ -227,6 +227,8 @@ ModelNode TransitionEditorView::addNewTransition()
|
|||||||
const QString targetId = target.id();
|
const QString targetId = target.id();
|
||||||
for (const VariantProperty &property : change.modelNode().variantProperties()) {
|
for (const VariantProperty &property : change.modelNode().variantProperties()) {
|
||||||
TypeName typeName = target.metaInfo().propertyTypeName(property.name());
|
TypeName typeName = target.metaInfo().propertyTypeName(property.name());
|
||||||
|
if (typeName.startsWith("<cpp>."))
|
||||||
|
typeName.remove(0, 6);
|
||||||
|
|
||||||
if (validProperties.contains(typeName))
|
if (validProperties.contains(typeName))
|
||||||
locList.append(QString::fromUtf8(property.name()));
|
locList.append(QString::fromUtf8(property.name()));
|
||||||
|
@@ -131,7 +131,7 @@ void ImageCacheFontCollector::start(Utils::SmallStringView name,
|
|||||||
auto &&auxiliaryData = Utils::get<ImageCache::FontCollectorSizeAuxiliaryData>(auxiliaryDataValue);
|
auto &&auxiliaryData = Utils::get<ImageCache::FontCollectorSizeAuxiliaryData>(auxiliaryDataValue);
|
||||||
QColor textColor = auxiliaryData.colorName;
|
QColor textColor = auxiliaryData.colorName;
|
||||||
QSize size = auxiliaryData.size;
|
QSize size = auxiliaryData.size;
|
||||||
QString text = font.family() + "\n\n" + auxiliaryData.text;
|
QString text = font.family() + "\n" + auxiliaryData.text;
|
||||||
|
|
||||||
QImage image = createFontImage(text, textColor, font, size);
|
QImage image = createFontImage(text, textColor, font, size);
|
||||||
|
|
||||||
|
@@ -565,9 +565,11 @@ void NodeInstanceView::nodeReparented(const ModelNode &node, const NodeAbstractP
|
|||||||
|
|
||||||
// Reset puppet when particle emitter/affector is reparented to work around issue in
|
// Reset puppet when particle emitter/affector is reparented to work around issue in
|
||||||
// autodetecting the particle system it belongs to. QTBUG-101157
|
// autodetecting the particle system it belongs to. QTBUG-101157
|
||||||
if ((node.isSubclassOf("QtQuick.Particles3D.ParticleEmitter3D")
|
// Reset is also needed when particle shapes are reparented. QTBUG-101882
|
||||||
|| node.isSubclassOf("QtQuick.Particles3D.Affector3D"))
|
if (((node.isSubclassOf("QtQuick.Particles3D.ParticleEmitter3D")
|
||||||
&& node.property("system").toBindingProperty().expression().isEmpty()) {
|
|| node.isSubclassOf("QtQuick.Particles3D.Affector3D"))
|
||||||
|
&& node.property("system").toBindingProperty().expression().isEmpty())
|
||||||
|
|| node.isSubclassOf("QQuick3DParticleAbstractShape")) {
|
||||||
resetPuppet();
|
resetPuppet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -97,6 +97,9 @@ static TypeName resolveTypeName(const ASTPropertyReference *ref, const ContextPt
|
|||||||
if (const CppComponentValue * componentObjectValue = value->asCppComponentValue()) {
|
if (const CppComponentValue * componentObjectValue = value->asCppComponentValue()) {
|
||||||
type = componentObjectValue->className().toUtf8();
|
type = componentObjectValue->className().toUtf8();
|
||||||
dotProperties = getObjectTypes(componentObjectValue, context);
|
dotProperties = getObjectTypes(componentObjectValue, context);
|
||||||
|
} else if (const ObjectValue * objectValue = value->asObjectValue()) {
|
||||||
|
type = objectValue->className().toUtf8();
|
||||||
|
dotProperties = getObjectTypes(objectValue, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == "alias") {
|
if (type == "alias") {
|
||||||
|
@@ -42,7 +42,7 @@ DocumentMessage::DocumentMessage(Exception *exception):
|
|||||||
m_line(exception->line()),
|
m_line(exception->line()),
|
||||||
m_column(-1),
|
m_column(-1),
|
||||||
m_description(exception->description()),
|
m_description(exception->description()),
|
||||||
m_url(exception->file())
|
m_url(QUrl::fromLocalFile(exception->file()))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,14 +84,14 @@ QString DocumentMessage::toString() const
|
|||||||
if (line() != -1) {
|
if (line() != -1) {
|
||||||
if (!str.isEmpty())
|
if (!str.isEmpty())
|
||||||
str += QLatin1Char(' ');
|
str += QLatin1Char(' ');
|
||||||
str += ::QmlDesigner::DocumentMessage::tr("line %1").arg(line());
|
str += ::QmlDesigner::DocumentMessage::tr("line %1\n").arg(line());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (column() != -1) {
|
if (column() != -1) {
|
||||||
if (!str.isEmpty())
|
if (!str.isEmpty())
|
||||||
str += QLatin1Char(' ');
|
str += QLatin1Char(' ');
|
||||||
|
|
||||||
str += ::QmlDesigner::DocumentMessage::tr("column %1").arg(column());
|
str += ::QmlDesigner::DocumentMessage::tr("column %1\n").arg(column());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!str.isEmpty())
|
if (!str.isEmpty())
|
||||||
|
@@ -335,7 +335,8 @@ QmlObjectNode QmlVisualNode::createQmlObjectNode(AbstractView *view,
|
|||||||
if (!newQmlObjectNode.isValid())
|
if (!newQmlObjectNode.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
newQmlObjectNode.modelNode().setIdWithoutRefactoring(view->model()->generateNewId(itemLibraryEntry.name()));
|
if (newQmlObjectNode.id().isEmpty())
|
||||||
|
newQmlObjectNode.modelNode().setIdWithoutRefactoring(view->model()->generateNewId(itemLibraryEntry.name()));
|
||||||
|
|
||||||
for (const auto &propertyBindingEntry : propertyBindingList)
|
for (const auto &propertyBindingEntry : propertyBindingList)
|
||||||
newQmlObjectNode.modelNode().bindingProperty(propertyBindingEntry.first).setExpression(propertyBindingEntry.second);
|
newQmlObjectNode.modelNode().bindingProperty(propertyBindingEntry.first).setExpression(propertyBindingEntry.second);
|
||||||
|
@@ -680,6 +680,8 @@ Project {
|
|||||||
"navigator/nameitemdelegate.cpp",
|
"navigator/nameitemdelegate.cpp",
|
||||||
"navigator/nameitemdelegate.h",
|
"navigator/nameitemdelegate.h",
|
||||||
"navigator/navigator.qrc",
|
"navigator/navigator.qrc",
|
||||||
|
"navigator/navigatorsearchwidget.cpp",
|
||||||
|
"navigator/navigatorsearchwidget.h",
|
||||||
"navigator/navigatortreemodel.cpp",
|
"navigator/navigatortreemodel.cpp",
|
||||||
"navigator/navigatortreemodel.h",
|
"navigator/navigatortreemodel.h",
|
||||||
"navigator/navigatortreeview.cpp",
|
"navigator/navigatortreeview.cpp",
|
||||||
|
@@ -235,8 +235,6 @@ QString QmlProjectRunConfiguration::commandLineArguments() const
|
|||||||
if (!main.isEmpty())
|
if (!main.isEmpty())
|
||||||
ProcessArgs::addArg(&args, main, osType);
|
ProcessArgs::addArg(&args, main, osType);
|
||||||
|
|
||||||
if (m_multiLanguageAspect && m_multiLanguageAspect->value())
|
|
||||||
ProcessArgs::addArg(&args, "-qmljsdebugger=file:unused_if_debugger_arguments_added,services:DebugTranslation", osType);
|
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
@@ -13,7 +13,6 @@ add_qtc_plugin(StudioWelcome
|
|||||||
wizardfactories.cpp wizardfactories.h
|
wizardfactories.cpp wizardfactories.h
|
||||||
createproject.cpp createproject.h
|
createproject.cpp createproject.h
|
||||||
wizardhandler.cpp wizardhandler.h
|
wizardhandler.cpp wizardhandler.h
|
||||||
recentpresets.cpp recentpresets.h
|
|
||||||
userpresets.cpp userpresets.h
|
userpresets.cpp userpresets.h
|
||||||
screensizemodel.h
|
screensizemodel.h
|
||||||
algorithm.h
|
algorithm.h
|
||||||
|
@@ -42,6 +42,16 @@ template<typename C, typename F>
|
|||||||
return it == end ? nullopt : make_optional(*it);
|
return it == end ? nullopt : make_optional(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename C>
|
||||||
|
[[nodiscard]] bool containsItem(const C &container, const typename C::value_type &item)
|
||||||
|
{
|
||||||
|
auto begin = std::cbegin(container);
|
||||||
|
auto end = std::cend(container);
|
||||||
|
|
||||||
|
auto it = std::find(begin, end, item);
|
||||||
|
return it == end ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
///////// FILTER
|
///////// FILTER
|
||||||
template<typename C, typename T = typename C::value_type>
|
template<typename C, typename T = typename C::value_type>
|
||||||
[[nodiscard]] C filterOut(const C &container, const T &value = T())
|
[[nodiscard]] C filterOut(const C &container, const T &value = T())
|
||||||
@@ -67,13 +77,14 @@ void concat(C &out, const SC &container)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename C, typename T>
|
template<typename C, typename T>
|
||||||
void erase_one(C &container, const T &value)
|
bool erase_one(C &container, const T &value)
|
||||||
{
|
{
|
||||||
typename C::const_iterator i = std::find(std::cbegin(container), std::cend(container), value);
|
typename C::const_iterator i = std::find(std::cbegin(container), std::cend(container), value);
|
||||||
if (i == std::cend(container))
|
if (i == std::cend(container))
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
container.erase(i);
|
container.erase(i);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename C, typename T>
|
template<typename C, typename T>
|
||||||
|
@@ -47,7 +47,7 @@ QString PresetData::recentsTabName()
|
|||||||
|
|
||||||
void PresetData::setData(const PresetsByCategory &presetsByCategory,
|
void PresetData::setData(const PresetsByCategory &presetsByCategory,
|
||||||
const std::vector<UserPresetData> &userPresetsData,
|
const std::vector<UserPresetData> &userPresetsData,
|
||||||
const std::vector<RecentPresetData> &loadedRecentsData)
|
const std::vector<UserPresetData> &loadedRecentsData)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!presetsByCategory.empty(), return );
|
QTC_ASSERT(!presetsByCategory.empty(), return );
|
||||||
m_recents = loadedRecentsData;
|
m_recents = loadedRecentsData;
|
||||||
@@ -60,16 +60,13 @@ void PresetData::setData(const PresetsByCategory &presetsByCategory,
|
|||||||
|
|
||||||
PresetItems wizardPresets = Utils::flatten(m_presets);
|
PresetItems wizardPresets = Utils::flatten(m_presets);
|
||||||
|
|
||||||
PresetItems userPresetItems = makeUserPresets(wizardPresets);
|
PresetItems userPresetItems = makeUserPresets(wizardPresets, m_userPresets);
|
||||||
if (!userPresetItems.empty()) {
|
if (!userPresetItems.empty()) {
|
||||||
m_categories.push_back(CustomTabName);
|
m_categories.push_back(CustomTabName);
|
||||||
m_presets.push_back(userPresetItems);
|
m_presets.push_back(userPresetItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
PresetItems allWizardPresets = std::move(wizardPresets);
|
PresetItems recentPresets = makeUserPresets(wizardPresets, m_recents);
|
||||||
Utils::concat(allWizardPresets, userPresetItems);
|
|
||||||
|
|
||||||
PresetItems recentPresets = makeRecentPresets(allWizardPresets);
|
|
||||||
if (!recentPresets.empty()) {
|
if (!recentPresets.empty()) {
|
||||||
Utils::prepend(m_categories, RecentsTabName);
|
Utils::prepend(m_categories, RecentsTabName);
|
||||||
Utils::prepend(m_presets, recentPresets);
|
Utils::prepend(m_presets, recentPresets);
|
||||||
@@ -79,7 +76,7 @@ void PresetData::setData(const PresetsByCategory &presetsByCategory,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PresetData::reload(const std::vector<UserPresetData> &userPresetsData,
|
void PresetData::reload(const std::vector<UserPresetData> &userPresetsData,
|
||||||
const std::vector<RecentPresetData> &loadedRecentsData)
|
const std::vector<UserPresetData> &loadedRecentsData)
|
||||||
{
|
{
|
||||||
m_categories.clear();
|
m_categories.clear();
|
||||||
m_presets.clear();
|
m_presets.clear();
|
||||||
@@ -96,11 +93,12 @@ std::shared_ptr<PresetItem> PresetData::findPresetItemForUserPreset(const UserPr
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
PresetItems PresetData::makeUserPresets(const PresetItems &wizardPresets)
|
PresetItems PresetData::makeUserPresets(const PresetItems &wizardPresets,
|
||||||
|
const std::vector<UserPresetData> &data)
|
||||||
{
|
{
|
||||||
PresetItems result;
|
PresetItems result;
|
||||||
|
|
||||||
for (const UserPresetData &userPresetData : m_userPresets) {
|
for (const UserPresetData &userPresetData : data) {
|
||||||
std::shared_ptr<PresetItem> foundPreset = findPresetItemForUserPreset(userPresetData,
|
std::shared_ptr<PresetItem> foundPreset = findPresetItemForUserPreset(userPresetData,
|
||||||
wizardPresets);
|
wizardPresets);
|
||||||
if (!foundPreset)
|
if (!foundPreset)
|
||||||
@@ -128,35 +126,6 @@ PresetItems PresetData::makeUserPresets(const PresetItems &wizardPresets)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<PresetItem> PresetData::findPresetItemForRecent(const RecentPresetData &recent, const PresetItems &wizardPresets)
|
|
||||||
{
|
|
||||||
return Utils::findOrDefault(wizardPresets, [&recent](const std::shared_ptr<PresetItem> &item) {
|
|
||||||
bool sameName = item->categoryId == recent.category
|
|
||||||
&& item->displayName() == recent.presetName;
|
|
||||||
|
|
||||||
bool sameType = (recent.isUserPreset ? item->isUserPreset() : !item->isUserPreset());
|
|
||||||
|
|
||||||
return sameName && sameType;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
PresetItems PresetData::makeRecentPresets(const PresetItems &wizardPresets)
|
|
||||||
{
|
|
||||||
PresetItems result;
|
|
||||||
|
|
||||||
for (const RecentPresetData &recent : m_recents) {
|
|
||||||
std::shared_ptr<PresetItem> preset = findPresetItemForRecent(recent, wizardPresets);
|
|
||||||
|
|
||||||
if (preset) {
|
|
||||||
auto clone = std::shared_ptr<PresetItem>{preset->clone()};
|
|
||||||
clone->screenSizeName = recent.sizeName;
|
|
||||||
result.push_back(clone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************** BasePresetModel ******************/
|
/****************** BasePresetModel ******************/
|
||||||
|
|
||||||
BasePresetModel::BasePresetModel(const PresetData *data, QObject *parent)
|
BasePresetModel::BasePresetModel(const PresetData *data, QObject *parent)
|
||||||
|
@@ -33,7 +33,6 @@
|
|||||||
#include <utils/optional.h>
|
#include <utils/optional.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include "recentpresets.h"
|
|
||||||
#include "userpresets.h"
|
#include "userpresets.h"
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
@@ -169,10 +168,10 @@ class PresetData
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void reload(const std::vector<UserPresetData> &userPresets,
|
void reload(const std::vector<UserPresetData> &userPresets,
|
||||||
const std::vector<RecentPresetData> &loadedRecents);
|
const std::vector<UserPresetData> &loadedRecents);
|
||||||
void setData(const PresetsByCategory &presets,
|
void setData(const PresetsByCategory &presets,
|
||||||
const std::vector<UserPresetData> &userPresets,
|
const std::vector<UserPresetData> &userPresets,
|
||||||
const std::vector<RecentPresetData> &recents);
|
const std::vector<UserPresetData> &recents);
|
||||||
|
|
||||||
const std::vector<PresetItems> &presets() const { return m_presets; }
|
const std::vector<PresetItems> &presets() const { return m_presets; }
|
||||||
const Categories &categories() const { return m_categories; }
|
const Categories &categories() const { return m_categories; }
|
||||||
@@ -180,16 +179,13 @@ public:
|
|||||||
static QString recentsTabName();
|
static QString recentsTabName();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PresetItems makeRecentPresets(const PresetItems &wizardPresets);
|
PresetItems makeUserPresets(const PresetItems &wizardPresets, const std::vector<UserPresetData> &data);
|
||||||
PresetItems makeUserPresets(const PresetItems &wizardPresets);
|
|
||||||
|
|
||||||
std::shared_ptr<PresetItem> findPresetItemForUserPreset(const UserPresetData &preset, const PresetItems &wizardPresets);
|
std::shared_ptr<PresetItem> findPresetItemForUserPreset(const UserPresetData &preset, const PresetItems &wizardPresets);
|
||||||
std::shared_ptr<PresetItem> findPresetItemForRecent(const RecentPresetData &recent, const PresetItems &wizardPresets);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<PresetItems> m_presets;
|
std::vector<PresetItems> m_presets;
|
||||||
Categories m_categories;
|
Categories m_categories;
|
||||||
std::vector<RecentPresetData> m_recents;
|
std::vector<UserPresetData> m_recents;
|
||||||
std::vector<UserPresetData> m_userPresets;
|
std::vector<UserPresetData> m_userPresets;
|
||||||
PresetsByCategory m_presetsByCategory;
|
PresetsByCategory m_presetsByCategory;
|
||||||
};
|
};
|
||||||
|
@@ -72,10 +72,14 @@ QdsNewDialog::QdsNewDialog(QWidget *parent)
|
|||||||
, m_presetModel{new PresetModel(&m_presetData, this)}
|
, m_presetModel{new PresetModel(&m_presetData, this)}
|
||||||
, m_screenSizeModel{new ScreenSizeModel(this)}
|
, m_screenSizeModel{new ScreenSizeModel(this)}
|
||||||
, m_styleModel{new StyleModel(this)}
|
, m_styleModel{new StyleModel(this)}
|
||||||
, m_recentsStore{Core::ICore::settings()}
|
, m_recentsStore{"RecentPresets.json", StorePolicy::UniqueValues}
|
||||||
|
, m_userPresetsStore{"UserPresets.json", StorePolicy::UniqueNames}
|
||||||
{
|
{
|
||||||
setParent(m_dialog);
|
setParent(m_dialog);
|
||||||
|
|
||||||
|
m_recentsStore.setReverseOrder();
|
||||||
|
m_recentsStore.setMaximum(10);
|
||||||
|
|
||||||
m_dialog->setResizeMode(QQuickWidget::SizeRootObjectToView); // SizeViewToRootObject
|
m_dialog->setResizeMode(QQuickWidget::SizeRootObjectToView); // SizeViewToRootObject
|
||||||
m_dialog->engine()->addImageProvider(QStringLiteral("newprojectdialog_library"),
|
m_dialog->engine()->addImageProvider(QStringLiteral("newprojectdialog_library"),
|
||||||
new Internal::NewProjectDialogImageProvider());
|
new Internal::NewProjectDialogImageProvider());
|
||||||
@@ -190,8 +194,11 @@ void QdsNewDialog::updateScreenSizes()
|
|||||||
|
|
||||||
void QdsNewDialog::onWizardCreated(QStandardItemModel *screenSizeModel, QStandardItemModel *styleModel)
|
void QdsNewDialog::onWizardCreated(QStandardItemModel *screenSizeModel, QStandardItemModel *styleModel)
|
||||||
{
|
{
|
||||||
m_screenSizeModel->setBackendModel(screenSizeModel);
|
if (screenSizeModel)
|
||||||
m_styleModel->setBackendModel(styleModel);
|
m_screenSizeModel->setBackendModel(screenSizeModel);
|
||||||
|
|
||||||
|
if (styleModel)
|
||||||
|
m_styleModel->setBackendModel(styleModel);
|
||||||
|
|
||||||
auto userPreset = m_currentPreset->asUserPreset();
|
auto userPreset = m_currentPreset->asUserPreset();
|
||||||
|
|
||||||
@@ -326,7 +333,7 @@ void QdsNewDialog::setWizardFactories(QList<Core::IWizardFactory *> factories_,
|
|||||||
|
|
||||||
WizardFactories factories{factories_, m_dialog, platform};
|
WizardFactories factories{factories_, m_dialog, platform};
|
||||||
|
|
||||||
std::vector<RecentPresetData> recents = m_recentsStore.fetchAll();
|
std::vector<UserPresetData> recents = m_recentsStore.fetchAll();
|
||||||
std::vector<UserPresetData> userPresets = m_userPresetsStore.fetchAll();
|
std::vector<UserPresetData> userPresets = m_userPresetsStore.fetchAll();
|
||||||
m_presetData.setData(factories.presetsGroupedByCategory(), userPresets, recents);
|
m_presetData.setData(factories.presetsGroupedByCategory(), userPresets, recents);
|
||||||
|
|
||||||
@@ -360,33 +367,13 @@ void QdsNewDialog::setWizardFactories(QList<Core::IWizardFactory *> factories_,
|
|||||||
* sure that all events have occurred before we go ahead and configure the wizard.
|
* sure that all events have occurred before we go ahead and configure the wizard.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
auto userPreset = m_currentPreset->asUserPreset();
|
/* onWizardCreated will have been called by this time, as a result of m_presetModel->reset(),
|
||||||
|
* but at that time the Details and Styles panes haven't been loaded yet - only the backend
|
||||||
|
* models loaded. We call it again, cause at this point those panes are now loaded, and we can
|
||||||
|
* set them up.
|
||||||
|
*/
|
||||||
|
|
||||||
if (m_qmlDetailsLoaded) {
|
onWizardCreated(nullptr, nullptr);
|
||||||
updateScreenSizes();
|
|
||||||
|
|
||||||
if (m_wizard.haveTargetQtVersion()) {
|
|
||||||
int index = (userPreset ? m_wizard.targetQtVersionIndex(userPreset->qtVersion)
|
|
||||||
: m_wizard.targetQtVersionIndex());
|
|
||||||
if (index != -1)
|
|
||||||
setTargetQtVersionIndex(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_wizard.haveVirtualKeyboard() && userPreset)
|
|
||||||
setUseVirtualKeyboard(userPreset->useQtVirtualKeyboard);
|
|
||||||
|
|
||||||
emit haveVirtualKeyboardChanged();
|
|
||||||
emit haveTargetQtVersionChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_qmlStylesLoaded && m_wizard.haveStyleModel()) {
|
|
||||||
if (userPreset) {
|
|
||||||
int index = m_wizard.styleIndex(userPreset->styleName);
|
|
||||||
if (index != -1)
|
|
||||||
setStyleIndex(index);
|
|
||||||
}
|
|
||||||
m_styleModel->reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QdsNewDialog::recentsTabName() const
|
QString QdsNewDialog::recentsTabName() const
|
||||||
@@ -431,7 +418,8 @@ void QdsNewDialog::accept()
|
|||||||
std::shared_ptr<PresetItem> item = m_wizard.preset();
|
std::shared_ptr<PresetItem> item = m_wizard.preset();
|
||||||
QString customSizeName = m_qmlCustomWidth + " x " + m_qmlCustomHeight;
|
QString customSizeName = m_qmlCustomWidth + " x " + m_qmlCustomHeight;
|
||||||
|
|
||||||
m_recentsStore.add(item->categoryId, item->displayName(), customSizeName, item->isUserPreset());
|
UserPresetData preset = currentUserPresetData(m_currentPreset->displayName());
|
||||||
|
m_recentsStore.save(preset);
|
||||||
|
|
||||||
m_dialog->close();
|
m_dialog->close();
|
||||||
m_dialog->deleteLater();
|
m_dialog->deleteLater();
|
||||||
@@ -471,7 +459,7 @@ void QdsNewDialog::setSelectedPreset(int selection)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QdsNewDialog::savePresetDialogAccept()
|
UserPresetData QdsNewDialog::currentUserPresetData(const QString &displayName) const
|
||||||
{
|
{
|
||||||
QString screenSize = m_qmlCustomWidth + " x " + m_qmlCustomHeight;
|
QString screenSize = m_qmlCustomWidth + " x " + m_qmlCustomHeight;
|
||||||
QString targetQtVersion = "";
|
QString targetQtVersion = "";
|
||||||
@@ -489,12 +477,19 @@ void QdsNewDialog::savePresetDialogAccept()
|
|||||||
|
|
||||||
UserPresetData preset = {m_currentPreset->categoryId,
|
UserPresetData preset = {m_currentPreset->categoryId,
|
||||||
m_currentPreset->wizardName,
|
m_currentPreset->wizardName,
|
||||||
m_qmlPresetName,
|
displayName,
|
||||||
screenSize,
|
screenSize,
|
||||||
useVirtualKeyboard,
|
useVirtualKeyboard,
|
||||||
targetQtVersion,
|
targetQtVersion,
|
||||||
styleName};
|
styleName};
|
||||||
|
|
||||||
|
return preset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QdsNewDialog::savePresetDialogAccept()
|
||||||
|
{
|
||||||
|
UserPresetData preset = currentUserPresetData(m_qmlPresetName);
|
||||||
|
|
||||||
if (!m_userPresetsStore.save(preset)) {
|
if (!m_userPresetsStore.save(preset)) {
|
||||||
QMessageBox::warning(m_dialog,
|
QMessageBox::warning(m_dialog,
|
||||||
tr("Save Preset"),
|
tr("Save Preset"),
|
||||||
@@ -503,7 +498,7 @@ void QdsNewDialog::savePresetDialogAccept()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// reload model
|
// reload model
|
||||||
std::vector<RecentPresetData> recents = m_recentsStore.fetchAll();
|
std::vector<UserPresetData> recents = m_recentsStore.fetchAll();
|
||||||
std::vector<UserPresetData> userPresets = m_userPresetsStore.fetchAll();
|
std::vector<UserPresetData> userPresets = m_userPresetsStore.fetchAll();
|
||||||
m_presetData.reload(userPresets, recents);
|
m_presetData.reload(userPresets, recents);
|
||||||
|
|
||||||
@@ -520,8 +515,8 @@ void QdsNewDialog::removeCurrentPreset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// remove preset & reload model
|
// remove preset & reload model
|
||||||
std::vector<RecentPresetData> recents = m_recentsStore.remove(m_currentPreset->categoryId,
|
UserPresetData currentPreset = currentUserPresetData(m_qmlPresetName);
|
||||||
m_currentPreset->displayName());
|
std::vector<UserPresetData> recents = m_recentsStore.remove(currentPreset);
|
||||||
|
|
||||||
auto userPreset = m_currentPreset->asUserPreset();
|
auto userPreset = m_currentPreset->asUserPreset();
|
||||||
m_userPresetsStore.remove(userPreset->categoryId, userPreset->displayName());
|
m_userPresetsStore.remove(userPreset->categoryId, userPreset->displayName());
|
||||||
|
@@ -34,7 +34,6 @@
|
|||||||
#include "presetmodel.h"
|
#include "presetmodel.h"
|
||||||
#include "screensizemodel.h"
|
#include "screensizemodel.h"
|
||||||
#include "stylemodel.h"
|
#include "stylemodel.h"
|
||||||
#include "recentpresets.h"
|
|
||||||
#include "userpresets.h"
|
#include "userpresets.h"
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@@ -153,6 +152,7 @@ private:
|
|||||||
|
|
||||||
void updateScreenSizes();
|
void updateScreenSizes();
|
||||||
bool eventFilter(QObject *obj, QEvent *ev) override;
|
bool eventFilter(QObject *obj, QEvent *ev) override;
|
||||||
|
UserPresetData currentUserPresetData(const QString &displayName) const;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onDeletingWizard();
|
void onDeletingWizard();
|
||||||
@@ -194,7 +194,7 @@ private:
|
|||||||
std::shared_ptr<PresetItem> m_currentPreset;
|
std::shared_ptr<PresetItem> m_currentPreset;
|
||||||
|
|
||||||
WizardHandler m_wizard;
|
WizardHandler m_wizard;
|
||||||
RecentPresetsStore m_recentsStore;
|
UserPresetsStore m_recentsStore;
|
||||||
UserPresetsStore m_userPresetsStore;
|
UserPresetsStore m_userPresetsStore;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,152 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2022 The Qt Company Ltd.
|
|
||||||
** Contact: https://www.qt.io/licensing/
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator.
|
|
||||||
**
|
|
||||||
** Commercial License Usage
|
|
||||||
** Licensees holding valid commercial Qt licenses may use this file in
|
|
||||||
** accordance with the commercial license agreement provided with the
|
|
||||||
** Software or, alternatively, in accordance with the terms contained in
|
|
||||||
** a written agreement between you and The Qt Company. For licensing terms
|
|
||||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
||||||
** information use the contact form at https://www.qt.io/contact-us.
|
|
||||||
**
|
|
||||||
** GNU General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU
|
|
||||||
** General Public License version 3 as published by the Free Software
|
|
||||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
||||||
** included in the packaging of this file. Please review the following
|
|
||||||
** information to ensure the GNU General Public License requirements will
|
|
||||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "recentpresets.h"
|
|
||||||
#include "algorithm.h"
|
|
||||||
|
|
||||||
#include <QRegularExpression>
|
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
|
||||||
#include <utils/qtcassert.h>
|
|
||||||
#include <utils/qtcsettings.h>
|
|
||||||
|
|
||||||
using namespace StudioWelcome;
|
|
||||||
|
|
||||||
constexpr char GROUP_NAME[] = "RecentPresets";
|
|
||||||
constexpr char WIZARDS[] = "Wizards";
|
|
||||||
|
|
||||||
void RecentPresetsStore::add(const QString &categoryId,
|
|
||||||
const QString &name,
|
|
||||||
const QString &sizeName,
|
|
||||||
bool isUserPreset)
|
|
||||||
{
|
|
||||||
std::vector<RecentPresetData> existing = fetchAll();
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> recents
|
|
||||||
= addRecentToExisting(RecentPresetData{categoryId, name, sizeName, isUserPreset}, existing);
|
|
||||||
|
|
||||||
save(recents);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RecentPresetsStore::save(const std::vector<RecentPresetData> &recents)
|
|
||||||
{
|
|
||||||
QStringList encodedRecents = encodeRecentPresets(recents);
|
|
||||||
|
|
||||||
m_settings->beginGroup(GROUP_NAME);
|
|
||||||
m_settings->setValue(WIZARDS, encodedRecents);
|
|
||||||
m_settings->endGroup();
|
|
||||||
m_settings->sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> RecentPresetsStore::remove(const QString &categoryId, const QString &presetName)
|
|
||||||
{
|
|
||||||
std::vector<RecentPresetData> recents = fetchAll();
|
|
||||||
size_t countBefore = recents.size();
|
|
||||||
|
|
||||||
/* NOTE: when removing one preset, it may happen that there are more than one recent for that
|
|
||||||
* preset. In that case, we need to remove all associated recents, for the preset.*/
|
|
||||||
|
|
||||||
Utils::erase(recents, [&](const RecentPresetData &p) {
|
|
||||||
return p.category == categoryId && p.presetName == presetName;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (recents.size() < countBefore)
|
|
||||||
save(recents);
|
|
||||||
|
|
||||||
return recents;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> RecentPresetsStore::addRecentToExisting(
|
|
||||||
const RecentPresetData &preset, std::vector<RecentPresetData> &recents)
|
|
||||||
{
|
|
||||||
Utils::erase_one(recents, preset);
|
|
||||||
Utils::prepend(recents, preset);
|
|
||||||
|
|
||||||
if (int(recents.size()) > m_max)
|
|
||||||
recents.pop_back();
|
|
||||||
|
|
||||||
return recents;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> RecentPresetsStore::fetchAll() const
|
|
||||||
{
|
|
||||||
m_settings->beginGroup(GROUP_NAME);
|
|
||||||
QVariant value = m_settings->value(WIZARDS);
|
|
||||||
m_settings->endGroup();
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> result;
|
|
||||||
|
|
||||||
if (value.type() == QVariant::String)
|
|
||||||
result.push_back(decodeOneRecentPreset(value.toString()));
|
|
||||||
else if (value.type() == QVariant::StringList)
|
|
||||||
Utils::concat(result, decodeRecentPresets(value.toList()));
|
|
||||||
|
|
||||||
const RecentPresetData empty;
|
|
||||||
return Utils::filtered(result, [&empty](const RecentPresetData &recent) { return recent != empty; });
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList RecentPresetsStore::encodeRecentPresets(const std::vector<RecentPresetData> &recents)
|
|
||||||
{
|
|
||||||
return Utils::transform<QList>(recents, [](const RecentPresetData &p) -> QString {
|
|
||||||
QString name = p.presetName;
|
|
||||||
if (p.isUserPreset)
|
|
||||||
name.prepend("[U]");
|
|
||||||
|
|
||||||
return p.category + "/" + name + ":" + p.sizeName;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
RecentPresetData RecentPresetsStore::decodeOneRecentPreset(const QString &encoded)
|
|
||||||
{
|
|
||||||
QRegularExpression pattern{R"(^(\S+)/(.+):(\d+ x \d+)$)"};
|
|
||||||
auto m = pattern.match(encoded);
|
|
||||||
if (!m.hasMatch())
|
|
||||||
return RecentPresetData{};
|
|
||||||
|
|
||||||
QString category = m.captured(1);
|
|
||||||
QString name = m.captured(2);
|
|
||||||
QString size = m.captured(3);
|
|
||||||
bool isUserPreset = name.startsWith("[U]");
|
|
||||||
if (isUserPreset)
|
|
||||||
name = name.split("[U]")[1];
|
|
||||||
|
|
||||||
if (!QRegularExpression{R"(^\w[\w ]*$)"}.match(name).hasMatch())
|
|
||||||
return RecentPresetData{};
|
|
||||||
|
|
||||||
RecentPresetData result;
|
|
||||||
result.category = category;
|
|
||||||
result.presetName = name;
|
|
||||||
result.sizeName = size;
|
|
||||||
result.isUserPreset = isUserPreset;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> RecentPresetsStore::decodeRecentPresets(const QVariantList &values)
|
|
||||||
{
|
|
||||||
return Utils::transform<std::vector>(values, [](const QVariant &value) {
|
|
||||||
return decodeOneRecentPreset(value.toString());
|
|
||||||
});
|
|
||||||
}
|
|
@@ -1,103 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2022 The Qt Company Ltd.
|
|
||||||
** Contact: https://www.qt.io/licensing/
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator.
|
|
||||||
**
|
|
||||||
** Commercial License Usage
|
|
||||||
** Licensees holding valid commercial Qt licenses may use this file in
|
|
||||||
** accordance with the commercial license agreement provided with the
|
|
||||||
** Software or, alternatively, in accordance with the terms contained in
|
|
||||||
** a written agreement between you and The Qt Company. For licensing terms
|
|
||||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
||||||
** information use the contact form at https://www.qt.io/contact-us.
|
|
||||||
**
|
|
||||||
** GNU General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU
|
|
||||||
** General Public License version 3 as published by the Free Software
|
|
||||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
||||||
** included in the packaging of this file. Please review the following
|
|
||||||
** information to ensure the GNU General Public License requirements will
|
|
||||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QPair>
|
|
||||||
#include <QSettings>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace StudioWelcome {
|
|
||||||
|
|
||||||
struct RecentPresetData
|
|
||||||
{
|
|
||||||
RecentPresetData() = default;
|
|
||||||
RecentPresetData(const QString &category,
|
|
||||||
const QString &name,
|
|
||||||
const QString &size,
|
|
||||||
bool isUserPreset = false)
|
|
||||||
: category{category}
|
|
||||||
, presetName{name}
|
|
||||||
, sizeName{size}
|
|
||||||
, isUserPreset{isUserPreset}
|
|
||||||
{}
|
|
||||||
|
|
||||||
QString category;
|
|
||||||
QString presetName;
|
|
||||||
QString sizeName;
|
|
||||||
bool isUserPreset = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool operator==(const RecentPresetData &lhs, const RecentPresetData &rhs)
|
|
||||||
{
|
|
||||||
return lhs.category == rhs.category && lhs.presetName == rhs.presetName
|
|
||||||
&& lhs.sizeName == rhs.sizeName && lhs.isUserPreset == rhs.isUserPreset;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(const RecentPresetData &lhs, const RecentPresetData &rhs)
|
|
||||||
{
|
|
||||||
return !(lhs == rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QDebug &operator<<(QDebug &d, const RecentPresetData &preset)
|
|
||||||
{
|
|
||||||
d << "RecentPreset{category=" << preset.category << "; name=" << preset.presetName
|
|
||||||
<< "; size=" << preset.sizeName << "; isUserPreset=" << preset.isUserPreset << "}";
|
|
||||||
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
class RecentPresetsStore
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit RecentPresetsStore(QSettings *settings)
|
|
||||||
: m_settings{settings}
|
|
||||||
{}
|
|
||||||
|
|
||||||
void setMaximum(int n) { m_max = n; }
|
|
||||||
void add(const QString &categoryId,
|
|
||||||
const QString &name,
|
|
||||||
const QString &sizeName,
|
|
||||||
bool isUserPreset = false);
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> remove(const QString &categoryId, const QString &presetName);
|
|
||||||
std::vector<RecentPresetData> fetchAll() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<RecentPresetData> addRecentToExisting(const RecentPresetData &preset,
|
|
||||||
std::vector<RecentPresetData> &recents);
|
|
||||||
static QStringList encodeRecentPresets(const std::vector<RecentPresetData> &recents);
|
|
||||||
static std::vector<RecentPresetData> decodeRecentPresets(const QVariantList &values);
|
|
||||||
static RecentPresetData decodeOneRecentPreset(const QString &encoded);
|
|
||||||
void save(const std::vector<RecentPresetData> &recents);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QSettings *m_settings = nullptr;
|
|
||||||
int m_max = 10;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace StudioWelcome
|
|
@@ -37,8 +37,6 @@ QtcPlugin {
|
|||||||
"wizardfactories.h",
|
"wizardfactories.h",
|
||||||
"wizardhandler.cpp",
|
"wizardhandler.cpp",
|
||||||
"wizardhandler.h",
|
"wizardhandler.h",
|
||||||
"recentpresets.cpp",
|
|
||||||
"recentpresets.h",
|
|
||||||
"userpresets.cpp",
|
"userpresets.cpp",
|
||||||
"userpresets.h"
|
"userpresets.h"
|
||||||
]
|
]
|
||||||
|
@@ -24,43 +24,75 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "userpresets.h"
|
#include "userpresets.h"
|
||||||
|
#include "algorithm.h"
|
||||||
|
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonValue>
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <utils/algorithm.h>
|
#include <memory>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
using namespace StudioWelcome;
|
using namespace StudioWelcome;
|
||||||
|
|
||||||
constexpr char PREFIX[] = "UserPresets";
|
FileStoreIo::FileStoreIo(const QString &fileName)
|
||||||
|
: m_file{std::make_unique<QFile>(fullFilePath(fileName))}
|
||||||
UserPresetsStore::UserPresetsStore()
|
|
||||||
{
|
|
||||||
m_settings = std::make_unique<QSettings>(fullFilePath(), QSettings::IniFormat);
|
|
||||||
}
|
|
||||||
|
|
||||||
UserPresetsStore::UserPresetsStore(std::unique_ptr<QSettings> &&settings)
|
|
||||||
: m_settings{std::move(settings)}
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void UserPresetsStore::savePresets(const std::vector<UserPresetData> &presets)
|
QByteArray FileStoreIo::read() const
|
||||||
{
|
{
|
||||||
m_settings->beginWriteArray(PREFIX, static_cast<int>(presets.size()));
|
m_file->open(QFile::ReadOnly | QFile::Text);
|
||||||
|
QByteArray data = m_file->readAll();
|
||||||
|
m_file->close();
|
||||||
|
|
||||||
for (size_t i = 0; i < presets.size(); ++i) {
|
return data;
|
||||||
m_settings->setArrayIndex(static_cast<int>(i));
|
}
|
||||||
const auto &preset = presets[i];
|
|
||||||
|
|
||||||
m_settings->setValue("categoryId", preset.categoryId);
|
void FileStoreIo::write(const QByteArray &data)
|
||||||
m_settings->setValue("wizardName", preset.wizardName);
|
{
|
||||||
m_settings->setValue("name", preset.name);
|
m_file->open(QFile::WriteOnly | QFile::Text);
|
||||||
m_settings->setValue("screenSize", preset.screenSize);
|
m_file->write(data);
|
||||||
m_settings->setValue("useQtVirtualKeyboard", preset.useQtVirtualKeyboard);
|
m_file->close();
|
||||||
m_settings->setValue("qtVersion", preset.qtVersion);
|
}
|
||||||
m_settings->setValue("styleName", preset.styleName);
|
|
||||||
|
QString FileStoreIo::fullFilePath(const QString &fileName) const
|
||||||
|
{
|
||||||
|
return Core::ICore::userResourcePath(fileName).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
UserPresetsStore::UserPresetsStore(const QString &fileName, StorePolicy policy)
|
||||||
|
: m_store{std::make_unique<FileStoreIo>(fileName)}
|
||||||
|
, m_policy{policy}
|
||||||
|
{}
|
||||||
|
|
||||||
|
UserPresetsStore::UserPresetsStore(std::unique_ptr<StoreIo> &&fileStore,
|
||||||
|
StorePolicy policy)
|
||||||
|
: m_store{std::move(fileStore)}
|
||||||
|
, m_policy{policy}
|
||||||
|
{}
|
||||||
|
|
||||||
|
void UserPresetsStore::savePresets(const std::vector<UserPresetData> &presetItems)
|
||||||
|
{
|
||||||
|
QJsonArray jsonArray;
|
||||||
|
|
||||||
|
for (const auto &preset : presetItems) {
|
||||||
|
QJsonObject obj({{"categoryId", preset.categoryId},
|
||||||
|
{"wizardName", preset.wizardName},
|
||||||
|
{"name", preset.name},
|
||||||
|
{"screenSize", preset.screenSize},
|
||||||
|
{"useQtVirtualKeyboard", preset.useQtVirtualKeyboard},
|
||||||
|
{"qtVersion", preset.qtVersion},
|
||||||
|
{"styleName", preset.styleName}});
|
||||||
|
|
||||||
|
jsonArray.append(QJsonValue{obj});
|
||||||
}
|
}
|
||||||
m_settings->endArray();
|
|
||||||
m_settings->sync();
|
|
||||||
|
|
||||||
|
QJsonDocument doc(jsonArray);
|
||||||
|
QByteArray data = doc.toJson();
|
||||||
|
|
||||||
|
m_store->write(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UserPresetsStore::save(const UserPresetData &newPreset)
|
bool UserPresetsStore::save(const UserPresetData &newPreset)
|
||||||
@@ -68,12 +100,30 @@ bool UserPresetsStore::save(const UserPresetData &newPreset)
|
|||||||
QTC_ASSERT(newPreset.isValid(), return false);
|
QTC_ASSERT(newPreset.isValid(), return false);
|
||||||
|
|
||||||
std::vector<UserPresetData> presetItems = fetchAll();
|
std::vector<UserPresetData> presetItems = fetchAll();
|
||||||
if (Utils::anyOf(presetItems,
|
|
||||||
[&newPreset](const UserPresetData &p) { return p.name == newPreset.name; })) {
|
if (m_policy == StorePolicy::UniqueNames) {
|
||||||
return false;
|
if (Utils::anyOf(presetItems, [&newPreset](const UserPresetData &p) {
|
||||||
|
return p.name == newPreset.name;
|
||||||
|
})) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (m_policy == StorePolicy::UniqueValues) {
|
||||||
|
if (Utils::containsItem(presetItems, newPreset))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_reverse)
|
||||||
|
Utils::prepend(presetItems, newPreset);
|
||||||
|
else
|
||||||
|
presetItems.push_back(newPreset);
|
||||||
|
|
||||||
|
if (m_maximum > -1 && static_cast<int>(presetItems.size()) > m_maximum) {
|
||||||
|
if (m_reverse)
|
||||||
|
presetItems.pop_back();
|
||||||
|
else
|
||||||
|
presetItems.erase(std::cbegin(presetItems));
|
||||||
}
|
}
|
||||||
|
|
||||||
presetItems.push_back(newPreset);
|
|
||||||
savePresets(presetItems);
|
savePresets(presetItems);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -92,34 +142,45 @@ void UserPresetsStore::remove(const QString &category, const QString &name)
|
|||||||
savePresets(presetItems);
|
savePresets(presetItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<UserPresetData> UserPresetsStore::remove(const UserPresetData &preset)
|
||||||
|
{
|
||||||
|
std::vector<UserPresetData> presetItems = fetchAll();
|
||||||
|
bool erased = Utils::erase_one(presetItems, preset);
|
||||||
|
if (erased)
|
||||||
|
savePresets(presetItems);
|
||||||
|
|
||||||
|
return presetItems;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<UserPresetData> UserPresetsStore::fetchAll() const
|
std::vector<UserPresetData> UserPresetsStore::fetchAll() const
|
||||||
{
|
{
|
||||||
|
QByteArray data = m_store->read();
|
||||||
|
|
||||||
|
const QJsonDocument doc = QJsonDocument::fromJson(data);
|
||||||
|
if (!doc.isArray())
|
||||||
|
return {};
|
||||||
|
|
||||||
std::vector<UserPresetData> result;
|
std::vector<UserPresetData> result;
|
||||||
int size = m_settings->beginReadArray(PREFIX);
|
const QJsonArray jsonArray = doc.array();
|
||||||
if (size >= 0)
|
|
||||||
result.reserve(static_cast<size_t>(size) + 1);
|
|
||||||
|
|
||||||
for (int i = 0; i < size; ++i) {
|
for (const QJsonValue &value: jsonArray) {
|
||||||
m_settings->setArrayIndex(i);
|
if (!value.isObject())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const QJsonObject obj = value.toObject();
|
||||||
UserPresetData preset;
|
UserPresetData preset;
|
||||||
preset.categoryId = m_settings->value("categoryId").toString();
|
|
||||||
preset.wizardName = m_settings->value("wizardName").toString();
|
preset.categoryId = obj["categoryId"].toString();
|
||||||
preset.name = m_settings->value("name").toString();
|
preset.wizardName = obj["wizardName"].toString();
|
||||||
preset.screenSize = m_settings->value("screenSize").toString();
|
preset.name = obj["name"].toString();
|
||||||
preset.useQtVirtualKeyboard = m_settings->value("useQtVirtualKeyboard").toBool();
|
preset.screenSize = obj["screenSize"].toString();
|
||||||
preset.qtVersion = m_settings->value("qtVersion").toString();
|
preset.useQtVirtualKeyboard = obj["useQtVirtualKeyboard"].toBool();
|
||||||
preset.styleName = m_settings->value("styleName").toString();
|
preset.qtVersion = obj["qtVersion"].toString();
|
||||||
|
preset.styleName = obj["styleName"].toString();
|
||||||
|
|
||||||
if (preset.isValid())
|
if (preset.isValid())
|
||||||
result.push_back(std::move(preset));
|
result.push_back(preset);
|
||||||
}
|
}
|
||||||
m_settings->endArray();
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString UserPresetsStore::fullFilePath() const
|
|
||||||
{
|
|
||||||
return Core::ICore::userResourcePath("UserPresets.ini").toString();
|
|
||||||
}
|
|
||||||
|
@@ -25,8 +25,10 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <QFile>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QSettings>
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -70,24 +72,59 @@ inline bool operator==(const UserPresetData &lhs, const UserPresetData &rhs)
|
|||||||
return lhs.categoryId == rhs.categoryId && lhs.wizardName == rhs.wizardName
|
return lhs.categoryId == rhs.categoryId && lhs.wizardName == rhs.wizardName
|
||||||
&& lhs.name == rhs.name && lhs.screenSize == rhs.screenSize
|
&& lhs.name == rhs.name && lhs.screenSize == rhs.screenSize
|
||||||
&& lhs.useQtVirtualKeyboard == rhs.useQtVirtualKeyboard && lhs.qtVersion == rhs.qtVersion
|
&& lhs.useQtVirtualKeyboard == rhs.useQtVirtualKeyboard && lhs.qtVersion == rhs.qtVersion
|
||||||
&& lhs.styleName == rhs.styleName;
|
&& lhs.styleName == rhs.styleName;;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class StorePolicy {UniqueNames, UniqueValues};
|
||||||
|
|
||||||
|
class StoreIo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~StoreIo() {}
|
||||||
|
|
||||||
|
virtual QByteArray read() const = 0;
|
||||||
|
virtual void write(const QByteArray &bytes) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileStoreIo : public StoreIo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit FileStoreIo(const QString &fileName);
|
||||||
|
FileStoreIo(FileStoreIo &&other): m_file{std::move(other.m_file)} {}
|
||||||
|
FileStoreIo& operator=(FileStoreIo &&other) { m_file = std::move(other.m_file); return *this; }
|
||||||
|
|
||||||
|
QByteArray read() const override;
|
||||||
|
void write(const QByteArray &data) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString fullFilePath(const QString &fileName) const;
|
||||||
|
|
||||||
|
std::unique_ptr<QFile> m_file;
|
||||||
|
|
||||||
|
Q_DISABLE_COPY(FileStoreIo)
|
||||||
|
};
|
||||||
|
|
||||||
class UserPresetsStore
|
class UserPresetsStore
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UserPresetsStore();
|
UserPresetsStore(const QString &fileName, StorePolicy policy);
|
||||||
UserPresetsStore(std::unique_ptr<QSettings> &&settings);
|
UserPresetsStore(std::unique_ptr<StoreIo> &&store, StorePolicy policy);
|
||||||
|
|
||||||
bool save(const UserPresetData &preset);
|
bool save(const UserPresetData &preset);
|
||||||
void remove(const QString &category, const QString &name);
|
|
||||||
std::vector<UserPresetData> fetchAll() const;
|
std::vector<UserPresetData> fetchAll() const;
|
||||||
|
void remove(const QString &category, const QString &name);
|
||||||
|
std::vector<UserPresetData> remove(const UserPresetData &preset);
|
||||||
|
|
||||||
|
void setMaximum(int maximum) { m_maximum = maximum; }
|
||||||
|
void setReverseOrder() { m_reverse = true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString fullFilePath() const;
|
|
||||||
void savePresets(const std::vector<UserPresetData> &presets);
|
void savePresets(const std::vector<UserPresetData> &presets);
|
||||||
|
|
||||||
std::unique_ptr<QSettings> m_settings;
|
std::unique_ptr<StoreIo> m_store;
|
||||||
|
StorePolicy m_policy = StorePolicy::UniqueNames;
|
||||||
|
bool m_reverse = false;
|
||||||
|
int m_maximum = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace StudioWelcome
|
} // namespace StudioWelcome
|
||||||
|
@@ -328,10 +328,13 @@ bool RefactoringFile::apply()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// open / activate / goto position
|
// open / activate / goto position
|
||||||
|
bool ensureCursorVisible = false;
|
||||||
if (m_openEditor && !m_filePath.isEmpty()) {
|
if (m_openEditor && !m_filePath.isEmpty()) {
|
||||||
int line = -1, column = -1;
|
int line = -1, column = -1;
|
||||||
if (m_editorCursorPosition != -1)
|
if (m_editorCursorPosition != -1) {
|
||||||
lineAndColumn(m_editorCursorPosition, &line, &column);
|
lineAndColumn(m_editorCursorPosition, &line, &column);
|
||||||
|
ensureCursorVisible = true;
|
||||||
|
}
|
||||||
m_editor = RefactoringChanges::openEditor(m_filePath, m_activateEditor, line, column);
|
m_editor = RefactoringChanges::openEditor(m_filePath, m_activateEditor, line, column);
|
||||||
m_openEditor = false;
|
m_openEditor = false;
|
||||||
m_activateEditor = false;
|
m_activateEditor = false;
|
||||||
@@ -392,6 +395,9 @@ bool RefactoringFile::apply()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_editor && ensureCursorVisible)
|
||||||
|
m_editor->ensureCursorVisible();
|
||||||
|
|
||||||
m_appliedOnce = true;
|
m_appliedOnce = true;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@@ -17,14 +17,12 @@ add_qtc_test(tst_qml_wizard
|
|||||||
SOURCES
|
SOURCES
|
||||||
wizardfactories-test.cpp
|
wizardfactories-test.cpp
|
||||||
stylemodel-test.cpp
|
stylemodel-test.cpp
|
||||||
recentpresets-test.cpp
|
|
||||||
userpresets-test.cpp
|
userpresets-test.cpp
|
||||||
presetmodel-test.cpp
|
presetmodel-test.cpp
|
||||||
test-utilities.h
|
test-utilities.h
|
||||||
test-main.cpp
|
test-main.cpp
|
||||||
"${StudioWelcomeDir}/wizardfactories.cpp"
|
"${StudioWelcomeDir}/wizardfactories.cpp"
|
||||||
"${StudioWelcomeDir}/stylemodel.cpp"
|
"${StudioWelcomeDir}/stylemodel.cpp"
|
||||||
"${StudioWelcomeDir}/recentpresets.cpp"
|
|
||||||
"${StudioWelcomeDir}/userpresets.cpp"
|
"${StudioWelcomeDir}/userpresets.cpp"
|
||||||
"${StudioWelcomeDir}/presetmodel.cpp"
|
"${StudioWelcomeDir}/presetmodel.cpp"
|
||||||
)
|
)
|
||||||
|
@@ -100,6 +100,14 @@ UserPresetData aUserPreset(const QString &categId, const QString &wizardName, co
|
|||||||
return preset;
|
return preset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UserPresetData aRecentPreset(const QString &categId, const QString &wizardName, const QString &screenSizeName)
|
||||||
|
{
|
||||||
|
UserPresetData preset = aUserPreset(categId, wizardName, wizardName);
|
||||||
|
preset.screenSize = screenSizeName;
|
||||||
|
|
||||||
|
return preset;
|
||||||
|
}
|
||||||
|
|
||||||
MATCHER_P2(PresetIs, category, name, PrintToString(PresetItem{name, category}))
|
MATCHER_P2(PresetIs, category, name, PrintToString(PresetItem{name, category}))
|
||||||
{
|
{
|
||||||
return arg->categoryId == category && arg->wizardName == name;
|
return arg->categoryId == category && arg->wizardName == name;
|
||||||
@@ -139,6 +147,7 @@ TEST(QdsPresetModel, haveSameArraySizeForPresetsAndCategories)
|
|||||||
PresetData data;
|
PresetData data;
|
||||||
|
|
||||||
data.setData(
|
data.setData(
|
||||||
|
/*wizard presets*/
|
||||||
{
|
{
|
||||||
aCategory("A.categ", "A", {"item a", "item b"}),
|
aCategory("A.categ", "A", {"item a", "item b"}),
|
||||||
aCategory("B.categ", "B", {"item c", "item d"}),
|
aCategory("B.categ", "B", {"item c", "item d"}),
|
||||||
@@ -157,6 +166,7 @@ TEST(QdsPresetModel, haveWizardPresetsNoRecents)
|
|||||||
|
|
||||||
// When
|
// When
|
||||||
data.setData(
|
data.setData(
|
||||||
|
/*wizard presets*/
|
||||||
{
|
{
|
||||||
aCategory("A.categ", "A", {"item a", "item b"}),
|
aCategory("A.categ", "A", {"item a", "item b"}),
|
||||||
aCategory("B.categ", "B", {"item c", "item d"}),
|
aCategory("B.categ", "B", {"item c", "item d"}),
|
||||||
@@ -179,6 +189,7 @@ TEST(QdsPresetModel, whenHaveUserPresetsButNoWizardPresetsReturnEmpty)
|
|||||||
|
|
||||||
// When
|
// When
|
||||||
data.setData({/*builtin presets*/},
|
data.setData({/*builtin presets*/},
|
||||||
|
/*user presets*/
|
||||||
{
|
{
|
||||||
aUserPreset("A.Mobile", "Scroll", "iPhone5"),
|
aUserPreset("A.Mobile", "Scroll", "iPhone5"),
|
||||||
aUserPreset("B.Desktop", "Launcher", "MacBook"),
|
aUserPreset("B.Desktop", "Launcher", "MacBook"),
|
||||||
@@ -196,9 +207,10 @@ TEST(QdsPresetModel, haveRecentsNoWizardPresets)
|
|||||||
|
|
||||||
data.setData({/*wizardPresets*/},
|
data.setData({/*wizardPresets*/},
|
||||||
{/*user presets*/},
|
{/*user presets*/},
|
||||||
|
/*recent presets*/
|
||||||
{
|
{
|
||||||
{"A.categ", "Desktop", "640 x 480"},
|
aRecentPreset("A.categ", "Desktop", "640 x 480"),
|
||||||
{"B.categ", "Mobile", "800 x 600"},
|
aRecentPreset("B.categ", "Mobile", "800 x 600"),
|
||||||
});
|
});
|
||||||
|
|
||||||
ASSERT_THAT(data.categories(), IsEmpty());
|
ASSERT_THAT(data.categories(), IsEmpty());
|
||||||
@@ -220,8 +232,8 @@ TEST(QdsPresetModel, recentsAddedWithWizardPresets)
|
|||||||
{/*user presets*/},
|
{/*user presets*/},
|
||||||
/*recents*/
|
/*recents*/
|
||||||
{
|
{
|
||||||
{"A.categ", "Desktop", "800 x 600"},
|
aRecentPreset("A.categ", "Desktop", "800 x 600"),
|
||||||
{"B.categ", "Mobile", "640 x 480"},
|
aRecentPreset("B.categ", "Mobile", "640 x 480"),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
@@ -247,6 +259,7 @@ TEST(QdsPresetModel, userPresetsAddedWithWizardPresets)
|
|||||||
aCategory("A.categ", "A", {"Desktop", "item b"}),
|
aCategory("A.categ", "A", {"Desktop", "item b"}),
|
||||||
aCategory("B.categ", "B", {"Mobile"}),
|
aCategory("B.categ", "B", {"Mobile"}),
|
||||||
},
|
},
|
||||||
|
/*user presets*/
|
||||||
{
|
{
|
||||||
aUserPreset("A.categ", "Desktop", "Windows10"),
|
aUserPreset("A.categ", "Desktop", "Windows10"),
|
||||||
},
|
},
|
||||||
@@ -272,6 +285,7 @@ TEST(QdsPresetModel, doesNotAddUserPresetsOfNonExistingCategory)
|
|||||||
{
|
{
|
||||||
aCategory("A.categ", "A", {"Desktop"}), // Only category "A.categ" exists
|
aCategory("A.categ", "A", {"Desktop"}), // Only category "A.categ" exists
|
||||||
},
|
},
|
||||||
|
/*user presets*/
|
||||||
{
|
{
|
||||||
aUserPreset("Bad.Categ", "Desktop", "Windows8"), // Bad.Categ does not exist
|
aUserPreset("Bad.Categ", "Desktop", "Windows8"), // Bad.Categ does not exist
|
||||||
},
|
},
|
||||||
@@ -293,6 +307,7 @@ TEST(QdsPresetModel, doesNotAddUserPresetIfWizardPresetItRefersToDoesNotExist)
|
|||||||
{
|
{
|
||||||
aCategory("A.categ", "A", {"Desktop"}),
|
aCategory("A.categ", "A", {"Desktop"}),
|
||||||
},
|
},
|
||||||
|
/*user presets*/
|
||||||
{
|
{
|
||||||
aUserPreset("B.categ", "BadWizard", "Tablet"), // BadWizard referenced does not exist
|
aUserPreset("B.categ", "BadWizard", "Tablet"), // BadWizard referenced does not exist
|
||||||
},
|
},
|
||||||
@@ -314,6 +329,7 @@ TEST(QdsPresetModel, userPresetWithSameNameAsWizardPreset)
|
|||||||
{
|
{
|
||||||
aCategory("A.categ", "A", {"Desktop"}),
|
aCategory("A.categ", "A", {"Desktop"}),
|
||||||
},
|
},
|
||||||
|
/*user presets*/
|
||||||
{
|
{
|
||||||
aUserPreset("A.categ", "Desktop", "Desktop"),
|
aUserPreset("A.categ", "Desktop", "Desktop"),
|
||||||
},
|
},
|
||||||
@@ -326,58 +342,7 @@ TEST(QdsPresetModel, userPresetWithSameNameAsWizardPreset)
|
|||||||
ElementsAre(UserPresetIs("A.categ", "Desktop", "Desktop"))));
|
ElementsAre(UserPresetIs("A.categ", "Desktop", "Desktop"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(QdsPresetModel, recentOfUserPresetReferringToExistingWizardPreset)
|
TEST(QdsPresetModel, recentOfNonExistentWizardPreset)
|
||||||
{
|
|
||||||
// Given
|
|
||||||
PresetData data;
|
|
||||||
|
|
||||||
// When
|
|
||||||
data.setData(
|
|
||||||
/*wizard presets*/
|
|
||||||
{
|
|
||||||
aCategory("A.categ", "A", {"Desktop"}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
aUserPreset("A.categ", "Desktop", "Windows 7"),
|
|
||||||
},
|
|
||||||
/*recents*/
|
|
||||||
{
|
|
||||||
{"A.categ", "Windows 7", "200 x 300", /*is user*/true}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Then
|
|
||||||
ASSERT_THAT(data.categories(), ElementsAre("Recents", "A", "Custom"));
|
|
||||||
ASSERT_THAT(data.presets(),
|
|
||||||
ElementsAre(ElementsAre(UserPresetIs("A.categ", "Desktop", "Windows 7")),
|
|
||||||
ElementsAre(PresetIs("A.categ", "Desktop")),
|
|
||||||
ElementsAre(UserPresetIs("A.categ", "Desktop", "Windows 7"))));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(QdsPresetModel, recentOfUserPresetReferringToNonexistingWizardPreset)
|
|
||||||
{
|
|
||||||
// Given
|
|
||||||
PresetData data;
|
|
||||||
|
|
||||||
// When
|
|
||||||
data.setData(
|
|
||||||
/*wizard presets*/
|
|
||||||
{
|
|
||||||
aCategory("A.categ", "A", {"Desktop"}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
aUserPreset("A.categ", "Not-Desktop", "Windows 7"), // Non-existing Wizard Preset
|
|
||||||
},
|
|
||||||
/*recents*/
|
|
||||||
{
|
|
||||||
{"A.categ", "Windows 7", "200 x 300", /*is user*/true}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Then
|
|
||||||
ASSERT_THAT(data.categories(), ElementsAre("A"));
|
|
||||||
ASSERT_THAT(data.presets(), ElementsAre(ElementsAre(PresetIs("A.categ", "Desktop"))));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(QdsPresetModel, recentOfNonExistentUserPreset)
|
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
PresetData data;
|
PresetData data;
|
||||||
@@ -391,7 +356,7 @@ TEST(QdsPresetModel, recentOfNonExistentUserPreset)
|
|||||||
{/*user presets*/},
|
{/*user presets*/},
|
||||||
/*recents*/
|
/*recents*/
|
||||||
{
|
{
|
||||||
{"A.categ", "Windows 7", "200 x 300", /*is user*/true}
|
aRecentPreset("A.categ", "Windows 7", "200 x 300")
|
||||||
});
|
});
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
@@ -415,9 +380,9 @@ TEST(QdsPresetModel, recentsShouldNotBeSorted)
|
|||||||
{/*user presets*/},
|
{/*user presets*/},
|
||||||
/*recents*/
|
/*recents*/
|
||||||
{
|
{
|
||||||
{"Z.categ", "Z.desktop", "200 x 300"},
|
aRecentPreset("Z.categ", "Z.desktop", "200 x 300"),
|
||||||
{"B.categ", "Mobile", "200 x 300"},
|
aRecentPreset("B.categ", "Mobile", "200 x 300"),
|
||||||
{"A.categ", "Desktop", "200 x 300"},
|
aRecentPreset("A.categ", "Desktop", "200 x 300"),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
@@ -442,9 +407,9 @@ TEST(QdsPresetModel, recentsOfSameWizardProjectButDifferentSizesAreRecognizedAsD
|
|||||||
{/*user presets*/},
|
{/*user presets*/},
|
||||||
/*recents*/
|
/*recents*/
|
||||||
{
|
{
|
||||||
{"B.categ", "Mobile", "400 x 400"},
|
aRecentPreset("B.categ", "Mobile", "400 x 400"),
|
||||||
{"B.categ", "Mobile", "200 x 300"},
|
aRecentPreset("B.categ", "Mobile", "200 x 300"),
|
||||||
{"A.categ", "Desktop", "640 x 480"},
|
aRecentPreset("A.categ", "Desktop", "640 x 480"),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
@@ -454,6 +419,35 @@ TEST(QdsPresetModel, recentsOfSameWizardProjectButDifferentSizesAreRecognizedAsD
|
|||||||
PresetIs("A.categ", "Desktop", "640 x 480")));
|
PresetIs("A.categ", "Desktop", "640 x 480")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(QdsPresetModel, allowRecentsWithTheSameName)
|
||||||
|
{
|
||||||
|
// Given
|
||||||
|
PresetData data;
|
||||||
|
|
||||||
|
// When
|
||||||
|
data.setData(
|
||||||
|
/*wizard presets*/
|
||||||
|
{
|
||||||
|
aCategory("A.categ", "A", {"Desktop"}),
|
||||||
|
},
|
||||||
|
{/*user presets*/},
|
||||||
|
/*recents*/
|
||||||
|
{
|
||||||
|
/* NOTE: it is assumed recents with the same name and size have other fields that
|
||||||
|
* distinguishes them from one another. It is the responsibility of the caller, who
|
||||||
|
* calls data.setData() to make sure that the recents do not contain duplicates. */
|
||||||
|
aRecentPreset("A.categ", "Desktop", "200 x 300"),
|
||||||
|
aRecentPreset("A.categ", "Desktop", "200 x 300"),
|
||||||
|
aRecentPreset("A.categ", "Desktop", "200 x 300"),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Then
|
||||||
|
ASSERT_THAT(data.presets()[0],
|
||||||
|
ElementsAre(PresetIs("A.categ", "Desktop"),
|
||||||
|
PresetIs("A.categ", "Desktop"),
|
||||||
|
PresetIs("A.categ", "Desktop")));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(QdsPresetModel, outdatedRecentsAreNotShown)
|
TEST(QdsPresetModel, outdatedRecentsAreNotShown)
|
||||||
{
|
{
|
||||||
// Given
|
// Given
|
||||||
@@ -469,8 +463,8 @@ TEST(QdsPresetModel, outdatedRecentsAreNotShown)
|
|||||||
{/*user presets*/},
|
{/*user presets*/},
|
||||||
/*recents*/
|
/*recents*/
|
||||||
{
|
{
|
||||||
{"B.categ", "NoLongerExists", "400 x 400"},
|
aRecentPreset("B.categ", "NoLongerExists", "400 x 400"),
|
||||||
{"A.categ", "Desktop", "640 x 480"},
|
aRecentPreset("A.categ", "Desktop", "640 x 480"),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
|
@@ -1,303 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2022 The Qt Company Ltd.
|
|
||||||
** Contact: https://www.qt.io/licensing/
|
|
||||||
**
|
|
||||||
** This file is part of Qt Creator.
|
|
||||||
**
|
|
||||||
** Commercial License Usage
|
|
||||||
** Licensees holding valid commercial Qt licenses may use this file in
|
|
||||||
** accordance with the commercial license agreement provided with the
|
|
||||||
** Software or, alternatively, in accordance with the terms contained in
|
|
||||||
** a written agreement between you and The Qt Company. For licensing terms
|
|
||||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
||||||
** information use the contact form at https://www.qt.io/contact-us.
|
|
||||||
**
|
|
||||||
** GNU General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU
|
|
||||||
** General Public License version 3 as published by the Free Software
|
|
||||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
||||||
** included in the packaging of this file. Please review the following
|
|
||||||
** information to ensure the GNU General Public License requirements will
|
|
||||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#include "test-utilities.h"
|
|
||||||
|
|
||||||
#include <QDir>
|
|
||||||
#include <QRandomGenerator>
|
|
||||||
#include <QTime>
|
|
||||||
|
|
||||||
#include "recentpresets.h"
|
|
||||||
#include "utils/filepath.h"
|
|
||||||
#include "utils/temporarydirectory.h"
|
|
||||||
|
|
||||||
using namespace StudioWelcome;
|
|
||||||
|
|
||||||
constexpr char GROUP_NAME[] = "RecentPresets";
|
|
||||||
constexpr char ITEMS[] = "Wizards";
|
|
||||||
|
|
||||||
namespace StudioWelcome {
|
|
||||||
void PrintTo(const RecentPresetData &recent, std::ostream *os)
|
|
||||||
{
|
|
||||||
*os << "{categId: " << recent.category << ", name: " << recent.presetName
|
|
||||||
<< ", size: " << recent.sizeName << ", isUser: " << recent.isUserPreset;
|
|
||||||
|
|
||||||
*os << "}";
|
|
||||||
}
|
|
||||||
} // namespace StudioWelcome
|
|
||||||
|
|
||||||
class QdsRecentPresets : public ::testing::Test
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
RecentPresetsStore aStoreWithRecents(const QStringList &items)
|
|
||||||
{
|
|
||||||
settings.beginGroup(GROUP_NAME);
|
|
||||||
settings.setValue(ITEMS, items);
|
|
||||||
settings.endGroup();
|
|
||||||
|
|
||||||
return RecentPresetsStore{&settings};
|
|
||||||
}
|
|
||||||
|
|
||||||
RecentPresetsStore aStoreWithOne(const QVariant &item)
|
|
||||||
{
|
|
||||||
settings.beginGroup(GROUP_NAME);
|
|
||||||
settings.setValue(ITEMS, item);
|
|
||||||
settings.endGroup();
|
|
||||||
|
|
||||||
return RecentPresetsStore{&settings};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Utils::TemporaryDirectory tempDir{"recentpresets-XXXXXX"};
|
|
||||||
QSettings settings{tempDir.filePath("test").toString(), QSettings::IniFormat};
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString settingsPath;
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************* TESTS *******************/
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, readFromEmptyStore)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store{&settings};
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents, IsEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, readEmptyRecentPresets)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store = aStoreWithOne("");
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents, IsEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, readOneRecentPresetAsList)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store = aStoreWithRecents({"category/preset:640 x 480"});
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents, ElementsAre(RecentPresetData("category", "preset", "640 x 480")));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, readOneRecentPresetAsString)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store = aStoreWithOne("category/preset:200 x 300");
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents, ElementsAre(RecentPresetData("category", "preset", "200 x 300")));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, readOneRecentUserPresetAsString)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store = aStoreWithOne("category/[U]preset:200 x 300");
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents, ElementsAre(RecentPresetData("category", "preset", "200 x 300", true)));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, readBadRecentPresetAsString)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store = aStoreWithOne("no_category_only_preset");
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents, IsEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, readBadRecentPresetAsInt)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store = aStoreWithOne(32);
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents, IsEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, readBadRecentPresetsInList)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store = aStoreWithRecents({
|
|
||||||
"bad1", // no category, no size
|
|
||||||
"categ/name:800 x 600", // good
|
|
||||||
"categ/bad2", //no size
|
|
||||||
"categ/bad3:", //no size
|
|
||||||
"categ 1/bad4:200 x 300", // category has space
|
|
||||||
"categ/bad5: 400 x 300", // size starts with space
|
|
||||||
"categ/bad6:400", // bad size
|
|
||||||
"categ/[U]user:300 x 200", // good
|
|
||||||
"categ/[u]user2:300 x 200", // small cap "U"
|
|
||||||
"categ/[x]user3:300 x 200", // must be letter "U"
|
|
||||||
"categ/[U] user4:300 x 200", // space
|
|
||||||
});
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents,
|
|
||||||
ElementsAre(RecentPresetData("categ", "name", "800 x 600", false),
|
|
||||||
RecentPresetData("categ", "user", "300 x 200", true)));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, readTwoRecentPresets)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store = aStoreWithRecents(
|
|
||||||
{"category_1/preset 1:640 x 480", "category_2/preset 2:320 x 200"});
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents,
|
|
||||||
ElementsAre(RecentPresetData("category_1", "preset 1", "640 x 480"),
|
|
||||||
RecentPresetData("category_2", "preset 2", "320 x 200")));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, readRecentsToDifferentKindsOfPresets)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store = aStoreWithRecents(
|
|
||||||
{"category_1/preset 1:640 x 480", "category_2/[U]preset 2:320 x 200"});
|
|
||||||
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents,
|
|
||||||
ElementsAre(RecentPresetData("category_1", "preset 1", "640 x 480", false),
|
|
||||||
RecentPresetData("category_2", "preset 2", "320 x 200", true)));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, addFirstRecentPreset)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store{&settings};
|
|
||||||
|
|
||||||
store.add("A.Category", "Normal Application", "400 x 600");
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents, ElementsAre(RecentPresetData("A.Category", "Normal Application", "400 x 600")));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, addFirstRecentUserPreset)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store{&settings};
|
|
||||||
|
|
||||||
store.add("A.Category", "Normal Application", "400 x 600", /*user preset*/ true);
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents,
|
|
||||||
ElementsAre(RecentPresetData("A.Category", "Normal Application", "400 x 600", true)));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, addExistingFirstRecentPreset)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store = aStoreWithRecents({"category/preset:200 x 300"});
|
|
||||||
ASSERT_THAT(store.fetchAll(), ElementsAre(RecentPresetData("category", "preset", "200 x 300")));
|
|
||||||
|
|
||||||
store.add("category", "preset", "200 x 300");
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents, ElementsAre(RecentPresetData("category", "preset", "200 x 300")));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, addRecentUserPresetWithSameNameAsExistingRecentNormalPreset)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store = aStoreWithRecents({"category/preset:200 x 300"});
|
|
||||||
ASSERT_THAT(store.fetchAll(), ElementsAre(RecentPresetData("category", "preset", "200 x 300")));
|
|
||||||
|
|
||||||
store.add("category", "preset", "200 x 300", /*user preset*/ true);
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents,
|
|
||||||
ElementsAre(RecentPresetData("category", "preset", "200 x 300", true),
|
|
||||||
RecentPresetData("category", "preset", "200 x 300", false)));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, addSecondRecentPreset)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store = aStoreWithRecents({"A.Category/Preset 1:800 x 600"});
|
|
||||||
|
|
||||||
store.add("A.Category", "Preset 2", "640 x 480");
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents,
|
|
||||||
ElementsAre(RecentPresetData("A.Category", "Preset 2", "640 x 480"),
|
|
||||||
RecentPresetData("A.Category", "Preset 1", "800 x 600")));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, addSecondRecentPresetSameKindButDifferentSize)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store = aStoreWithRecents({"A.Category/Preset:800 x 600"});
|
|
||||||
|
|
||||||
store.add("A.Category", "Preset", "640 x 480");
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents,
|
|
||||||
ElementsAre(RecentPresetData("A.Category", "Preset", "640 x 480"),
|
|
||||||
RecentPresetData("A.Category", "Preset", "800 x 600")));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, fetchesRecentPresetsInTheReverseOrderTheyWereAdded)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store{&settings};
|
|
||||||
|
|
||||||
store.add("A.Category", "Preset 1", "640 x 480");
|
|
||||||
store.add("A.Category", "Preset 2", "640 x 480");
|
|
||||||
store.add("A.Category", "Preset 3", "800 x 600");
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents,
|
|
||||||
ElementsAre(RecentPresetData("A.Category", "Preset 3", "800 x 600"),
|
|
||||||
RecentPresetData("A.Category", "Preset 2", "640 x 480"),
|
|
||||||
RecentPresetData("A.Category", "Preset 1", "640 x 480")));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, addingAnExistingRecentPresetMakesItTheFirst)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store = aStoreWithRecents({"A.Category/Preset 1:200 x 300",
|
|
||||||
"A.Category/Preset 2:200 x 300",
|
|
||||||
"A.Category/Preset 3:640 x 480"});
|
|
||||||
|
|
||||||
store.add("A.Category", "Preset 3", "640 x 480");
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents,
|
|
||||||
ElementsAre(RecentPresetData("A.Category", "Preset 3", "640 x 480"),
|
|
||||||
RecentPresetData("A.Category", "Preset 1", "200 x 300"),
|
|
||||||
RecentPresetData("A.Category", "Preset 2", "200 x 300")));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(QdsRecentPresets, addingTooManyRecentPresetsRemovesTheOldestOne)
|
|
||||||
{
|
|
||||||
RecentPresetsStore store = aStoreWithRecents(
|
|
||||||
{"A.Category/Preset 2:200 x 300", "A.Category/Preset 1:200 x 300"});
|
|
||||||
store.setMaximum(2);
|
|
||||||
|
|
||||||
store.add("A.Category", "Preset 3", "200 x 300");
|
|
||||||
std::vector<RecentPresetData> recents = store.fetchAll();
|
|
||||||
|
|
||||||
ASSERT_THAT(recents,
|
|
||||||
ElementsAre(RecentPresetData("A.Category", "Preset 3", "200 x 300"),
|
|
||||||
RecentPresetData("A.Category", "Preset 2", "200 x 300")));
|
|
||||||
}
|
|
@@ -29,6 +29,10 @@
|
|||||||
#include <utils/filepath.h>
|
#include <utils/filepath.h>
|
||||||
#include <utils/temporarydirectory.h>
|
#include <utils/temporarydirectory.h>
|
||||||
|
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
namespace StudioWelcome {
|
namespace StudioWelcome {
|
||||||
|
|
||||||
void PrintTo(const UserPresetData &preset, std::ostream *os)
|
void PrintTo(const UserPresetData &preset, std::ostream *os)
|
||||||
@@ -64,69 +68,85 @@ using namespace StudioWelcome;
|
|||||||
|
|
||||||
constexpr char ARRAY_NAME[] = "UserPresets";
|
constexpr char ARRAY_NAME[] = "UserPresets";
|
||||||
|
|
||||||
|
class FakeStoreIo : public StoreIo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QByteArray read() const override
|
||||||
|
{
|
||||||
|
return data.toUtf8();
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(const QByteArray &bytes) override
|
||||||
|
{
|
||||||
|
data = bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString data;
|
||||||
|
};
|
||||||
|
|
||||||
class QdsUserPresets : public ::testing::Test
|
class QdsUserPresets : public ::testing::Test
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
void SetUp()
|
void SetUp()
|
||||||
{
|
{
|
||||||
settings = std::make_unique<QSettings>(tempDir.filePath("test").toString(),
|
storeIo = std::make_unique<FakeStoreIo>();
|
||||||
QSettings::IniFormat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UserPresetsStore anEmptyStore() { return UserPresetsStore{std::move(settings)}; }
|
UserPresetsStore anEmptyStore()
|
||||||
|
{
|
||||||
|
return UserPresetsStore{std::move(storeIo), StorePolicy::UniqueNames};
|
||||||
|
}
|
||||||
|
|
||||||
UserPresetsStore aStoreWithZeroItems()
|
UserPresetsStore aStoreWithZeroItems()
|
||||||
{
|
{
|
||||||
settings->beginWriteArray(ARRAY_NAME, 0);
|
storeIo->data = "[]";
|
||||||
settings->endArray();
|
|
||||||
|
|
||||||
return UserPresetsStore{std::move(settings)};
|
return UserPresetsStore{std::move(storeIo), StorePolicy::UniqueNames};
|
||||||
}
|
}
|
||||||
|
|
||||||
UserPresetsStore aStoreWithOne(const UserPresetData &preset)
|
UserPresetsStore aStoreWithOne(const UserPresetData &preset,
|
||||||
|
StorePolicy policy = StorePolicy::UniqueNames)
|
||||||
{
|
{
|
||||||
settings->beginWriteArray(ARRAY_NAME, 1);
|
QJsonArray array({QJsonObject{{"categoryId", preset.categoryId},
|
||||||
settings->setArrayIndex(0);
|
{"wizardName", preset.wizardName},
|
||||||
|
{"name", preset.name},
|
||||||
|
{"screenSize", preset.screenSize},
|
||||||
|
{"useQtVirtualKeyboard", preset.useQtVirtualKeyboard},
|
||||||
|
{"qtVersion", preset.qtVersion},
|
||||||
|
{"styleName", preset.styleName}}});
|
||||||
|
QJsonDocument doc{array};
|
||||||
|
storeIo->data = doc.toJson();
|
||||||
|
|
||||||
settings->setValue("categoryId", preset.categoryId);
|
return UserPresetsStore{std::move(storeIo), policy};
|
||||||
settings->setValue("wizardName", preset.wizardName);
|
|
||||||
settings->setValue("name", preset.name);
|
|
||||||
settings->setValue("screenSize", preset.screenSize);
|
|
||||||
settings->setValue("useQtVirtualKeyboard", preset.useQtVirtualKeyboard);
|
|
||||||
settings->setValue("qtVersion", preset.qtVersion);
|
|
||||||
settings->setValue("styleName", preset.styleName);
|
|
||||||
|
|
||||||
settings->endArray();
|
|
||||||
|
|
||||||
return UserPresetsStore{std::move(settings)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UserPresetsStore aStoreWithPresets(const std::vector<UserPresetData> &presets)
|
UserPresetsStore aStoreWithPresets(const std::vector<UserPresetData> &presetItems)
|
||||||
{
|
{
|
||||||
settings->beginWriteArray(ARRAY_NAME, presets.size());
|
QJsonArray array;
|
||||||
|
|
||||||
for (size_t i = 0; i < presets.size(); ++i) {
|
for (const auto &preset : presetItems) {
|
||||||
settings->setArrayIndex(i);
|
QJsonObject obj({{"categoryId", preset.categoryId},
|
||||||
const auto &preset = presets[i];
|
{"wizardName", preset.wizardName},
|
||||||
|
{"name", preset.name},
|
||||||
|
{"screenSize", preset.screenSize},
|
||||||
|
{"useQtVirtualKeyboard", preset.useQtVirtualKeyboard},
|
||||||
|
{"qtVersion", preset.qtVersion},
|
||||||
|
{"styleName", preset.styleName}});
|
||||||
|
|
||||||
settings->setValue("categoryId", preset.categoryId);
|
array.append(QJsonValue{obj});
|
||||||
settings->setValue("wizardName", preset.wizardName);
|
|
||||||
settings->setValue("name", preset.name);
|
|
||||||
settings->setValue("screenSize", preset.screenSize);
|
|
||||||
settings->setValue("useQtVirtualKeyboard", preset.useQtVirtualKeyboard);
|
|
||||||
settings->setValue("qtVersion", preset.qtVersion);
|
|
||||||
settings->setValue("styleName", preset.styleName);
|
|
||||||
}
|
}
|
||||||
settings->endArray();
|
|
||||||
|
|
||||||
return UserPresetsStore{std::move(settings)};
|
QJsonDocument doc{array};
|
||||||
|
storeIo->data = doc.toJson();
|
||||||
|
|
||||||
|
return UserPresetsStore{std::move(storeIo), StorePolicy::UniqueNames};
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::TemporaryDirectory tempDir{"userpresets-XXXXXX"};
|
Utils::TemporaryDirectory tempDir{"userpresets-XXXXXX"};
|
||||||
std::unique_ptr<QSettings> settings;
|
std::unique_ptr<FakeStoreIo> storeIo;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString settingsPath;
|
QString storeIoPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************* TESTS *******************/
|
/******************* TESTS *******************/
|
||||||
@@ -234,10 +254,10 @@ TEST_F(QdsUserPresets, saveIncompletePreset)
|
|||||||
ASSERT_THAT(presets, ElementsAre(preset));
|
ASSERT_THAT(presets, ElementsAre(preset));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(QdsUserPresets, cannotSavePresetWithSameName)
|
TEST_F(QdsUserPresets, cannotSavePresetWithSameNameForUniqueNamesPolicy)
|
||||||
{
|
{
|
||||||
UserPresetData existing{"B.categ", "3D App", "Same Name", "400 x 20", true, "Qt 5", "Material Dark"};
|
UserPresetData existing{"B.categ", "3D App", "Same Name", "400 x 20", true, "Qt 5", "Material Dark"};
|
||||||
auto store = aStoreWithOne(existing);
|
auto store = aStoreWithOne(existing, StorePolicy::UniqueNames);
|
||||||
|
|
||||||
UserPresetData newPreset{"C.categ", "Empty", "Same Name", "100 x 30", false, "Qt 6", "Fusion"};
|
UserPresetData newPreset{"C.categ", "Empty", "Same Name", "100 x 30", false, "Qt 6", "Fusion"};
|
||||||
bool saved = store.save(newPreset);
|
bool saved = store.save(newPreset);
|
||||||
@@ -246,6 +266,30 @@ TEST_F(QdsUserPresets, cannotSavePresetWithSameName)
|
|||||||
ASSERT_THAT(store.fetchAll(), ElementsAreArray({existing}));
|
ASSERT_THAT(store.fetchAll(), ElementsAreArray({existing}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(QdsUserPresets, canSavePresetWithSameNameForUniqueValuesPolicy)
|
||||||
|
{
|
||||||
|
UserPresetData existing{"B.categ", "3D App", "Same Name", "400 x 20", true, "Qt 5", "Material Dark"};
|
||||||
|
auto store = aStoreWithOne(existing, StorePolicy::UniqueValues);
|
||||||
|
|
||||||
|
// NOTE: only Style is different
|
||||||
|
UserPresetData newPreset{"B.categ", "3D App", "Same Name", "400 x 20", true, "Qt 5", "Fusion"};
|
||||||
|
bool saved = store.save(newPreset);
|
||||||
|
|
||||||
|
ASSERT_TRUE(saved);
|
||||||
|
ASSERT_THAT(store.fetchAll(), ElementsAreArray({existing, newPreset}));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(QdsUserPresets, cannotSaveExactCopyForUniqueValuesPolicy)
|
||||||
|
{
|
||||||
|
UserPresetData existing{"B.categ", "3D App", "Same Name", "400 x 20", true, "Qt 5", "Material Dark"};
|
||||||
|
auto store = aStoreWithOne(existing, StorePolicy::UniqueNames);
|
||||||
|
|
||||||
|
bool saved = store.save(existing);
|
||||||
|
|
||||||
|
ASSERT_FALSE(saved);
|
||||||
|
ASSERT_THAT(store.fetchAll(), ElementsAreArray({existing}));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(QdsUserPresets, saveNewPreset)
|
TEST_F(QdsUserPresets, saveNewPreset)
|
||||||
{
|
{
|
||||||
UserPresetData existing{"A.categ", "3D App", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"};
|
UserPresetData existing{"A.categ", "3D App", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"};
|
||||||
@@ -258,6 +302,54 @@ TEST_F(QdsUserPresets, saveNewPreset)
|
|||||||
ASSERT_THAT(presets, ElementsAre(existing, newPreset));
|
ASSERT_THAT(presets, ElementsAre(existing, newPreset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(QdsUserPresets, canLimitPresetsToAMaximum)
|
||||||
|
{
|
||||||
|
std::vector<UserPresetData> existing{
|
||||||
|
{"A.categ", "AppA", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"},
|
||||||
|
{"B.categ", "AppB", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"},
|
||||||
|
{"C.categ", "AppC", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"},
|
||||||
|
};
|
||||||
|
auto store = aStoreWithPresets(existing);
|
||||||
|
store.setMaximum(3);
|
||||||
|
|
||||||
|
UserPresetData newPreset{"D.categ", "AppD", "Huawei", "100 x 30", true, "Qt 6", "Fusion"};
|
||||||
|
store.save(newPreset);
|
||||||
|
|
||||||
|
auto presets = store.fetchAll();
|
||||||
|
ASSERT_THAT(presets, ElementsAre(existing[1], existing[2], newPreset));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(QdsUserPresets, canLimitPresetsToAMaximumForReverseOrder)
|
||||||
|
{
|
||||||
|
std::vector<UserPresetData> existing{
|
||||||
|
{"A.categ", "AppA", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"},
|
||||||
|
{"B.categ", "AppB", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"},
|
||||||
|
{"C.categ", "AppC", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"},
|
||||||
|
};
|
||||||
|
auto store = aStoreWithPresets(existing);
|
||||||
|
store.setMaximum(3);
|
||||||
|
store.setReverseOrder();
|
||||||
|
|
||||||
|
UserPresetData newPreset{"D.categ", "AppD", "Huawei", "100 x 30", true, "Qt 6", "Fusion"};
|
||||||
|
store.save(newPreset);
|
||||||
|
|
||||||
|
auto presets = store.fetchAll();
|
||||||
|
ASSERT_THAT(presets, ElementsAre(newPreset, existing[0], existing[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(QdsUserPresets, canSavePresetsInReverseOrder)
|
||||||
|
{
|
||||||
|
UserPresetData existing{"A.categ", "3D App", "iPhone7", "400 x 20", true, "Qt 5", "Material Dark"};
|
||||||
|
auto store = aStoreWithOne(existing, StorePolicy::UniqueNames);
|
||||||
|
store.setReverseOrder();
|
||||||
|
|
||||||
|
UserPresetData newPreset{"A.categ", "Empty", "Huawei", "100 x 30", true, "Qt 6", "Fusion"};
|
||||||
|
store.save(newPreset);
|
||||||
|
|
||||||
|
auto presets = store.fetchAll();
|
||||||
|
ASSERT_THAT(presets, ElementsAre(newPreset, existing));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(QdsUserPresets, removeUserPresetFromEmptyStore)
|
TEST_F(QdsUserPresets, removeUserPresetFromEmptyStore)
|
||||||
{
|
{
|
||||||
UserPresetData preset{"C.categ", "2D App", "Android", "", false, "", ""};
|
UserPresetData preset{"C.categ", "2D App", "Android", "", false, "", ""};
|
||||||
|
@@ -46,11 +46,11 @@ class Targets:
|
|||||||
"Desktop 5.14.1 default"]))
|
"Desktop 5.14.1 default"]))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def availableTargetClasses():
|
def availableTargetClasses(ignoreValidity=False):
|
||||||
availableTargets = set(Targets.ALL_TARGETS)
|
availableTargets = set(Targets.ALL_TARGETS)
|
||||||
if not qt4Available:
|
if not qt4Available and not ignoreValidity:
|
||||||
availableTargets.remove(Targets.DESKTOP_4_8_7_DEFAULT)
|
availableTargets.remove(Targets.DESKTOP_4_8_7_DEFAULT)
|
||||||
if not qt4Available or platform.system() in ('Windows', 'Microsoft'):
|
if not (qt4Available or ignoreValidity) or platform.system() in ('Windows', 'Microsoft'):
|
||||||
availableTargets.remove(Targets.EMBEDDED_LINUX)
|
availableTargets.remove(Targets.EMBEDDED_LINUX)
|
||||||
elif platform.system() == 'Darwin':
|
elif platform.system() == 'Darwin':
|
||||||
availableTargets.remove(Targets.DESKTOP_5_4_1_GCC)
|
availableTargets.remove(Targets.DESKTOP_5_4_1_GCC)
|
||||||
|
@@ -207,7 +207,7 @@ def __verifyFileCreation__(path, expectedFiles):
|
|||||||
def __modifyAvailableTargets__(available, requiredQt, asStrings=False):
|
def __modifyAvailableTargets__(available, requiredQt, asStrings=False):
|
||||||
versionFinder = re.compile("^Desktop (\\d{1}\.\\d{1,2}\.\\d{1,2}).*$")
|
versionFinder = re.compile("^Desktop (\\d{1}\.\\d{1,2}\.\\d{1,2}).*$")
|
||||||
tmp = list(available) # we need a deep copy
|
tmp = list(available) # we need a deep copy
|
||||||
if Qt5Path.toVersionTuple(requiredQt) > (4,8,7):
|
if Qt5Path.toVersionTuple(requiredQt) > (4,8,7) and qt4Available:
|
||||||
toBeRemoved = Targets.EMBEDDED_LINUX
|
toBeRemoved = Targets.EMBEDDED_LINUX
|
||||||
if asStrings:
|
if asStrings:
|
||||||
toBeRemoved = Targets.getStringForTarget(toBeRemoved)
|
toBeRemoved = Targets.getStringForTarget(toBeRemoved)
|
||||||
@@ -221,6 +221,8 @@ def __modifyAvailableTargets__(available, requiredQt, asStrings=False):
|
|||||||
if found:
|
if found:
|
||||||
if Qt5Path.toVersionTuple(found.group(1)) < Qt5Path.toVersionTuple(requiredQt):
|
if Qt5Path.toVersionTuple(found.group(1)) < Qt5Path.toVersionTuple(requiredQt):
|
||||||
available.discard(currentItem)
|
available.discard(currentItem)
|
||||||
|
elif currentItem.endswith(" (invalid)"):
|
||||||
|
available.discard(currentItem)
|
||||||
|
|
||||||
def __getProjectFileName__(projectName, buildSystem):
|
def __getProjectFileName__(projectName, buildSystem):
|
||||||
if buildSystem is None or buildSystem == "CMake":
|
if buildSystem is None or buildSystem == "CMake":
|
||||||
@@ -523,7 +525,9 @@ def __closeSubprocessByPushingStop__(isQtQuickUI):
|
|||||||
# configured Qt versions and Toolchains and cannot be looked up the same way
|
# configured Qt versions and Toolchains and cannot be looked up the same way
|
||||||
# if you set getAsStrings to True this function returns a list of strings instead
|
# if you set getAsStrings to True this function returns a list of strings instead
|
||||||
# of the constants defined in Targets
|
# of the constants defined in Targets
|
||||||
def __getSupportedPlatforms__(text, templateName, getAsStrings=False):
|
# ignoreValidity if true kits will be considered available even if they are configured
|
||||||
|
# to use an invalid Qt
|
||||||
|
def __getSupportedPlatforms__(text, templateName, getAsStrings=False, ignoreValidity=False):
|
||||||
reqPattern = re.compile("requires qt (?P<version>\d+\.\d+(\.\d+)?)", re.IGNORECASE)
|
reqPattern = re.compile("requires qt (?P<version>\d+\.\d+(\.\d+)?)", re.IGNORECASE)
|
||||||
res = reqPattern.search(text)
|
res = reqPattern.search(text)
|
||||||
if res:
|
if res:
|
||||||
@@ -536,11 +540,12 @@ def __getSupportedPlatforms__(text, templateName, getAsStrings=False):
|
|||||||
supports = text[text.find('Supported Platforms'):].split(":")[1].strip().split("\n")
|
supports = text[text.find('Supported Platforms'):].split(":")[1].strip().split("\n")
|
||||||
result = set()
|
result = set()
|
||||||
if 'Desktop' in supports:
|
if 'Desktop' in supports:
|
||||||
if (version == None or version < "5.0") and not templateName.startswith("Qt Quick 2"):
|
if (version == None or version < "5.0") and not templateName.startswith("Qt Quick"):
|
||||||
if qt4Available:
|
neverIgnoreValidity = templateName in ("Qt Custom Designer Widget", "Code Snippet", "Subdirs Project")
|
||||||
|
if qt4Available or ignoreValidity and not neverIgnoreValidity:
|
||||||
result.add(Targets.DESKTOP_4_8_7_DEFAULT)
|
result.add(Targets.DESKTOP_4_8_7_DEFAULT)
|
||||||
if platform.system() in ("Linux", "Darwin"):
|
if platform.system() in ("Linux", "Darwin"):
|
||||||
result.add(Targets.EMBEDDED_LINUX)
|
result.add(Targets.EMBEDDED_LINUX)
|
||||||
result = result.union(set([Targets.DESKTOP_5_10_1_DEFAULT, Targets.DESKTOP_5_14_1_DEFAULT]))
|
result = result.union(set([Targets.DESKTOP_5_10_1_DEFAULT, Targets.DESKTOP_5_14_1_DEFAULT]))
|
||||||
if platform.system() != 'Darwin':
|
if platform.system() != 'Darwin':
|
||||||
result.add(Targets.DESKTOP_5_4_1_GCC)
|
result.add(Targets.DESKTOP_5_4_1_GCC)
|
||||||
|
@@ -366,6 +366,9 @@ def getConfiguredKits():
|
|||||||
def __setQtVersionForKit__(kit, kitName, kitsQtVersionName):
|
def __setQtVersionForKit__(kit, kitName, kitsQtVersionName):
|
||||||
mouseClick(waitForObjectItem(":BuildAndRun_QTreeView", kit))
|
mouseClick(waitForObjectItem(":BuildAndRun_QTreeView", kit))
|
||||||
qtVersionStr = str(waitForObjectExists(":Kits_QtVersion_QComboBox").currentText)
|
qtVersionStr = str(waitForObjectExists(":Kits_QtVersion_QComboBox").currentText)
|
||||||
|
invalid = qtVersionStr.endswith(" (invalid)")
|
||||||
|
if invalid:
|
||||||
|
qtVersionStr = qtVersionStr[:-10]
|
||||||
kitsQtVersionName[kitName] = qtVersionStr
|
kitsQtVersionName[kitName] = qtVersionStr
|
||||||
# end of internal function for iterate kits
|
# end of internal function for iterate kits
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
############################################################################
|
############################################################################
|
||||||
#
|
#
|
||||||
# Copyright (C) 2016 The Qt Company Ltd.
|
# Copyright (C) 2022 The Qt Company Ltd.
|
||||||
# Contact: https://www.qt.io/licensing/
|
# Contact: https://www.qt.io/licensing/
|
||||||
#
|
#
|
||||||
# This file is part of Qt Creator.
|
# This file is part of Qt Creator.
|
||||||
@@ -93,8 +93,8 @@ def main():
|
|||||||
example = findExampleOrTutorial(listView, ".*", True)
|
example = findExampleOrTutorial(listView, ".*", True)
|
||||||
test.verify(example is None, "Verifying: No example is shown.")
|
test.verify(example is None, "Verifying: No example is shown.")
|
||||||
|
|
||||||
proFiles = map(lambda p: os.path.join(p, "opengl", "2dpainting", "2dpainting.pro"),
|
proFiles = [os.path.join(p, "opengl", "2dpainting", "2dpainting.pro")
|
||||||
Qt5Path.getPaths(Qt5Path.EXAMPLES))
|
for p in Qt5Path.getPaths(Qt5Path.EXAMPLES)]
|
||||||
cleanUpUserFiles(proFiles)
|
cleanUpUserFiles(proFiles)
|
||||||
for p in proFiles:
|
for p in proFiles:
|
||||||
removePackagingDirectory(os.path.dirname(p))
|
removePackagingDirectory(os.path.dirname(p))
|
||||||
@@ -115,8 +115,8 @@ def main():
|
|||||||
|
|
||||||
# go to "Welcome" page and choose another example
|
# go to "Welcome" page and choose another example
|
||||||
switchViewTo(ViewConstants.WELCOME)
|
switchViewTo(ViewConstants.WELCOME)
|
||||||
proFiles = map(lambda p: os.path.join(p, "widgets", "itemviews", "addressbook", "addressbook.pro"),
|
proFiles = [os.path.join(p, "widgets", "itemviews", "addressbook", "addressbook.pro")
|
||||||
Qt5Path.getPaths(Qt5Path.EXAMPLES))
|
for p in Qt5Path.getPaths(Qt5Path.EXAMPLES)]
|
||||||
cleanUpUserFiles(proFiles)
|
cleanUpUserFiles(proFiles)
|
||||||
for p in proFiles:
|
for p in proFiles:
|
||||||
removePackagingDirectory(os.path.dirname(p))
|
removePackagingDirectory(os.path.dirname(p))
|
||||||
|
@@ -156,7 +156,7 @@ def __createProject__(category, template):
|
|||||||
origTxt = safeGetTextBrowserText()
|
origTxt = safeGetTextBrowserText()
|
||||||
mouseClick(waitForObjectItem(templatesView, template))
|
mouseClick(waitForObjectItem(templatesView, template))
|
||||||
waitFor("origTxt != safeGetTextBrowserText() != ''", 2000)
|
waitFor("origTxt != safeGetTextBrowserText() != ''", 2000)
|
||||||
displayedPlatforms = __getSupportedPlatforms__(safeGetTextBrowserText(), template, True)[0]
|
displayedPlatforms = __getSupportedPlatforms__(safeGetTextBrowserText(), template, True, True)[0]
|
||||||
safeClickButton("Choose...")
|
safeClickButton("Choose...")
|
||||||
# don't check because project could exist
|
# don't check because project could exist
|
||||||
__createProjectSetNameAndPath__(os.path.expanduser("~"), 'untitled', False)
|
__createProjectSetNameAndPath__(os.path.expanduser("~"), 'untitled', False)
|
||||||
|
@@ -54,9 +54,9 @@ def main():
|
|||||||
startQC()
|
startQC()
|
||||||
if not startedWithoutPluginError():
|
if not startedWithoutPluginError():
|
||||||
return
|
return
|
||||||
createProject_Qt_Console(tempDir(), "SquishProject")
|
createProject_Qt_Console(tempDir(), "SquishProject", buildSystem = "qmake")
|
||||||
switchViewTo(ViewConstants.PROJECTS)
|
switchViewTo(ViewConstants.PROJECTS)
|
||||||
verifyProjectsMode(Targets.getTargetsAsStrings(Targets.availableTargetClasses()))
|
verifyProjectsMode(Targets.getTargetsAsStrings(Targets.availableTargetClasses(True)))
|
||||||
iterateKits(True, False, __removeKit__)
|
iterateKits(True, False, __removeKit__)
|
||||||
clickButton(waitForObject(":Options.OK_QPushButton"))
|
clickButton(waitForObject(":Options.OK_QPushButton"))
|
||||||
verifyProjectsMode([])
|
verifyProjectsMode([])
|
||||||
|
@@ -165,7 +165,7 @@ def main():
|
|||||||
startQC()
|
startQC()
|
||||||
if not startedWithoutPluginError():
|
if not startedWithoutPluginError():
|
||||||
return
|
return
|
||||||
createProject_Qt_GUI(srcPath, projectName, addToVersionControl = "Git")
|
createProject_Qt_GUI(srcPath, projectName, addToVersionControl = "Git", buildSystem = "qmake")
|
||||||
openVcsLog()
|
openVcsLog()
|
||||||
vcsLog = waitForObject("{type='Core::OutputWindow' unnamed='1' visible='1' "
|
vcsLog = waitForObject("{type='Core::OutputWindow' unnamed='1' visible='1' "
|
||||||
"window=':Qt Creator_Core::Internal::MainWindow'}").plainText
|
"window=':Qt Creator_Core::Internal::MainWindow'}").plainText
|
||||||
|
Reference in New Issue
Block a user