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:
Henning Gruendl
2023-09-12 11:14:58 +02:00
committed by Henning Gründl
parent c5d5a564c8
commit ed6f870a81
7 changed files with 108 additions and 16 deletions

View File

@@ -181,10 +181,12 @@ Column {
color: StudioTheme.Values.themeToolbarBackground
Text {
width: parent.width - 8 // twice the editor button margins
anchors.centerIn: parent
text: backend.source
color: StudioTheme.Values.themeTextColor
font.pixelSize: StudioTheme.Values.myFontSize
wrapMode: Text.WordWrap
}
HelperWidgets.AbstractButton {

View File

@@ -87,10 +87,68 @@ Rectangle {
newTextInput.index = index
newTextInput.visible = true
newTextInput.forceActiveFocus()
if (!root.shadowPillVisible)
popup.showOperators = root.conditionListModel.operatorAllowed(index)
// Open suggestion popup
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 {
id: toolTip
visible: mouseArea.containsMouse && toolTip.text !== ""
@@ -197,6 +255,8 @@ Rectangle {
Pill {
id: pill
operatorModel: __operatorModel
onRemove: function() {
// If pill has focus due to selection or keyboard navigation
if (pill.focus)
@@ -289,6 +349,8 @@ Rectangle {
y: root.height
width: root.width
operatorModel: __operatorModel
//onOpened: console.log("POPUP opened")
//onClosed: console.log("POPUP closed")

View File

@@ -31,6 +31,7 @@ FocusScope {
signal submit(int cursorPosition)
readonly property int margin: StudioTheme.Values.flowPillMargin
property var operatorModel
width: {
if (root.isEditable()) {
@@ -88,7 +89,7 @@ FocusScope {
return 0
}
radius: 4
radius: StudioTheme.Values.flowPillRadius
Row {
id: row
@@ -102,7 +103,8 @@ FocusScope {
font.pixelSize: StudioTheme.Values.baseFontSize
color: root.isShadow() ? StudioTheme.Values.themeTextSelectedTextColor
: StudioTheme.Values.themeTextColor
text: root.value
text: root.isOperator() ? root.operatorModel.convertValueToName(root.value)
: root.value
anchors.verticalCenter: parent.verticalCenter
}

View File

@@ -3,6 +3,7 @@
import QtQuick
import QtQuick.Controls as Controls
import HelperWidgets as HelperWidgets
import StudioTheme as StudioTheme
import StudioControls as StudioControls
import ConnectionsEditorEditorBackend
@@ -20,6 +21,8 @@ Controls.Popup {
signal exited(var value)
property alias searchActive: search.activeFocus
property bool showOperators: false
property alias operatorModel: repeater.model
function reset() {
search.clear()
@@ -43,6 +46,7 @@ Controls.Popup {
StudioControls.SearchBox {
id: search
width: parent.width
visible: !root.showOperators
onSearchChanged: function(value) {
root.treeModel.setFilter(value)
@@ -51,12 +55,10 @@ Controls.Popup {
Controls.StackView {
id: stack
visible: !root.showOperators
width: parent.width
height: currentItem?.implicitHeight
clip: true
initialItem: mainView
}
@@ -210,7 +212,7 @@ Controls.Popup {
}
Item {
visible: false
visible: root.showOperators
width: stack.width
height: flow.childrenRect.height + 2 * StudioTheme.Values.flowMargin
@@ -224,30 +226,38 @@ Controls.Popup {
Repeater {
id: repeater
// TODO actual value + tooltip
model: ["AND", "OR", "equal", "not equal", "greater", "less", "greater then", "less then"]
Rectangle {
width: textItem.contentWidth + 14
height: 26
id: delegate
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"
radius: 4
radius: StudioTheme.Values.flowPillRadius
border {
color: "white"
width: mouseArea.containsMouse ? 1 : 0
}
MouseArea {
HelperWidgets.ToolTipArea {
id: mouseArea
hoverEnabled: true
anchors.fill: parent
tooltip: delegate.tooltip
onClicked: root.select(delegate.value)
}
Text {
id: textItem
font.pixelSize: 12
color: "white"
text: modelData
font.pixelSize: StudioTheme.Values.baseFontSize
color: StudioTheme.Values.themeTextColor
text: delegate.name
anchors.centerIn: parent
}
}

View File

@@ -243,6 +243,7 @@ QtObject {
readonly property int flowSpacing: 7 // Odd so cursor has a center location
readonly property int flowPillMargin: 4
readonly property int flowPillHeight: 20
readonly property int flowPillRadius: 4
// Theme Colors

View File

@@ -1774,6 +1774,19 @@ int ConditionListModel::errorIndex() const
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()
{
setInvalid(tr("No Valid Condition"));

View File

@@ -146,6 +146,8 @@ public:
QString error() const;
int errorIndex() const;
Q_INVOKABLE bool operatorAllowed(int cursorPosition);
signals:
void validChanged();
void emptyChanged();