From: Tobias Koenig Date: Fri, 19 Oct 2012 12:09:57 +0000 (+0200) Subject: Add ActionItem to allow sharing Action objects between MenuBar, ToolBar and Widgets X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=3b2bce0a43d152fb7bd67051e8b428fb60fa7495;p=web%2Fkonrad%2FDeclarativeWidgets.git Add ActionItem to allow sharing Action objects between MenuBar, ToolBar and Widgets --- diff --git a/declarativeobjects.cpp b/declarativeobjects.cpp index a6771db..88ea6e2 100644 --- a/declarativeobjects.cpp +++ b/declarativeobjects.cpp @@ -154,6 +154,14 @@ DeclarativeAction::DeclarativeAction(QObject *parent) : DeclarativeObjectProxy(parent) +{ + connectAllSignals(m_proxiedObject, this); +} + +CUSTOM_METAOBJECT(DeclarativeActionItem, ActionItem) + // DeclarativeSeparator DeclarativeSeparator::DeclarativeSeparator(QObject *parent) : DeclarativeObjectProxy(parent) { diff --git a/declarativeobjects_p.h b/declarativeobjects_p.h index 8f80f8d..f7a3b36 100644 --- a/declarativeobjects_p.h +++ b/declarativeobjects_p.h @@ -29,6 +29,10 @@ #include #include +#include "objectadaptors_p.h" + +Q_DECLARE_METATYPE(QAction*) + #define DECLARATIVE_OBJECT \ public: \ Q_OBJECT_CHECK \ @@ -99,6 +103,14 @@ class DeclarativeObjectProxy : public AbstractDeclarativeObject QVector m_children; }; +class DeclarativeActionItem : public DeclarativeObjectProxy +{ + DECLARATIVE_OBJECT + + public: + DeclarativeActionItem(QObject *parent = 0); +}; + template class DeclarativeWidgetProxy : public DeclarativeObjectProxy { @@ -129,6 +141,12 @@ class DeclarativeWidgetProxy : public DeclarativeObjectProxy return; } + DeclarativeActionItem *declarativeActionItem = dynamic_cast(object); + if (declarativeActionItem) { + addAction(qobject_cast(declarativeActionItem->object())->action(), declarativeObject); + return; + } + QAction *action = qobject_cast(declarativeObject->object()); if (action) { addAction(action, declarativeObject); @@ -212,6 +230,7 @@ class DeclarativeAction : public DeclarativeObjectProxy public: DeclarativeAction(QObject *parent = 0); }; +Q_DECLARE_METATYPE(DeclarativeAction*) class DeclarativeSeparator : public DeclarativeObjectProxy { diff --git a/declarativewidgetdocument.cpp b/declarativewidgetdocument.cpp index 1955afb..fd2648a 100644 --- a/declarativewidgetdocument.cpp +++ b/declarativewidgetdocument.cpp @@ -32,6 +32,7 @@ DeclarativeWidgetDocument::DeclarativeWidgetDocument(const QUrl &url, QObject *p // objects qmlRegisterType(); qmlRegisterType("QtGui", 1, 0, "Action"); + qmlRegisterType("QtGui", 1, 0, "ActionItem"); qmlRegisterType("QtGui", 1, 0, "Separator"); // layouts diff --git a/editor.qml b/editor.qml index 1fd14cf..43f29ad 100644 --- a/editor.qml +++ b/editor.qml @@ -49,7 +49,7 @@ MainWindow { Separator {} Action { - text: "Close" + text: qsTr("Close") onTriggered: Qt.quit() } } @@ -70,16 +70,19 @@ MainWindow { Separator {} Action { + id: cutAction text: qsTr("Cut") onTriggered: textEdit.cut() } Action { + id: copyAction text: qsTr("Copy") onTriggered: textEdit.copy() } Action { + id: pasteAction text: qsTr("Paste") onTriggered: textEdit.paste() } @@ -139,19 +142,16 @@ MainWindow { contextMenuPolicy: Qt.ActionsContextMenu - Action { - text: qsTr("Cut") - onTriggered: textEdit.cut() + ActionItem { + action: cutAction } - Action { - text: qsTr("Copy") - onTriggered: textEdit.copy() + ActionItem { + action: copyAction } - Action { - text: qsTr("Paste") - onTriggered: textEdit.paste() + ActionItem { + action: pasteAction } } diff --git a/objectadaptors.cpp b/objectadaptors.cpp index d3f44b6..8862f24 100644 --- a/objectadaptors.cpp +++ b/objectadaptors.cpp @@ -1,5 +1,7 @@ #include "objectadaptors_p.h" +#include "declarativeobjects_p.h" + FileDialog::FileDialog(QWidget *parent) : QFileDialog(parent) { @@ -23,3 +25,55 @@ bool TextEdit::modified() const { return document()->isModified(); } + +ActionItem::ActionItem(QObject *parent) + : QObject(parent) + , m_placeholderAction(new QAction(this)) + , m_qAction(m_placeholderAction) +{ +} + +QAction* ActionItem::action() +{ + return m_qAction; +} + +void ActionItem::setAction(const QVariant &action) +{ + if (m_action == action) + return; + + m_action = action; + + QObject *object = m_action.value(); + + // Is the passed action a QAction ... + QAction *newAction = qobject_cast(object); + + // ... or a DeclarativeAction + DeclarativeAction *declarativeAction = dynamic_cast(object); + if (declarativeAction) { + newAction = qobject_cast(declarativeAction->object()); + } + + // Check if the placeholder must be replaced with the actual action + if (m_qAction == m_placeholderAction) { + const QList widgets = m_placeholderAction->associatedWidgets(); + if (!widgets.isEmpty()) { + Q_ASSERT(widgets.count() == 1); // The placeholder action can only be plugged into one widget + + // Replace the placeholder action with the new one + widgets.first()->insertAction(m_placeholderAction, newAction); + widgets.first()->removeAction(m_placeholderAction); + + m_qAction = newAction; + } + } + + emit actionChanged(); +} + +QVariant ActionItem::qmlAction() const +{ + return m_action; +} diff --git a/objectadaptors_p.h b/objectadaptors_p.h index 11e22f7..cc2f32f 100644 --- a/objectadaptors_p.h +++ b/objectadaptors_p.h @@ -1,6 +1,7 @@ #ifndef OBJECTADAPTORS_P_H #define OBJECTADAPTORS_P_H +#include #include #include #include @@ -65,4 +66,27 @@ class TextEdit : public QTextEdit bool modified() const; }; +class ActionItem : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QVariant action READ qmlAction WRITE setAction NOTIFY actionChanged) + + public: + ActionItem(QObject *parent = 0); + + QAction* action(); + + Q_SIGNALS: + void actionChanged(); + + private: + void setAction(const QVariant &action); + QVariant qmlAction() const; + + QVariant m_action; + QAction* m_placeholderAction; + QAction* m_qAction; +}; + #endif