forked from qt-creator/qt-creator
QmlDesigner: Add operators to expression builder
* Show operator fills when cursor is placed at position where operator is required * Convert operators from real syntax to text version Task-number: QDS-10630 Task-number: QDS-10638 Change-Id: Iffceb24024b7cde9a93c2acd0033fedd54e2ee32 Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
committed by
Henning Gründl
parent
c5d5a564c8
commit
ed6f870a81
@@ -181,10 +181,12 @@ Column {
|
|||||||
color: StudioTheme.Values.themeToolbarBackground
|
color: StudioTheme.Values.themeToolbarBackground
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
width: parent.width - 8 // twice the editor button margins
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: backend.source
|
text: backend.source
|
||||||
color: StudioTheme.Values.themeTextColor
|
color: StudioTheme.Values.themeTextColor
|
||||||
font.pixelSize: StudioTheme.Values.myFontSize
|
font.pixelSize: StudioTheme.Values.myFontSize
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
}
|
}
|
||||||
|
|
||||||
HelperWidgets.AbstractButton {
|
HelperWidgets.AbstractButton {
|
||||||
|
@@ -87,10 +87,68 @@ Rectangle {
|
|||||||
newTextInput.index = index
|
newTextInput.index = index
|
||||||
newTextInput.visible = true
|
newTextInput.visible = true
|
||||||
newTextInput.forceActiveFocus()
|
newTextInput.forceActiveFocus()
|
||||||
|
|
||||||
|
if (!root.shadowPillVisible)
|
||||||
|
popup.showOperators = root.conditionListModel.operatorAllowed(index)
|
||||||
|
|
||||||
// Open suggestion popup
|
// Open suggestion popup
|
||||||
popup.open()
|
popup.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: __operatorModel
|
||||||
|
function convertValueToName(value) {
|
||||||
|
for (var i = 0; i < __operatorModel.count; ++i) {
|
||||||
|
let element = __operatorModel.get(i)
|
||||||
|
if (element.value === value )
|
||||||
|
return element.name
|
||||||
|
}
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
ListElement {
|
||||||
|
name: "AND"
|
||||||
|
value: "&&"
|
||||||
|
tooltip: QT_TR_NOOP("This is AND (&&)")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "OR"
|
||||||
|
value: "||"
|
||||||
|
tooltip: QT_TR_NOOP("This is OR (||)")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "EQUAL"
|
||||||
|
value: "==="
|
||||||
|
tooltip: QT_TR_NOOP("This is EQUAL (===)")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "NOT EQUAL"
|
||||||
|
value: "!=="
|
||||||
|
tooltip: QT_TR_NOOP("This is NOT EQUAL (!==)")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "GREATER"
|
||||||
|
value: ">"
|
||||||
|
tooltip: QT_TR_NOOP("This is GREATER (>)")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "LESS"
|
||||||
|
value: "<"
|
||||||
|
tooltip: QT_TR_NOOP("This is LESS (<)")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "GREATER OR EQUAL"
|
||||||
|
value: ">="
|
||||||
|
tooltip: QT_TR_NOOP("This is GREATER OR EQUAL (>=)")
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "LESS OR EQUAL"
|
||||||
|
value: "<="
|
||||||
|
tooltip: QT_TR_NOOP("This is LESS OR EQUAL (<=)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StudioControls.ToolTip {
|
StudioControls.ToolTip {
|
||||||
id: toolTip
|
id: toolTip
|
||||||
visible: mouseArea.containsMouse && toolTip.text !== ""
|
visible: mouseArea.containsMouse && toolTip.text !== ""
|
||||||
@@ -197,6 +255,8 @@ Rectangle {
|
|||||||
Pill {
|
Pill {
|
||||||
id: pill
|
id: pill
|
||||||
|
|
||||||
|
operatorModel: __operatorModel
|
||||||
|
|
||||||
onRemove: function() {
|
onRemove: function() {
|
||||||
// If pill has focus due to selection or keyboard navigation
|
// If pill has focus due to selection or keyboard navigation
|
||||||
if (pill.focus)
|
if (pill.focus)
|
||||||
@@ -289,6 +349,8 @@ Rectangle {
|
|||||||
y: root.height
|
y: root.height
|
||||||
width: root.width
|
width: root.width
|
||||||
|
|
||||||
|
operatorModel: __operatorModel
|
||||||
|
|
||||||
//onOpened: console.log("POPUP opened")
|
//onOpened: console.log("POPUP opened")
|
||||||
//onClosed: console.log("POPUP closed")
|
//onClosed: console.log("POPUP closed")
|
||||||
|
|
||||||
|
@@ -31,6 +31,7 @@ FocusScope {
|
|||||||
signal submit(int cursorPosition)
|
signal submit(int cursorPosition)
|
||||||
|
|
||||||
readonly property int margin: StudioTheme.Values.flowPillMargin
|
readonly property int margin: StudioTheme.Values.flowPillMargin
|
||||||
|
property var operatorModel
|
||||||
|
|
||||||
width: {
|
width: {
|
||||||
if (root.isEditable()) {
|
if (root.isEditable()) {
|
||||||
@@ -88,7 +89,7 @@ FocusScope {
|
|||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
radius: 4
|
radius: StudioTheme.Values.flowPillRadius
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: row
|
id: row
|
||||||
@@ -102,7 +103,8 @@ FocusScope {
|
|||||||
font.pixelSize: StudioTheme.Values.baseFontSize
|
font.pixelSize: StudioTheme.Values.baseFontSize
|
||||||
color: root.isShadow() ? StudioTheme.Values.themeTextSelectedTextColor
|
color: root.isShadow() ? StudioTheme.Values.themeTextSelectedTextColor
|
||||||
: StudioTheme.Values.themeTextColor
|
: StudioTheme.Values.themeTextColor
|
||||||
text: root.value
|
text: root.isOperator() ? root.operatorModel.convertValueToName(root.value)
|
||||||
|
: root.value
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls as Controls
|
import QtQuick.Controls as Controls
|
||||||
|
import HelperWidgets as HelperWidgets
|
||||||
import StudioTheme as StudioTheme
|
import StudioTheme as StudioTheme
|
||||||
import StudioControls as StudioControls
|
import StudioControls as StudioControls
|
||||||
import ConnectionsEditorEditorBackend
|
import ConnectionsEditorEditorBackend
|
||||||
@@ -20,6 +21,8 @@ Controls.Popup {
|
|||||||
signal exited(var value)
|
signal exited(var value)
|
||||||
|
|
||||||
property alias searchActive: search.activeFocus
|
property alias searchActive: search.activeFocus
|
||||||
|
property bool showOperators: false
|
||||||
|
property alias operatorModel: repeater.model
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
search.clear()
|
search.clear()
|
||||||
@@ -43,6 +46,7 @@ Controls.Popup {
|
|||||||
StudioControls.SearchBox {
|
StudioControls.SearchBox {
|
||||||
id: search
|
id: search
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
visible: !root.showOperators
|
||||||
|
|
||||||
onSearchChanged: function(value) {
|
onSearchChanged: function(value) {
|
||||||
root.treeModel.setFilter(value)
|
root.treeModel.setFilter(value)
|
||||||
@@ -51,12 +55,10 @@ Controls.Popup {
|
|||||||
|
|
||||||
Controls.StackView {
|
Controls.StackView {
|
||||||
id: stack
|
id: stack
|
||||||
|
visible: !root.showOperators
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: currentItem?.implicitHeight
|
height: currentItem?.implicitHeight
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
initialItem: mainView
|
initialItem: mainView
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,7 +212,7 @@ Controls.Popup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
visible: false
|
visible: root.showOperators
|
||||||
width: stack.width
|
width: stack.width
|
||||||
height: flow.childrenRect.height + 2 * StudioTheme.Values.flowMargin
|
height: flow.childrenRect.height + 2 * StudioTheme.Values.flowMargin
|
||||||
|
|
||||||
@@ -224,30 +226,38 @@ Controls.Popup {
|
|||||||
Repeater {
|
Repeater {
|
||||||
id: repeater
|
id: repeater
|
||||||
|
|
||||||
// TODO actual value + tooltip
|
|
||||||
model: ["AND", "OR", "equal", "not equal", "greater", "less", "greater then", "less then"]
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: textItem.contentWidth + 14
|
id: delegate
|
||||||
height: 26
|
|
||||||
|
required property int index
|
||||||
|
|
||||||
|
required property string name
|
||||||
|
required property string value
|
||||||
|
required property string tooltip
|
||||||
|
|
||||||
|
width: textItem.contentWidth + 2 * StudioTheme.Values.flowPillMargin
|
||||||
|
height: StudioTheme.Values.flowPillHeight
|
||||||
color: "#161616"
|
color: "#161616"
|
||||||
radius: 4
|
radius: StudioTheme.Values.flowPillRadius
|
||||||
border {
|
border {
|
||||||
color: "white"
|
color: "white"
|
||||||
width: mouseArea.containsMouse ? 1 : 0
|
width: mouseArea.containsMouse ? 1 : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
HelperWidgets.ToolTipArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
tooltip: delegate.tooltip
|
||||||
|
|
||||||
|
onClicked: root.select(delegate.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: textItem
|
id: textItem
|
||||||
font.pixelSize: 12
|
font.pixelSize: StudioTheme.Values.baseFontSize
|
||||||
color: "white"
|
color: StudioTheme.Values.themeTextColor
|
||||||
text: modelData
|
text: delegate.name
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -243,6 +243,7 @@ QtObject {
|
|||||||
readonly property int flowSpacing: 7 // Odd so cursor has a center location
|
readonly property int flowSpacing: 7 // Odd so cursor has a center location
|
||||||
readonly property int flowPillMargin: 4
|
readonly property int flowPillMargin: 4
|
||||||
readonly property int flowPillHeight: 20
|
readonly property int flowPillHeight: 20
|
||||||
|
readonly property int flowPillRadius: 4
|
||||||
|
|
||||||
// Theme Colors
|
// Theme Colors
|
||||||
|
|
||||||
|
@@ -1774,6 +1774,19 @@ int ConditionListModel::errorIndex() const
|
|||||||
return m_errorIndex;
|
return m_errorIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ConditionListModel::operatorAllowed(int cursorPosition)
|
||||||
|
{
|
||||||
|
if (m_tokens.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int tokenIdx = cursorPosition - 1;
|
||||||
|
|
||||||
|
if (tokenIdx >= 0 && m_tokens[tokenIdx].type != Operator)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void ConditionListModel::internalSetup()
|
void ConditionListModel::internalSetup()
|
||||||
{
|
{
|
||||||
setInvalid(tr("No Valid Condition"));
|
setInvalid(tr("No Valid Condition"));
|
||||||
|
@@ -146,6 +146,8 @@ public:
|
|||||||
QString error() const;
|
QString error() const;
|
||||||
int errorIndex() const;
|
int errorIndex() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE bool operatorAllowed(int cursorPosition);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void validChanged();
|
void validChanged();
|
||||||
void emptyChanged();
|
void emptyChanged();
|
||||||
|
Reference in New Issue
Block a user