Port Menu and MenuItem to QtQuick2

In MenuItem, we can't inherit QAction anymore (our MenuItem has to be a
QQuickItem), so we need to aggregate, which means adding glue API.

Positioning code is disabled, icons broken, but a QMenu with our items
inside shows up and is works.
This commit is contained in:
Sebastian Kügler 2013-03-26 20:15:56 +01:00
parent b2e2cff847
commit 335e0b6d9d
4 changed files with 112 additions and 35 deletions

View File

@ -22,9 +22,9 @@
#include <QApplication> #include <QApplication>
#include <QDebug> #include <QDebug>
#include <QDesktopWidget> #include <QDesktopWidget>
#include <QGraphicsObject> // #include <QQuickItem>
#include <QGraphicsView> // #include <QGraphicsView>
#include <QDeclarativeItem> #include <QQuickItem>
#include "plasmacomponentsplugin.h" #include "plasmacomponentsplugin.h"
QMenuProxy::QMenuProxy (QObject *parent) QMenuProxy::QMenuProxy (QObject *parent)
@ -41,9 +41,9 @@ QMenuProxy::~QMenuProxy()
delete m_menu; delete m_menu;
} }
QDeclarativeListProperty<QMenuItem> QMenuProxy::content() QQmlListProperty<QMenuItem> QMenuProxy::content()
{ {
return QDeclarativeListProperty<QMenuItem>(this, m_items); return QQmlListProperty<QMenuItem>(this, m_items);
} }
int QMenuProxy::actionCount() const int QMenuProxy::actionCount() const
@ -84,7 +84,7 @@ void QMenuProxy::setVisualParent(QObject *parent)
action->setMenu(m_menu); action->setMenu(m_menu);
m_menu->clear(); m_menu->clear();
foreach(QMenuItem* item, m_items) { foreach(QMenuItem* item, m_items) {
m_menu->addAction(item); m_menu->addAction(item->action());
} }
m_menu->updateGeometry(); m_menu->updateGeometry();
} }
@ -101,7 +101,7 @@ bool QMenuProxy::event(QEvent *event)
QMenuItem *mi = qobject_cast<QMenuItem *>(ce->child()); QMenuItem *mi = qobject_cast<QMenuItem *>(ce->child());
//FIXME: linear complexity here //FIXME: linear complexity here
if (mi && !m_items.contains(mi)) { if (mi && !m_items.contains(mi)) {
m_menu->addAction(mi); m_menu->addAction(mi->action());
m_items << mi; m_items << mi;
} }
break; break;
@ -113,7 +113,7 @@ bool QMenuProxy::event(QEvent *event)
//FIXME: linear complexity here //FIXME: linear complexity here
if (mi) { if (mi) {
m_menu->removeAction(mi); m_menu->removeAction(mi->action());
m_items.removeAll(mi); m_items.removeAll(mi);
} }
break; break;
@ -134,15 +134,15 @@ void QMenuProxy::clearMenuItems()
void QMenuProxy::addMenuItem(const QString &text) void QMenuProxy::addMenuItem(const QString &text)
{ {
QMenuItem *item = new QMenuItem(this); QMenuItem *item = new QMenuItem();
item->setText(text); item->setText(text);
m_menu->addAction(item); m_menu->addAction(item->action());
m_items << item; m_items << item;
} }
void QMenuProxy::addMenuItem(QMenuItem *item) void QMenuProxy::addMenuItem(QMenuItem *item)
{ {
m_menu->addAction(item); m_menu->addAction(item->action());
m_items << item; m_items << item;
} }
@ -162,25 +162,25 @@ void QMenuProxy::open(int x, int y)
{ {
m_menu->clear(); m_menu->clear();
foreach(QMenuItem* item, m_items) { foreach(QMenuItem* item, m_items) {
m_menu->addAction (item); qDebug() <<"Adding action: " << item->text();
m_menu->addAction(item->action());
} }
QPoint screenPos; QPoint screenPos;
QGraphicsObject *parentItem; QQuickItem *parentItem;
if (m_visualParent) { if (m_visualParent) {
parentItem = qobject_cast<QGraphicsObject *>(m_visualParent.data()); parentItem = qobject_cast<QQuickItem *>(m_visualParent.data());
} else { } else {
parentItem = qobject_cast<QGraphicsObject *>(parent()); parentItem = qobject_cast<QQuickItem *>(parent());
} }
/*
if (!parentItem || !parentItem->scene()) { if (!parentItem || !parentItem->scene()) {
m_menu->popup(QPoint(0, 0)); m_menu->popup(QPoint(0, 0));
m_status = DialogStatus::Open; m_status = DialogStatus::Open;
emit statusChanged(); emit statusChanged();
return; return;
} }
QList<QGraphicsView*> views = parentItem->scene()->views(); QList<QGraphicsView*> views = parentItem->scene()->views();
if (views.size() < 1) { if (views.size() < 1) {
@ -214,7 +214,7 @@ void QMenuProxy::open(int x, int y)
} else { } else {
screenPos = QApplication::activeWindow()->mapToGlobal(QPoint(x, y)); screenPos = QApplication::activeWindow()->mapToGlobal(QPoint(x, y));
} }
*/
m_menu->popup(screenPos); m_menu->popup(screenPos);
m_status = DialogStatus::Open; m_status = DialogStatus::Open;
emit statusChanged(); emit statusChanged();
@ -225,24 +225,24 @@ void QMenuProxy::open()
m_menu->clear(); m_menu->clear();
foreach(QMenuItem* item, m_items) { foreach(QMenuItem* item, m_items) {
m_menu->addAction (item); m_menu->addAction(item->action());
} }
m_menu->updateGeometry(); m_menu->updateGeometry();
QGraphicsObject *parentItem; QQuickItem *parentItem;
if (m_visualParent) { if (m_visualParent) {
parentItem = qobject_cast<QGraphicsObject *>(m_visualParent.data()); parentItem = qobject_cast<QQuickItem *>(m_visualParent.data());
} else { } else {
parentItem = qobject_cast<QGraphicsObject *>(parent()); parentItem = qobject_cast<QQuickItem *>(parent());
} }
/*
if (!parentItem || !parentItem->scene()) { if (!parentItem || !parentItem->scene()) {
m_menu->popup(QPoint(0, 0)); m_menu->popup(QPoint(0, 0));
m_status = DialogStatus::Open; m_status = DialogStatus::Open;
emit statusChanged(); emit statusChanged();
return; return;
} }*/
/*
QList<QGraphicsView*> views = parentItem->scene()->views(); QList<QGraphicsView*> views = parentItem->scene()->views();
if (views.size() < 1) { if (views.size() < 1) {
@ -272,10 +272,12 @@ void QMenuProxy::open()
} }
if (!view) { if (!view) {
*/
m_menu->popup(QPoint(0, 0)); m_menu->popup(QPoint(0, 0));
m_status = DialogStatus::Open; m_status = DialogStatus::Open;
emit statusChanged(); emit statusChanged();
return; return;
/*
} }
const QRect avail = QApplication::desktop()->availableGeometry(view); const QRect avail = QApplication::desktop()->availableGeometry(view);
@ -288,6 +290,7 @@ void QMenuProxy::open()
m_menu->popup(menuPos); m_menu->popup(menuPos);
m_status = DialogStatus::Open; m_status = DialogStatus::Open;
emit statusChanged(); emit statusChanged();
*/
} }
void QMenuProxy::close() void QMenuProxy::close()

View File

@ -22,7 +22,7 @@
#include <QObject> #include <QObject>
#include <QMenu> #include <QMenu>
#include <QDeclarativeListProperty> #include <QQmlListProperty>
#include "qmenuitem.h" #include "qmenuitem.h"
#include "enums.h" #include "enums.h"
@ -32,7 +32,7 @@ class QMenuProxy : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QDeclarativeListProperty<QMenuItem> content READ content CONSTANT) Q_PROPERTY(QQmlListProperty<QMenuItem> content READ content CONSTANT)
Q_CLASSINFO("DefaultProperty", "content") Q_CLASSINFO("DefaultProperty", "content")
/** /**
@ -45,7 +45,7 @@ public:
QMenuProxy(QObject *parent = 0); QMenuProxy(QObject *parent = 0);
~QMenuProxy(); ~QMenuProxy();
QDeclarativeListProperty<QMenuItem> content(); QQmlListProperty<QMenuItem> content();
int actionCount() const; int actionCount() const;
QMenuItem *action(int) const; QMenuItem *action(int) const;
DialogStatus::Status status() const; DialogStatus::Status status() const;

View File

@ -19,11 +19,64 @@
#include "qmenuitem.h" #include "qmenuitem.h"
QMenuItem::QMenuItem(QObject *parent) QMenuItem::QMenuItem(QQuickItem *parent)
: QAction(parent) : QQuickItem(parent),
m_action(0)
{ {
connect(this, SIGNAL(triggered(bool)), this, SIGNAL(clicked())); setAction(new QAction(this));
connect(m_action, &QAction::triggered, this, &QMenuItem::clicked);
} }
QAction* QMenuItem::action() const
{
return m_action;
}
void QMenuItem::setAction(QAction* a)
{
if (m_action != a) {
m_action = a;
connect(m_action, &QAction::changed, this, &QMenuItem::textChanged);
connect(m_action, &QAction::changed, this, &QMenuItem::textChanged);
emit actionChanged();
}
}
QIcon QMenuItem::icon() const
{
return m_action->icon();
}
void QMenuItem::setIcon(const QIcon& i)
{
m_action->setIcon(i);
emit iconChanged();
}
bool QMenuItem::separator() const
{
return m_action->isSeparator();
}
void QMenuItem::setSeparator(bool s)
{
m_action->setSeparator(s);
}
QString QMenuItem::text() const
{
return m_action->text();
}
void QMenuItem::setText(const QString& t)
{
if (m_action->text() != t) {
m_action->setText(t);
// signal comes from m_action
}
}
#include "qmenuitem.moc" #include "qmenuitem.moc"

View File

@ -1,5 +1,6 @@
/*************************************************************************** /***************************************************************************
* Copyright 2011 Viranch Mehta <viranch.mehta@gmail.com> * * Copyright 2011 Viranch Mehta <viranch.mehta@gmail.com> *
* Copyright 2013 Sebastian Kügler <sebas@kde.org> *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
@ -21,9 +22,9 @@
#define QMENUITEM_H #define QMENUITEM_H
#include <QAction> #include <QAction>
#include <QObject> #include <QQuickItem>
class QMenuItem : public QAction class QMenuItem : public QQuickItem
{ {
Q_OBJECT Q_OBJECT
@ -35,13 +36,33 @@ class QMenuItem : public QAction
/** /**
* If true, the menu item will behave like a separator * If true, the menu item will behave like a separator
*/ */
Q_PROPERTY(bool separator READ isSeparator WRITE setSeparator) Q_PROPERTY(bool separator READ separator WRITE setSeparator NOTIFY separatorChanged)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(QIcon icon READ icon WRITE setIcon NOTIFY iconChanged)
Q_PROPERTY(QAction* action READ action WRITE setAction NOTIFY actionChanged)
public: public:
QMenuItem(QObject *parent = 0); QMenuItem(QQuickItem *parent = 0);
QAction* action() const;
void setAction(QAction* a);
QIcon icon() const;
void setIcon(const QIcon& i);
bool separator() const;
void setSeparator(bool s);
QString text() const;
void setText(const QString &t);
Q_SIGNALS: Q_SIGNALS:
void clicked(); void clicked();
void actionChanged();
void iconChanged();
void separatorChanged();
void textChanged();
private:
QAction* m_action;
}; };
#endif // QMENUITEM_H #endif // QMENUITEM_H