• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kde-runtime API Reference
  • KDE Home
  • Contact Us
 

PlasmaComponents

  • sources
  • kde-4.14
  • kde-runtime
  • plasma
  • declarativeimports
  • plasmacomponents
qmenu.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2011 Viranch Mehta <viranch.mehta@gmail.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Library General Public License as
6  * published by the Free Software Foundation; either version 2, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this program; if not, write to the
16  * Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19 
20 #include "qmenu.h"
21 
22 #include <QApplication>
23 #include <QDebug>
24 #include <QDesktopWidget>
25 #include <QGraphicsObject>
26 #include <QGraphicsView>
27 #include <QDeclarativeItem>
28 
29 #include "plasmacomponentsplugin.h"
30 QMenuProxy::QMenuProxy (QObject *parent)
31  : QObject(parent),
32  m_status(DialogStatus::Closed)
33 {
34  m_menu = new QMenu(0);
35  connect(m_menu, SIGNAL(triggered(QAction *)),
36  this, SLOT(itemTriggered(QAction *)));
37  connect(m_menu, SIGNAL(aboutToHide()), SLOT(markAsClosed()));
38 }
39 
40 QMenuProxy::~QMenuProxy()
41 {
42  delete m_menu;
43 }
44 
45 QDeclarativeListProperty<QMenuItem> QMenuProxy::content()
46 {
47  return QDeclarativeListProperty<QMenuItem>(this, m_items);
48 }
49 
50 int QMenuProxy::actionCount() const
51 {
52  return m_items.count();
53 }
54 
55 QMenuItem *QMenuProxy::action(int index) const
56 {
57  return m_items.at(index);
58 }
59 
60 DialogStatus::Status QMenuProxy::status() const
61 {
62  return m_status;
63 }
64 
65 QObject *QMenuProxy::visualParent() const
66 {
67  return m_visualParent.data();
68 }
69 
70 void QMenuProxy::setVisualParent(QObject *parent)
71 {
72  if (m_visualParent.data() == parent) {
73  return;
74  }
75 
76  //if the old parent was a QAction, disconnect the menu from it
77  QAction *action = qobject_cast<QAction *>(m_visualParent.data());
78  if (action) {
79  action->setMenu(0);
80  m_menu->clear();
81  }
82  //if parent is a QAction, become a submenu
83  action = qobject_cast<QAction *>(parent);
84  if (action) {
85  action->setMenu(m_menu);
86  m_menu->clear();
87  foreach(QMenuItem* item, m_items) {
88  m_menu->addAction(item);
89  }
90  m_menu->updateGeometry();
91  }
92 
93  m_visualParent = parent;
94  emit visualParentChanged();
95 }
96 
97 bool QMenuProxy::event(QEvent *event)
98 {
99  switch (event->type()) {
100  case QEvent::ChildAdded: {
101  QChildEvent *ce = static_cast<QChildEvent *>(event);
102  QMenuItem *mi = qobject_cast<QMenuItem *>(ce->child());
103  //FIXME: linear complexity here
104  if (mi && !m_items.contains(mi)) {
105  m_menu->addAction(mi);
106  m_items << mi;
107  }
108  break;
109  }
110 
111  case QEvent::ChildRemoved: {
112  QChildEvent *ce = static_cast<QChildEvent *>(event);
113  QMenuItem *mi = qobject_cast<QMenuItem *>(ce->child());
114 
115  //FIXME: linear complexity here
116  if (mi) {
117  m_menu->removeAction(mi);
118  m_items.removeAll(mi);
119  }
120  break;
121  }
122 
123  default:
124  break;
125  }
126 
127  return QObject::event(event);
128 }
129 
130 void QMenuProxy::clearMenuItems()
131 {
132  qDeleteAll(m_items);
133  m_items.clear();
134 }
135 
136 void QMenuProxy::addMenuItem(const QString &text)
137 {
138  QMenuItem *item = new QMenuItem(this);
139  item->setText(text);
140  m_menu->addAction(item);
141  m_items << item;
142 }
143 
144 void QMenuProxy::addMenuItem(QMenuItem *item)
145 {
146  m_menu->addAction(item);
147  m_items << item;
148 }
149 
150 void QMenuProxy::itemTriggered(QAction *action)
151 {
152  QMenuItem *item = qobject_cast<QMenuItem *>(action);
153  if (item) {
154  emit triggered(item);
155  int index = m_items.indexOf(item);
156  if (index > -1) {
157  emit triggeredIndex(index);
158  }
159  }
160 }
161 
162 void QMenuProxy::open(int x, int y)
163 {
164  m_menu->clear();
165  foreach(QMenuItem* item, m_items) {
166  m_menu->addAction (item);
167  }
168 
169  QPoint screenPos;
170 
171  QGraphicsObject *parentItem;
172  if (m_visualParent) {
173  parentItem = qobject_cast<QGraphicsObject *>(m_visualParent.data());
174  } else {
175  parentItem = qobject_cast<QGraphicsObject *>(parent());
176  }
177 
178  if (!parentItem || !parentItem->scene()) {
179  m_menu->popup(QPoint(0, 0));
180  m_status = DialogStatus::Open;
181  emit statusChanged();
182  return;
183  }
184 
185  QList<QGraphicsView*> views = parentItem->scene()->views();
186 
187  if (views.size() < 1) {
188  m_menu->popup(QPoint(0, 0));
189  m_status = DialogStatus::Open;
190  emit statusChanged();
191  return;
192  }
193 
194  QGraphicsView *view = 0;
195  if (views.size() == 1) {
196  view = views[0];
197  } else {
198  QGraphicsView *found = 0;
199  QGraphicsView *possibleFind = 0;
200  foreach (QGraphicsView *v, views) {
201  if (v->sceneRect().intersects(parentItem->sceneBoundingRect()) ||
202  v->sceneRect().contains(parentItem->scenePos())) {
203  if (v->isActiveWindow()) {
204  found = v;
205  } else {
206  possibleFind = v;
207  }
208  }
209  }
210  view = found ? found : possibleFind;
211  }
212 
213  if (view) {
214  screenPos = view->mapToGlobal(view->mapFromScene(parentItem->scenePos()+ QPoint(x, y)));
215  } else {
216  screenPos = QApplication::activeWindow()->mapToGlobal(QPoint(x, y));
217  }
218 
219  m_menu->popup(screenPos);
220  m_status = DialogStatus::Open;
221  emit statusChanged();
222 }
223 
224 void QMenuProxy::open()
225 {
226  m_menu->clear();
227 
228  foreach(QMenuItem* item, m_items) {
229  m_menu->addAction (item);
230  }
231  m_menu->updateGeometry();
232 
233  QGraphicsObject *parentItem;
234  if (m_visualParent) {
235  parentItem = qobject_cast<QGraphicsObject *>(m_visualParent.data());
236  } else {
237  parentItem = qobject_cast<QGraphicsObject *>(parent());
238  }
239 
240  if (!parentItem || !parentItem->scene()) {
241  m_menu->popup(QPoint(0, 0));
242  m_status = DialogStatus::Open;
243  emit statusChanged();
244  return;
245  }
246 
247  QList<QGraphicsView*> views = parentItem->scene()->views();
248 
249  if (views.size() < 1) {
250  m_menu->popup(QPoint(0, 0));
251  m_status = DialogStatus::Open;
252  emit statusChanged();
253  return;
254  }
255 
256  QGraphicsView *view = 0;
257  if (views.size() == 1) {
258  view = views[0];
259  } else {
260  QGraphicsView *found = 0;
261  QGraphicsView *possibleFind = 0;
262  foreach (QGraphicsView *v, views) {
263  if (v->sceneRect().intersects(parentItem->sceneBoundingRect()) ||
264  v->sceneRect().contains(parentItem->scenePos())) {
265  if (v->isActiveWindow()) {
266  found = v;
267  } else {
268  possibleFind = v;
269  }
270  }
271  }
272  view = found ? found : possibleFind;
273  }
274 
275  if (!view) {
276  m_menu->popup(QPoint(0, 0));
277  m_status = DialogStatus::Open;
278  emit statusChanged();
279  return;
280  }
281 
282  const QRect avail = QApplication::desktop()->availableGeometry(view);
283  QPoint menuPos = view->mapToGlobal(view->mapFromScene(parentItem->scenePos()+QPoint(0, parentItem->boundingRect().height())));
284 
285  if (menuPos.y() + m_menu->sizeHint().height() > avail.bottom()) {
286  menuPos = view->mapToGlobal(view->mapFromScene(parentItem->scenePos() - QPoint(0, m_menu->sizeHint().height())));
287  }
288 
289  m_menu->popup(menuPos);
290  m_status = DialogStatus::Open;
291  emit statusChanged();
292 }
293 
294 void QMenuProxy::close()
295 {
296  m_menu->hide();
297 }
298 
299 void QMenuProxy::markAsClosed()
300 {
301  m_status = DialogStatus::Closed;
302  emit statusChanged();
303 }
304 
305 #include "qmenu.moc"
306 
QAction::setText
void setText(const QString &text)
QList::clear
void clear()
QEvent
QEvent::type
Type type() const
QWidget::updateGeometry
void updateGeometry()
QMenuProxy::triggeredIndex
void triggeredIndex(int index)
qmenu.h
QList::at
const T & at(int i) const
QMenuProxy::status
DialogStatus::Status status() const
QMenu::addAction
void addAction(QAction *action)
QGraphicsItem::sceneBoundingRect
QRectF sceneBoundingRect() const
QWidget::mapToGlobal
QPoint mapToGlobal(const QPoint &pos) const
QMenuProxy::visualParentChanged
void visualParentChanged()
QMenuProxy::actionCount
int actionCount() const
Definition: qmenu.cpp:50
QAction::setMenu
void setMenu(QMenu *menu)
QGraphicsView::sceneRect
sceneRect
QWeakPointer::data
T * data() const
QPoint
DialogStatus::Closed
Definition: enums.h:37
QChildEvent::child
QObject * child() const
DialogStatus::Open
Definition: enums.h:35
QMenuItem
Definition: qmenuitem.h:26
QGraphicsItem::scene
QGraphicsScene * scene() const
QPoint::y
int y() const
QList::size
int size() const
QObject::event
virtual bool event(QEvent *e)
QList::indexOf
int indexOf(const T &value, int from) const
QMenu::clear
void clear()
QRect
QApplication::activeWindow
QWidget * activeWindow()
QList::count
int count(const T &value) const
QMenu::popup
void popup(const QPoint &p, QAction *atAction)
QMenuProxy::action
QMenuItem * action(int) const
Definition: qmenu.cpp:55
QObject
QGraphicsScene::views
QList< QGraphicsView * > views() const
QList::removeAll
int removeAll(const T &value)
QMenuProxy::addMenuItem
Q_INVOKABLE void addMenuItem(const QString &text)
Definition: qmenu.cpp:136
QMenuProxy::~QMenuProxy
~QMenuProxy()
Definition: qmenu.cpp:40
QGraphicsView::mapFromScene
QPoint mapFromScene(const QPointF &point) const
QMenuProxy::triggered
void triggered(QMenuItem *item)
QMenu::sizeHint
virtual QSize sizeHint() const
QString
QList
QWidget::hide
void hide()
QWidget::isActiveWindow
isActiveWindow
DialogStatus
Definition: enums.h:27
QMenuProxy::clearMenuItems
Q_INVOKABLE void clearMenuItems()
Definition: qmenu.cpp:130
QGraphicsObject
QMenuProxy::close
Q_INVOKABLE void close()
Definition: qmenu.cpp:294
QChildEvent
QMenu
QList::contains
bool contains(const T &value) const
QMenuProxy::open
Q_INVOKABLE void open()
Definition: qmenu.cpp:224
QMenuProxy::setVisualParent
void setVisualParent(QObject *parent)
Definition: qmenu.cpp:70
plasmacomponentsplugin.h
QApplication::desktop
QDesktopWidget * desktop()
QGraphicsItem::boundingRect
virtual QRectF boundingRect() const =0
QMenuProxy::event
bool event(QEvent *event)
Definition: qmenu.cpp:97
QAction
QWidget::removeAction
void removeAction(QAction *action)
QSize::height
int height() const
QRect::bottom
int bottom() const
QRectF::height
qreal height() const
QDesktopWidget::availableGeometry
const QRect availableGeometry(int screen) const
QMenuProxy::QMenuProxy
QMenuProxy(QObject *parent=0)
Definition: qmenu.cpp:30
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QMenuProxy::statusChanged
void statusChanged()
QObject::parent
QObject * parent() const
QDeclarativeListProperty
QGraphicsView
QGraphicsItem::scenePos
QPointF scenePos() const
QMenuProxy::content
QDeclarativeListProperty< QMenuItem > content()
DialogStatus::Status
Status
Definition: enums.h:33
QMenuProxy::visualParent
QObject * visualParent() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:08:40 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

PlasmaComponents

Skip menu "PlasmaComponents"
  • Main Page
  • Namespace List
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List

kde-runtime API Reference

Skip menu "kde-runtime API Reference"
  • KCMShell
  • KNotify
  • Plasma Runtime
  •     PlasmaCore
  •     DragAndDrop
  •     PlasmaComponents
  •     PlasmaExtraComponents
  •     QtExtraComponents

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal