forked from qt-creator/qt-creator
QmlDesigner: Categorize slot actions
Task-number: QDS-8447 Change-Id: Ibc96bfcb7c87f0888e15f2533cab2567098a3760 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -487,11 +487,16 @@ QStringList getSignalsList(const ModelNode &node)
|
|||||||
|
|
||||||
struct SlotEntry
|
struct SlotEntry
|
||||||
{
|
{
|
||||||
QString category;
|
|
||||||
QString name;
|
QString name;
|
||||||
std::function<void(SignalHandlerProperty)> action;
|
std::function<void(SignalHandlerProperty)> action;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SlotList
|
||||||
|
{
|
||||||
|
QString categoryName;
|
||||||
|
QList<SlotEntry> slotEntries;
|
||||||
|
};
|
||||||
|
|
||||||
QList<ModelNode> stateGroups(const ModelNode &node)
|
QList<ModelNode> stateGroups(const ModelNode &node)
|
||||||
{
|
{
|
||||||
if (!node.view()->isAttached())
|
if (!node.view()->isAttached())
|
||||||
@@ -502,13 +507,7 @@ QList<ModelNode> stateGroups(const ModelNode &node)
|
|||||||
return node.view()->allModelNodesOfType(groupMetaInfo);
|
return node.view()->allModelNodesOfType(groupMetaInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList stateGroupsNames(const ModelNode &node)
|
QList<SlotList> getSlotsLists(const ModelNode &node)
|
||||||
{
|
|
||||||
return Utils::transform(stateGroups(node),
|
|
||||||
[](const ModelNode &node) { return node.displayName(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<SlotEntry> getSlotsLists(const ModelNode &node)
|
|
||||||
{
|
{
|
||||||
if (!node.isValid())
|
if (!node.isValid())
|
||||||
return {};
|
return {};
|
||||||
@@ -516,58 +515,52 @@ QList<SlotEntry> getSlotsLists(const ModelNode &node)
|
|||||||
if (!node.view()->rootModelNode().isValid())
|
if (!node.view()->rootModelNode().isValid())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
QList<SlotEntry> resultList;
|
QList<SlotList> resultList;
|
||||||
|
|
||||||
ModelNode rootNode = node.view()->rootModelNode();
|
ModelNode rootNode = node.view()->rootModelNode();
|
||||||
QmlObjectNode rootObjectNode(rootNode);
|
QmlObjectNode rootObjectNode(rootNode);
|
||||||
|
|
||||||
const QString stateCategory = "Change State";
|
const QString changeStateStr = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Change State");
|
||||||
|
const QString changeStateGroupStr = QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
|
||||||
//For now we are using category as part of the state name
|
"Change State Group");
|
||||||
//We should change it, once we extend number of categories
|
const QString defaultStateStr = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Default State");
|
||||||
const SlotEntry defaultState = {stateCategory,
|
auto createStateChangeSlot =
|
||||||
(stateCategory + " to " + "Default State"),
|
[](const ModelNode &node, const QString &stateName, const QString &displayName) {
|
||||||
[rootNode](SignalHandlerProperty signalHandler) {
|
return SlotEntry({displayName, [node, stateName](SignalHandlerProperty signalHandler) {
|
||||||
signalHandler.setSource(
|
signalHandler.setSource(
|
||||||
QString("%1.state = \"\"").arg(rootNode.id()));
|
QString("%1.state = \"%2\"").arg(node.id(), stateName));
|
||||||
}};
|
}});
|
||||||
resultList.push_back(defaultState);
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
SlotList states = {changeStateStr, {}};
|
||||||
|
|
||||||
|
const SlotEntry defaultState = createStateChangeSlot(rootNode, "", defaultStateStr);
|
||||||
|
states.slotEntries.push_back(defaultState);
|
||||||
|
|
||||||
for (const auto &stateName : rootObjectNode.states().names()) {
|
for (const auto &stateName : rootObjectNode.states().names()) {
|
||||||
SlotEntry entry = {stateCategory,
|
const SlotEntry entry = createStateChangeSlot(rootNode, stateName, stateName);
|
||||||
(stateCategory + " to " + stateName),
|
|
||||||
[rootNode, stateName](SignalHandlerProperty signalHandler) {
|
|
||||||
signalHandler.setSource(
|
|
||||||
QString("%1.state = \"%2\"").arg(rootNode.id(), stateName));
|
|
||||||
}};
|
|
||||||
|
|
||||||
resultList.push_back(entry);
|
states.slotEntries.push_back(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto sg = stateGroups(node);
|
resultList.push_back(states);
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto &stateGroup : sg) {
|
const QList<ModelNode> groups = stateGroups(node);
|
||||||
|
for (const auto &stateGroup : groups) {
|
||||||
QmlObjectNode stateGroupObjectNode(stateGroup);
|
QmlObjectNode stateGroupObjectNode(stateGroup);
|
||||||
const QString stateGroupCategory = QString("Change State Group") + " "
|
SlotList stateGroupCategory = {changeStateGroupStr + " " + stateGroup.displayName(), {}};
|
||||||
+ stateGroup.displayName();
|
|
||||||
|
|
||||||
const SlotEntry defaultGroupState = {stateGroupCategory,
|
const SlotEntry defaultGroupState = createStateChangeSlot(stateGroup, "", defaultStateStr);
|
||||||
(stateGroupCategory + " to " + "Default State"),
|
stateGroupCategory.slotEntries.push_back(defaultGroupState);
|
||||||
[stateGroup](SignalHandlerProperty signalHandler) {
|
|
||||||
signalHandler.setSource(
|
|
||||||
QString("%1.state = \"\"").arg(stateGroup.id()));
|
|
||||||
}};
|
|
||||||
resultList.push_back(defaultGroupState);
|
|
||||||
|
|
||||||
for (const auto &stateName : stateGroupObjectNode.states().names()) {
|
for (const auto &stateName : stateGroupObjectNode.states().names()) {
|
||||||
SlotEntry entry = {stateGroupCategory,
|
const SlotEntry entry = createStateChangeSlot(stateGroup, stateName, stateName);
|
||||||
(stateGroupCategory + " to " + stateName),
|
stateGroupCategory.slotEntries.push_back(entry);
|
||||||
[stateGroup, stateName](SignalHandlerProperty signalHandler) {
|
|
||||||
signalHandler.setSource(
|
|
||||||
QString("%1.state = \"%2\"").arg(stateGroup.id(), stateName));
|
|
||||||
}};
|
|
||||||
resultList.push_back(entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resultList.push_back(stateGroupCategory);
|
||||||
}
|
}
|
||||||
|
|
||||||
return resultList;
|
return resultList;
|
||||||
@@ -577,10 +570,8 @@ QList<SlotEntry> getSlotsLists(const ModelNode &node)
|
|||||||
ModelNode createNewConnection(ModelNode targetNode)
|
ModelNode createNewConnection(ModelNode targetNode)
|
||||||
{
|
{
|
||||||
NodeMetaInfo connectionsMetaInfo = targetNode.view()->model()->metaInfo("QtQuick.Connections");
|
NodeMetaInfo connectionsMetaInfo = targetNode.view()->model()->metaInfo("QtQuick.Connections");
|
||||||
ModelNode newConnectionNode = targetNode.view()
|
ModelNode newConnectionNode = targetNode.view()->createModelNode(
|
||||||
->createModelNode("QtQuick.Connections",
|
"QtQuick.Connections", connectionsMetaInfo.majorVersion(), connectionsMetaInfo.minorVersion());
|
||||||
connectionsMetaInfo.majorVersion(),
|
|
||||||
connectionsMetaInfo.minorVersion());
|
|
||||||
if (QmlItemNode::isValidQmlItemNode(targetNode))
|
if (QmlItemNode::isValidQmlItemNode(targetNode))
|
||||||
targetNode.nodeAbstractProperty("data").reparentHere(newConnectionNode);
|
targetNode.nodeAbstractProperty("data").reparentHere(newConnectionNode);
|
||||||
|
|
||||||
@@ -606,9 +597,7 @@ void removeSignal(SignalHandlerProperty signalHandler)
|
|||||||
class ConnectionsModelNodeActionGroup : public ActionGroup
|
class ConnectionsModelNodeActionGroup : public ActionGroup
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ConnectionsModelNodeActionGroup(const QString &displayName,
|
ConnectionsModelNodeActionGroup(const QString &displayName, const QByteArray &menuId, int priority)
|
||||||
const QByteArray &menuId,
|
|
||||||
int priority)
|
|
||||||
: ActionGroup(displayName,
|
: ActionGroup(displayName,
|
||||||
menuId,
|
menuId,
|
||||||
priority,
|
priority,
|
||||||
@@ -638,7 +627,7 @@ public:
|
|||||||
QmlObjectNode currentObjectNode(currentNode);
|
QmlObjectNode currentObjectNode(currentNode);
|
||||||
|
|
||||||
QStringList signalsList = getSignalsList(currentNode);
|
QStringList signalsList = getSignalsList(currentNode);
|
||||||
QList<SlotEntry> slotsList = getSlotsLists(currentNode);
|
QList<SlotList> slotsLists = getSlotsLists(currentNode);
|
||||||
|
|
||||||
if (!currentNode.hasId()) {
|
if (!currentNode.hasId()) {
|
||||||
menu()->setEnabled(false);
|
menu()->setEnabled(false);
|
||||||
@@ -654,7 +643,9 @@ public:
|
|||||||
|
|
||||||
QMenu *activeSignalHandlerGroup = new QMenu(propertyName, menu());
|
QMenu *activeSignalHandlerGroup = new QMenu(propertyName, menu());
|
||||||
|
|
||||||
QMenu *editSignalGroup = new QMenu("Change Signal", menu());
|
QMenu *editSignalGroup = new QMenu(QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
|
||||||
|
"Change Signal"),
|
||||||
|
menu());
|
||||||
|
|
||||||
for (const auto &signalStr : signalsList) {
|
for (const auto &signalStr : signalsList) {
|
||||||
if (prependSignal(signalStr).toUtf8() == signalHandler.name())
|
if (prependSignal(signalStr).toUtf8() == signalHandler.name())
|
||||||
@@ -680,39 +671,59 @@ public:
|
|||||||
|
|
||||||
activeSignalHandlerGroup->addMenu(editSignalGroup);
|
activeSignalHandlerGroup->addMenu(editSignalGroup);
|
||||||
|
|
||||||
if (!slotsList.isEmpty()) {
|
if (!slotsLists.isEmpty()) {
|
||||||
QMenu *editSlotGroup = new QMenu("Change Slot", menu());
|
QMenu *editSlotGroup = new QMenu(QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
|
||||||
|
"Change Slot"),
|
||||||
|
menu());
|
||||||
|
|
||||||
for (const auto &slot : slotsList) {
|
if (slotsLists.size() == 1) {
|
||||||
|
for (const auto &slot : slotsLists.at(0).slotEntries) {
|
||||||
|
ActionTemplate *newSlotAction = new ActionTemplate(
|
||||||
|
(slot.name + "Id").toLatin1(),
|
||||||
|
(slotsLists.at(0).categoryName
|
||||||
|
+ (QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
|
||||||
|
" to ")) //context: Change State _to_ state1
|
||||||
|
+ slot.name),
|
||||||
|
[slot, signalHandler](const SelectionContext &) {
|
||||||
|
signalHandler.parentModelNode().view()->executeInTransaction(
|
||||||
|
"ConnectionsModelNodeActionGroup::"
|
||||||
|
"changeSlot",
|
||||||
|
[slot, signalHandler]() { slot.action(signalHandler); });
|
||||||
|
});
|
||||||
|
editSlotGroup->addAction(newSlotAction);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (const auto &slotCategory : slotsLists) {
|
||||||
|
QMenu *slotCategoryMenu = new QMenu(slotCategory.categoryName, menu());
|
||||||
|
for (const auto &slot : slotCategory.slotEntries) {
|
||||||
ActionTemplate *newSlotAction = new ActionTemplate(
|
ActionTemplate *newSlotAction = new ActionTemplate(
|
||||||
(slot.name + "Id").toLatin1(),
|
(slot.name + "Id").toLatin1(),
|
||||||
slot.name,
|
slot.name,
|
||||||
[slot, signalHandler](const SelectionContext &) {
|
[slot, signalHandler](const SelectionContext &) {
|
||||||
signalHandler.parentModelNode()
|
signalHandler.parentModelNode().view()->executeInTransaction(
|
||||||
.view()
|
"ConnectionsModelNodeActionGroup::"
|
||||||
->executeInTransaction("ConnectionsModelNodeActionGroup::"
|
|
||||||
"changeSlot",
|
"changeSlot",
|
||||||
[slot, signalHandler]() {
|
[slot, signalHandler]() {
|
||||||
slot.action(signalHandler);
|
slot.action(signalHandler);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
editSlotGroup->addAction(newSlotAction);
|
slotCategoryMenu->addAction(newSlotAction);
|
||||||
|
}
|
||||||
|
editSlotGroup->addMenu(slotCategoryMenu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
activeSignalHandlerGroup->addMenu(editSlotGroup);
|
activeSignalHandlerGroup->addMenu(editSlotGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionTemplate *openEditorAction = new ActionTemplate(
|
ActionTemplate *openEditorAction = new ActionTemplate(
|
||||||
(propertyName + "OpenEditorId").toLatin1(),
|
(propertyName + "OpenEditorId").toLatin1(),
|
||||||
QString(
|
QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Open Connections Editor")),
|
||||||
QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Open Connections Editor")),
|
|
||||||
[=](const SelectionContext &) {
|
[=](const SelectionContext &) {
|
||||||
signalHandler.parentModelNode()
|
signalHandler.parentModelNode().view()->executeInTransaction(
|
||||||
.view()
|
"ConnectionsModelNodeActionGroup::"
|
||||||
->executeInTransaction("ConnectionsModelNodeActionGroup::"
|
|
||||||
"openConnectionsEditor",
|
"openConnectionsEditor",
|
||||||
[signalHandler]() {
|
[signalHandler]() {
|
||||||
ActionEditor::invokeEditor(signalHandler,
|
ActionEditor::invokeEditor(signalHandler, removeSignal);
|
||||||
removeSignal);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -725,9 +736,7 @@ public:
|
|||||||
signalHandler.parentModelNode().view()->executeInTransaction(
|
signalHandler.parentModelNode().view()->executeInTransaction(
|
||||||
"ConnectionsModelNodeActionGroup::"
|
"ConnectionsModelNodeActionGroup::"
|
||||||
"removeSignalHandler",
|
"removeSignalHandler",
|
||||||
[signalHandler]() {
|
[signalHandler]() { removeSignal(signalHandler); });
|
||||||
removeSignal(signalHandler);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
activeSignalHandlerGroup->addAction(removeSignalHandlerAction);
|
activeSignalHandlerGroup->addAction(removeSignalHandlerAction);
|
||||||
@@ -745,10 +754,15 @@ public:
|
|||||||
for (const auto &signalStr : signalsList) {
|
for (const auto &signalStr : signalsList) {
|
||||||
QMenu *newSignal = new QMenu(signalStr, addConnection);
|
QMenu *newSignal = new QMenu(signalStr, addConnection);
|
||||||
|
|
||||||
for (const auto &slot : slotsList) {
|
if (!slotsLists.isEmpty()) {
|
||||||
|
if (slotsLists.size() == 1) {
|
||||||
|
for (const auto &slot : slotsLists.at(0).slotEntries) {
|
||||||
ActionTemplate *newSlot = new ActionTemplate(
|
ActionTemplate *newSlot = new ActionTemplate(
|
||||||
QString(signalStr + slot.name + "Id").toLatin1(),
|
QString(signalStr + slot.name + "Id").toLatin1(),
|
||||||
slot.name,
|
(slotsLists.at(0).categoryName
|
||||||
|
+ (QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
|
||||||
|
" to ")) //context: Change State _to_ state1
|
||||||
|
+ slot.name),
|
||||||
[=](const SelectionContext &) {
|
[=](const SelectionContext &) {
|
||||||
currentNode.view()->executeInTransaction(
|
currentNode.view()->executeInTransaction(
|
||||||
"ConnectionsModelNodeActionGroup::addConnection", [=]() {
|
"ConnectionsModelNodeActionGroup::addConnection", [=]() {
|
||||||
@@ -759,6 +773,28 @@ public:
|
|||||||
});
|
});
|
||||||
newSignal->addAction(newSlot);
|
newSignal->addAction(newSlot);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for (const auto &slotCategory : slotsLists) {
|
||||||
|
QMenu *slotCategoryMenu = new QMenu(slotCategory.categoryName, menu());
|
||||||
|
for (const auto &slot : slotCategory.slotEntries) {
|
||||||
|
ActionTemplate *newSlot = new ActionTemplate(
|
||||||
|
QString(signalStr + slot.name + "Id").toLatin1(),
|
||||||
|
slot.name,
|
||||||
|
[=](const SelectionContext &) {
|
||||||
|
currentNode.view()->executeInTransaction(
|
||||||
|
"ConnectionsModelNodeActionGroup::addConnection", [=]() {
|
||||||
|
ModelNode newConnectionNode = createNewConnection(
|
||||||
|
currentNode);
|
||||||
|
slot.action(newConnectionNode.signalHandlerProperty(
|
||||||
|
prependSignal(signalStr).toLatin1()));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
slotCategoryMenu->addAction(newSlot);
|
||||||
|
}
|
||||||
|
newSignal->addMenu(slotCategoryMenu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ActionTemplate *openEditorAction = new ActionTemplate(
|
ActionTemplate *openEditorAction = new ActionTemplate(
|
||||||
(signalStr + "OpenEditorId").toLatin1(),
|
(signalStr + "OpenEditorId").toLatin1(),
|
||||||
@@ -770,8 +806,7 @@ public:
|
|||||||
[=]() {
|
[=]() {
|
||||||
ModelNode newConnectionNode = createNewConnection(currentNode);
|
ModelNode newConnectionNode = createNewConnection(currentNode);
|
||||||
|
|
||||||
SignalHandlerProperty newHandler
|
SignalHandlerProperty newHandler = newConnectionNode.signalHandlerProperty(
|
||||||
= newConnectionNode.signalHandlerProperty(
|
|
||||||
prependSignal(signalStr).toLatin1());
|
prependSignal(signalStr).toLatin1());
|
||||||
|
|
||||||
newHandler.setSource(
|
newHandler.setSource(
|
||||||
|
Reference in New Issue
Block a user