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

View File

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

View File

@ -19,11 +19,64 @@
#include "qmenuitem.h"
QMenuItem::QMenuItem(QObject *parent)
: QAction(parent)
QMenuItem::QMenuItem(QQuickItem *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"

View File

@ -1,5 +1,6 @@
/***************************************************************************
* 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 *
* it under the terms of the GNU General Public License as published by *
@ -21,9 +22,9 @@
#define QMENUITEM_H
#include <QAction>
#include <QObject>
#include <QQuickItem>
class QMenuItem : public QAction
class QMenuItem : public QQuickItem
{
Q_OBJECT
@ -35,13 +36,33 @@ class QMenuItem : public QAction
/**
* 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:
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:
void clicked();
void actionChanged();
void iconChanged();
void separatorChanged();
void textChanged();
private:
QAction* m_action;
};
#endif // QMENUITEM_H