forked from qt-creator/qt-creator
QmlDesigner: Add "NOT" option to binding editor
* Add "NOT" CheckBox in binding editor if boolean target * Fix wrong node assignment in binding editor context menu call * Fix connection editor state iteration source * Cleanup redundant code Task-number: QDS-2872 Change-Id: I8780bb1507f991b52aacfb011b889896d74ccb4f Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
committed by
Henning Gründl
parent
6d5e302157
commit
d3ab7a89f9
@@ -279,10 +279,9 @@ void ActionEditor::prepareConnections()
|
||||
}
|
||||
|
||||
// States
|
||||
for (const QmlModelState &state : QmlItemNode(m_modelNode).states().allStates())
|
||||
for (const QmlModelState &state : QmlItemNode(m_modelNode.view()->rootModelNode()).states().allStates())
|
||||
states.append(state.name());
|
||||
|
||||
|
||||
if (!connections.isEmpty() && !m_dialog.isNull())
|
||||
m_dialog->setAllConnections(connections, singletons, states);
|
||||
}
|
||||
|
||||
@@ -271,9 +271,7 @@ void BindingEditor::prepareBindings()
|
||||
}
|
||||
|
||||
if (!bindings.isEmpty() && !m_dialog.isNull())
|
||||
m_dialog->setAllBindings(bindings);
|
||||
|
||||
updateWindowName();
|
||||
m_dialog->setAllBindings(bindings, m_backendValueTypeName);
|
||||
}
|
||||
|
||||
void BindingEditor::updateWindowName()
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QPlainTextEdit>
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -50,6 +51,8 @@ BindingEditorDialog::BindingEditorDialog(QWidget *parent)
|
||||
this, &BindingEditorDialog::itemIDChanged);
|
||||
QObject::connect(m_comboBoxProperty, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &BindingEditorDialog::propertyIDChanged);
|
||||
QObject::connect(m_checkBoxNot, QOverload<int>::of(&QCheckBox::stateChanged),
|
||||
this, &BindingEditorDialog::checkBoxChanged);
|
||||
}
|
||||
|
||||
BindingEditorDialog::~BindingEditorDialog()
|
||||
@@ -58,7 +61,12 @@ BindingEditorDialog::~BindingEditorDialog()
|
||||
|
||||
void BindingEditorDialog::adjustProperties()
|
||||
{
|
||||
const QString expression = editorValue();
|
||||
QString expression = editorValue().trimmed();
|
||||
|
||||
m_checkBoxNot->setChecked(expression.startsWith("!"));
|
||||
if (m_checkBoxNot->isChecked())
|
||||
expression.remove(0, 1);
|
||||
|
||||
QString item;
|
||||
QString property;
|
||||
QStringList expressionElements = expression.split(".");
|
||||
@@ -94,12 +102,14 @@ void BindingEditorDialog::adjustProperties()
|
||||
m_comboBoxProperty->setCurrentText(property);
|
||||
}
|
||||
|
||||
void BindingEditorDialog::setAllBindings(QList<BindingOption> bindings)
|
||||
void BindingEditorDialog::setAllBindings(const QList<BindingOption> &bindings, const TypeName &type)
|
||||
{
|
||||
m_lock = true;
|
||||
|
||||
m_bindings = bindings;
|
||||
m_type = type;
|
||||
setupComboBoxes();
|
||||
setupCheckBox();
|
||||
adjustProperties();
|
||||
|
||||
m_lock = false;
|
||||
@@ -109,11 +119,15 @@ void BindingEditorDialog::setupUIComponents()
|
||||
{
|
||||
m_comboBoxItem = new QComboBox(this);
|
||||
m_comboBoxProperty = new QComboBox(this);
|
||||
m_checkBoxNot = new QCheckBox(this);
|
||||
m_checkBoxNot->setText(tr("NOT"));
|
||||
m_checkBoxNot->setVisible(false);
|
||||
m_checkBoxNot->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
|
||||
m_checkBoxNot->setToolTip(tr("Invert the boolean expression."));
|
||||
|
||||
m_comboBoxLayout->addWidget(m_comboBoxItem);
|
||||
m_comboBoxLayout->addWidget(m_comboBoxProperty);
|
||||
|
||||
//this->resize(660, 240);
|
||||
m_comboBoxLayout->addWidget(m_checkBoxNot);
|
||||
}
|
||||
|
||||
void BindingEditorDialog::setupComboBoxes()
|
||||
@@ -125,6 +139,12 @@ void BindingEditorDialog::setupComboBoxes()
|
||||
m_comboBoxItem->addItem(bind.item);
|
||||
}
|
||||
|
||||
void BindingEditorDialog::setupCheckBox()
|
||||
{
|
||||
const bool visible = (m_type == "bool");
|
||||
m_checkBoxNot->setVisible(visible);
|
||||
}
|
||||
|
||||
void BindingEditorDialog::itemIDChanged(int itemID)
|
||||
{
|
||||
const QString previousProperty = m_comboBoxProperty->currentText();
|
||||
@@ -148,12 +168,31 @@ void BindingEditorDialog::propertyIDChanged(int propertyID)
|
||||
const int itemID = m_comboBoxItem->currentIndex();
|
||||
|
||||
if (!m_lock)
|
||||
if (!m_comboBoxProperty->currentText().isEmpty() && (m_comboBoxProperty->currentText() != undefinedString))
|
||||
setEditorValue(m_comboBoxItem->itemText(itemID) + "." + m_comboBoxProperty->itemText(propertyID));
|
||||
if (!m_comboBoxProperty->currentText().isEmpty() && (m_comboBoxProperty->currentText() != undefinedString)) {
|
||||
QString expression = m_comboBoxItem->itemText(itemID) + "." + m_comboBoxProperty->itemText(propertyID);
|
||||
if (m_checkBoxNot->isChecked())
|
||||
expression.prepend("!");
|
||||
|
||||
setEditorValue(expression);
|
||||
}
|
||||
|
||||
const int undefinedProperty = m_comboBoxProperty->findText(undefinedString);
|
||||
if ((undefinedProperty != -1) && (m_comboBoxProperty->itemText(propertyID) != undefinedString))
|
||||
m_comboBoxProperty->removeItem(undefinedProperty);
|
||||
}
|
||||
|
||||
void BindingEditorDialog::checkBoxChanged(int state)
|
||||
{
|
||||
if (m_lock)
|
||||
return;
|
||||
|
||||
QString expression = editorValue().trimmed();
|
||||
if (state == Qt::Checked)
|
||||
expression.prepend("!");
|
||||
else
|
||||
expression.remove(0, 1);
|
||||
|
||||
setEditorValue(expression);
|
||||
}
|
||||
|
||||
} // QmlDesigner namespace
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QComboBox;
|
||||
class QCheckBox;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -56,21 +57,25 @@ public:
|
||||
|
||||
void adjustProperties() override;
|
||||
|
||||
void setAllBindings(QList<BindingOption> bindings);
|
||||
void setAllBindings(const QList<BindingOption> &bindings, const TypeName &type);
|
||||
|
||||
private:
|
||||
void setupUIComponents();
|
||||
void setupComboBoxes();
|
||||
void setupCheckBox();
|
||||
|
||||
public slots:
|
||||
void itemIDChanged(int);
|
||||
void propertyIDChanged(int);
|
||||
void checkBoxChanged(int);
|
||||
|
||||
private:
|
||||
QComboBox *m_comboBoxItem = nullptr;
|
||||
QComboBox *m_comboBoxProperty = nullptr;
|
||||
QCheckBox *m_checkBoxNot = nullptr;
|
||||
|
||||
QList<BindingOption> m_bindings;
|
||||
TypeName m_type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
|
||||
auto tablePos = [&](QTableView *targetView) {
|
||||
// adjusting qpoint to the qtableview entrances:
|
||||
QPoint posInTable(targetView->mapFromGlobal(mapToGlobal(event->pos())));
|
||||
posInTable = QPoint(posInTable.x(), posInTable.y() - targetView->horizontalHeader()->height());
|
||||
posInTable.ry() -= targetView->horizontalHeader()->height();
|
||||
return posInTable;
|
||||
};
|
||||
|
||||
@@ -153,23 +153,23 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
|
||||
if (ui->connectionView != nullptr) {
|
||||
QTableView *targetView = ui->connectionView;
|
||||
// making sure that we have source column in our hands:
|
||||
QModelIndex index = targetView->indexAt(tablePos(targetView)).siblingAtColumn(ConnectionModel::SourceRow);
|
||||
const QModelIndex index = targetView->indexAt(tablePos(targetView)).siblingAtColumn(ConnectionModel::SourceRow);
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
QMenu menu(this);
|
||||
|
||||
menu.addAction(tr("Open Connection Editor"), [&]() {
|
||||
if (index.isValid()) {
|
||||
auto *connectionModel = qobject_cast<ConnectionModel *>(targetView->model());
|
||||
ModelNode node = connectionModel->connectionView()->rootModelNode();
|
||||
const SignalHandlerProperty property = connectionModel->signalHandlerPropertyForRow(index.row());
|
||||
const ModelNode node = property.parentModelNode();
|
||||
|
||||
m_connectionEditor->showWidget();
|
||||
m_connectionEditor->setConnectionValue(index.data().toString());
|
||||
m_connectionEditor->setModelIndex(index);
|
||||
m_connectionEditor->setModelNode(node);
|
||||
m_connectionEditor->prepareConnections();
|
||||
m_connectionEditor->updateWindowName();
|
||||
}
|
||||
});
|
||||
|
||||
menu.exec(event->globalPos());
|
||||
@@ -179,37 +179,31 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
|
||||
case BindingTab:
|
||||
if (ui->bindingView != nullptr) {
|
||||
QTableView *targetView = bindingTableView();
|
||||
QModelIndex index = targetView->indexAt(tablePos(targetView)).siblingAtColumn(BindingModel::SourcePropertyNameRow);
|
||||
const QModelIndex index = targetView->indexAt(tablePos(targetView)).siblingAtColumn(BindingModel::SourcePropertyNameRow);
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
QMenu menu(this);
|
||||
|
||||
menu.addAction(tr("Open Binding Editor"), [&]() {
|
||||
if (index.isValid()) {
|
||||
BindingModel *binModel = qobject_cast<BindingModel*>(targetView->model());
|
||||
ModelNode node = binModel->connectionView()->rootModelNode();
|
||||
BindingModel *bindingModel = qobject_cast<BindingModel*>(targetView->model());
|
||||
const BindingProperty property = bindingModel->bindingPropertyForRow(index.row());
|
||||
|
||||
BindingProperty property = binModel->bindingPropertyForRow(index.row());
|
||||
if (!property.isValid() || !property.isBindingProperty())
|
||||
return;
|
||||
|
||||
const ModelNode node = property.parentModelNode();
|
||||
const TypeName typeName = property.isDynamic() ? property.dynamicTypeName()
|
||||
: node.metaInfo().propertyTypeName(property.name());
|
||||
|
||||
if (property.isValid()) {
|
||||
if (property.isBindingProperty()) {
|
||||
m_bindingEditor->showWidget();
|
||||
m_bindingEditor->setBindingValue(property.expression());
|
||||
m_bindingEditor->setModelNode(node);
|
||||
if (property.isDynamic()) {
|
||||
m_bindingEditor->setBackendValueTypeName(property.dynamicTypeName());
|
||||
}
|
||||
else {
|
||||
m_bindingEditor->setBackendValueTypeName(node.metaInfo().propertyTypeName(property.name()));
|
||||
}
|
||||
m_bindingEditor->setBackendValueTypeName(typeName);
|
||||
m_bindingEditor->prepareBindings();
|
||||
m_bindingEditor->updateWindowName();
|
||||
|
||||
m_bindingIndex = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
@@ -218,51 +212,40 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event)
|
||||
case DynamicPropertiesTab:
|
||||
if (ui->dynamicPropertiesView != nullptr) {
|
||||
QTableView *targetView = dynamicPropertiesTableView();
|
||||
QModelIndex index = targetView->indexAt(tablePos(targetView)).siblingAtColumn(DynamicPropertiesModel::PropertyValueRow);
|
||||
const QModelIndex index = targetView->indexAt(tablePos(targetView)).siblingAtColumn(DynamicPropertiesModel::PropertyValueRow);
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
DynamicPropertiesModel *propertiesModel = qobject_cast<DynamicPropertiesModel *>(targetView->model());
|
||||
QMenu menu(this);
|
||||
|
||||
menu.addAction(tr("Open Binding Editor"), [&]() {
|
||||
if (index.isValid()) {
|
||||
DynamicPropertiesModel *dynPropModel = qobject_cast<DynamicPropertiesModel*>(targetView->model());
|
||||
ModelNode node = dynPropModel->connectionView()->rootModelNode();
|
||||
|
||||
AbstractProperty abProp = dynPropModel->abstractPropertyForRow(index.row());
|
||||
AbstractProperty abstractProperty = propertiesModel->abstractPropertyForRow(index.row());
|
||||
if (!abstractProperty.isValid())
|
||||
return;
|
||||
|
||||
const ModelNode node = abstractProperty.parentModelNode();
|
||||
QString newExpression;
|
||||
|
||||
if (abProp.isValid()) {
|
||||
if (abProp.isBindingProperty()) {
|
||||
BindingProperty property = abProp.toBindingProperty();
|
||||
newExpression = property.expression();
|
||||
}
|
||||
else if (abProp.isVariantProperty()) {
|
||||
VariantProperty property = abProp.toVariantProperty();
|
||||
newExpression = property.value().toString();
|
||||
}
|
||||
if (abstractProperty.isBindingProperty())
|
||||
newExpression = abstractProperty.toBindingProperty().expression();
|
||||
else if (abstractProperty.isVariantProperty())
|
||||
newExpression = abstractProperty.toVariantProperty().value().toString();
|
||||
else
|
||||
return;
|
||||
|
||||
m_dynamicEditor->showWidget();
|
||||
m_dynamicEditor->setBindingValue(newExpression);
|
||||
m_dynamicEditor->setModelNode(node);
|
||||
m_dynamicEditor->setBackendValueTypeName(abProp.dynamicTypeName());
|
||||
m_dynamicEditor->setBackendValueTypeName(abstractProperty.dynamicTypeName());
|
||||
m_dynamicEditor->prepareBindings();
|
||||
m_dynamicEditor->updateWindowName();
|
||||
|
||||
m_dynamicIndex = index;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
menu.addAction(tr("Reset Property"), [&]() {
|
||||
if (index.isValid()) {
|
||||
DynamicPropertiesModel *propertiesModel = qobject_cast<DynamicPropertiesModel *>(dynamicPropertiesTableView()->model());
|
||||
|
||||
propertiesModel->resetProperty(propertiesModel->abstractPropertyForRow(index.row()).name());
|
||||
}
|
||||
});
|
||||
|
||||
menu.exec(event->globalPos());
|
||||
|
||||
Reference in New Issue
Block a user