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

PlasmaCore

  • sources
  • kde-4.14
  • kde-runtime
  • plasma
  • declarativeimports
  • core
dialog.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2011 Marco Martin <mart@kde.org>
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 "dialog.h"
21 #include "declarativeitemcontainer_p.h"
22 
23 #include <QApplication>
24 #include <QDeclarativeItem>
25 #include <QDesktopWidget>
26 #include <QGraphicsObject>
27 #include <QGraphicsWidget>
28 #include <QTimer>
29 #include <QLayout>
30 
31 #include <KWindowSystem>
32 
33 #include <Plasma/Corona>
34 #include <Plasma/Dialog>
35 #include <Plasma/WindowEffects>
36 
37 
38 int DialogProxy::offscreenX = 0;
39 int DialogProxy::offscreenY = 0;
40 
41 DialogMargins::DialogMargins(Plasma::Dialog *dialog, QObject *parent)
42  : QObject(parent),
43  m_left(0), m_top(0), m_right(0), m_bottom(0),
44  m_dialog(dialog)
45 {
46  checkMargins();
47 }
48 
49 void DialogMargins::checkMargins()
50 {
51  int left, top, right, bottom;
52  m_dialog->getContentsMargins(&left, &top, &right, &bottom);
53 
54  if (left != m_left) {
55  m_left = left;
56  emit leftChanged();
57  }
58  if (top != m_top) {
59  m_top = top;
60  emit topChanged();
61  }
62  if (right != m_right) {
63  m_right = right;
64  emit rightChanged();
65  }
66  if (bottom != m_bottom) {
67  m_bottom = bottom;
68  emit bottomChanged();
69  }
70 }
71 
72 int DialogMargins::left() const
73 {
74  return m_left;
75 }
76 
77 int DialogMargins::top() const
78 {
79  return m_top;
80 }
81 
82 int DialogMargins::right() const
83 {
84  return m_right;
85 }
86 
87 int DialogMargins::bottom() const
88 {
89  return m_bottom;
90 }
91 
92 DialogProxy::DialogProxy(QDeclarativeItem *parent)
93  : QDeclarativeItem(parent),
94  m_declarativeItemContainer(0),
95  m_activeWindow(false),
96  m_location(Plasma::Floating)
97 {
98  m_dialog = new Plasma::Dialog();
99  m_margins = new DialogMargins(m_dialog, this);
100  m_dialog->installEventFilter(this);
101  m_flags = m_dialog->windowFlags();
102 }
103 
104 DialogProxy::~DialogProxy()
105 {
106  delete m_declarativeItemContainer;
107  delete m_dialog;
108 }
109 
110 QGraphicsObject *DialogProxy::mainItem() const
111 {
112  return m_mainItem.data();
113 }
114 
115 void DialogProxy::setMainItem(QGraphicsObject *mainItem)
116 {
117  if (m_mainItem.data() != mainItem) {
118  if (m_mainItem) {
119  m_mainItem.data()->setParent(mainItem ? mainItem->parent() : 0);
120  }
121 
122  m_mainItem = mainItem;
123 
124  if (mainItem) {
125  mainItem->setParentItem(0);
126  mainItem->setParent(this);
127  }
128 
129  //if this is called in Compenent.onCompleted we have to wait a loop the item is added to a scene
130  QTimer::singleShot(0, this, SLOT(syncMainItem()));
131  emit mainItemChanged();
132  }
133 }
134 
135 void DialogProxy::syncMainItem()
136 {
137  if (!m_mainItem) {
138  return;
139  }
140 
141  if (static_cast<QGraphicsObject *>(m_dialog->graphicsWidget()) == m_mainItem.data() ||
142  (m_declarativeItemContainer && m_declarativeItemContainer->declarativeItem() == m_mainItem.data())) {
143  return;
144  }
145 
146  //not have a scene? go up in the hyerarchy until we find something with a scene
147  QGraphicsScene *scene = m_mainItem.data()->scene();
148  if (!scene) {
149  QObject *parent = m_mainItem.data();
150  while ((parent = parent->parent())) {
151  QGraphicsObject *qo = qobject_cast<QGraphicsObject *>(parent);
152  if (qo) {
153  scene = qo->scene();
154  if (scene) {
155  scene->addItem(m_mainItem.data());
156  break;
157  }
158  }
159  }
160  }
161 
162  if (!scene) {
163  return;
164  }
165 
166  //the parent of the qobject never changed, only the parentitem, so put it back what it was
167  m_mainItem.data()->setParentItem(qobject_cast<QGraphicsObject *>(m_mainItem.data()->parent()));
168 
169  QGraphicsWidget *widget = qobject_cast<QGraphicsWidget *>(m_mainItem.data());
170  if (widget) {
171  if (m_declarativeItemContainer) {
172  m_declarativeItemContainer->deleteLater();
173  m_declarativeItemContainer = 0;
174  }
175  } else {
176  QDeclarativeItem *di = qobject_cast<QDeclarativeItem *>(m_mainItem.data());
177  if (di) {
178  if (!m_declarativeItemContainer) {
179  m_declarativeItemContainer = new DeclarativeItemContainer();
180  scene->addItem(m_declarativeItemContainer);
181  }
182  m_declarativeItemContainer->setDeclarativeItem(di);
183  widget = m_declarativeItemContainer;
184  }
185  }
186  m_dialog->setGraphicsWidget(widget);
187 
188  if (!qobject_cast<Plasma::Corona *>(scene)) {
189  offscreenX -= 10000;
190  offscreenY -= 10000;
191  widget->setPos(offscreenX, offscreenY);
192  }
193 }
194 
195 bool DialogProxy::isVisible() const
196 {
197  return m_dialog->isVisible();
198 }
199 
200 void DialogProxy::setVisible(const bool visible)
201 {
202  if (m_dialog->isVisible() != visible) {
203  //FIXME: workaround to prevent dialogs of Popup type disappearing on the second show
204  const QSize s = m_dialog->size();
205  m_dialog->resize(0,0);
206  m_dialog->resize(s);
207 
208  const QRect workArea(KWindowSystem::workArea());
209  if (!workArea.contains(m_dialog->geometry())) {
210  m_dialog->move(qBound(workArea.left(), m_dialog->x(), workArea.right() - m_dialog->width()),
211  qBound(workArea.top(), m_dialog->y(), workArea.bottom() - m_dialog->height())
212  );
213  }
214 
215  m_dialog->setVisible(visible);
216  if (visible && !m_dialog->testAttribute(Qt::WA_X11NetWmWindowTypeDock)) {
217  m_dialog->raise();
218  }
219  }
220 }
221 
222 QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment)
223 {
224  QGraphicsObject *actualItem = item;
225 
226  //if no item is passed search the root item in order to figure out the view
227  if (!actualItem) {
228  actualItem = qobject_cast<QGraphicsObject *>(parent());
229 
230  //search the root object
231  while (true) {
232  QGraphicsObject *ancestor = qobject_cast<QGraphicsObject *>(actualItem->parent());
233 
234  if (ancestor) {
235  actualItem = ancestor;
236  } else {
237  break;
238  }
239  }
240  if (!actualItem) {
241  return QPoint();
242  }
243  }
244 
245  //ensure the dialog has the proper size
246  syncMainItem();
247  m_dialog->syncToGraphicsWidget();
248 
249  Plasma::Corona *corona = qobject_cast<Plasma::Corona *>(actualItem->scene());
250  if (corona && item) {
251  return corona->popupPosition(actualItem, m_dialog->size(), (Qt::AlignmentFlag)alignment);
252  } else {
253 
254  if (!actualItem->scene()) {
255  return QPoint();
256  }
257 
258  QList<QGraphicsView*> views = actualItem->scene()->views();
259 
260 
261  if (views.size() < 1) {
262  return QPoint();
263  }
264 
265  QGraphicsView *view = 0;
266  if (views.size() == 1) {
267  view = views[0];
268  } else {
269  QGraphicsView *found = 0;
270  QGraphicsView *possibleFind = 0;
271 
272  foreach (QGraphicsView *v, views) {
273  if (v->sceneRect().intersects(actualItem->sceneBoundingRect()) ||
274  v->sceneRect().contains(actualItem->scenePos())) {
275  if (v->isActiveWindow()) {
276  found = v;
277  } else {
278  possibleFind = v;
279  }
280  }
281  }
282  view = found ? found : possibleFind;
283  }
284 
285  if (!view) {
286  return QPoint();
287  }
288 
289  //if no item was explicitly specified, align the dialog in the center of the parent view
290  if (!item) {
291  return view->geometry().center() - QPoint(m_dialog->width()/2, m_dialog->height()/2);
292  }
293 
294  //swap direction if necessary
295  if (QApplication::isRightToLeft() && alignment != Qt::AlignCenter) {
296  if (alignment == Qt::AlignRight) {
297  alignment = Qt::AlignLeft;
298  } else {
299  alignment = Qt::AlignRight;
300  }
301  }
302 
303  int xOffset = 0;
304 
305  if (alignment == Qt::AlignCenter) {
306  xOffset = actualItem->boundingRect().width()/2 - m_dialog->width()/2;
307  } else if (alignment == Qt::AlignRight) {
308  xOffset = actualItem->boundingRect().width() - m_dialog->width();
309  }
310 
311  const QRect avail = QApplication::desktop()->availableGeometry(view);
312  QPoint menuPos = view->mapToGlobal(view->mapFromScene(actualItem->scenePos()+QPoint(xOffset, actualItem->boundingRect().height())));
313 
314  if (menuPos.y() + m_dialog->height() > avail.bottom()) {
315  menuPos = view->mapToGlobal(view->mapFromScene(actualItem->scenePos() - QPoint(-xOffset, m_dialog->height())));
316  }
317  return menuPos;
318  }
319 }
320 
321 
322 int DialogProxy::x() const
323 {
324  return m_dialog->pos().x();
325 }
326 
327 void DialogProxy::setX(int x)
328 {
329  m_dialog->move(x, m_dialog->pos().y());
330 }
331 
332 int DialogProxy::y() const
333 {
334  return m_dialog->pos().y();
335 }
336 
337 void DialogProxy::setY(int y)
338 {
339  m_dialog->move(m_dialog->pos().x(), y);
340 }
341 
342 int DialogProxy::width() const
343 {
344  return m_dialog->size().width();
345 }
346 
347 int DialogProxy::height() const
348 {
349  return m_dialog->size().height();
350 }
351 
352 bool DialogProxy::isActiveWindow() const
353 {
354  return m_activeWindow;
355 }
356 
357 void DialogProxy::activateWindow()
358 {
359  m_dialog->activateWindow();
360 }
361 
362 int DialogProxy::windowFlags() const
363 {
364  return (int)m_flags;
365 }
366 
367 #ifndef Q_WS_WIN
368 qulonglong DialogProxy::windowId() const
369 {
370  return m_dialog->winId();
371 }
372 #endif
373 
374 void DialogProxy::setWindowFlags(const int flags)
375 {
376  m_flags = (Qt::WindowFlags)flags;
377  m_dialog->setWindowFlags(Qt::FramelessWindowHint|m_flags);
378 }
379 
380 int DialogProxy::location() const
381 {
382  return (int)m_location;
383 }
384 
385 void DialogProxy::setLocation(int location)
386 {
387  if (m_location == location) {
388  return;
389  }
390  m_location = (Plasma::Location)location;
391  emit locationChanged();
392 }
393 
394 
395 QObject *DialogProxy::margins() const
396 {
397  return m_margins;
398 }
399 
400 bool DialogProxy::eventFilter(QObject *watched, QEvent *event)
401 {
402  if (watched == m_dialog && event->type() == QEvent::Move) {
403  QMoveEvent *me = static_cast<QMoveEvent *>(event);
404  if (me->oldPos().x() != me->pos().x()) {
405  emit xChanged();
406  }
407  if (me->oldPos().y() != me->pos().y()) {
408  emit yChanged();
409  }
410  if ((me->oldPos().x() != me->pos().x()) || (me->oldPos().y() != me->pos().y())) {
411  m_margins->checkMargins();
412  }
413  } else if (watched == m_dialog && event->type() == QEvent::Resize) {
414  QResizeEvent *re = static_cast<QResizeEvent *>(event);
415  if (re->oldSize().width() != re->size().width()) {
416  emit widthChanged();
417  }
418  if (re->oldSize().height() != re->size().height()) {
419  emit heightChanged();
420  }
421  } else if (watched == m_dialog && event->type() == QEvent::Show) {
422  Plasma::WindowEffects::slideWindow(m_dialog, m_location);
423  if (m_dialog->testAttribute(Qt::WA_X11NetWmWindowTypeDock)) {
424  KWindowSystem::setOnAllDesktops(m_dialog->winId(), true);
425  } else {
426  KWindowSystem::setOnAllDesktops(m_dialog->winId(), false);
427  }
428  emit visibleChanged();
429  } else if (watched == m_dialog && event->type() == QEvent::Hide) {
430  Plasma::WindowEffects::slideWindow(m_dialog, m_location);
431  emit visibleChanged();
432  } else if (watched == m_dialog && event->type() == QEvent::WindowActivate) {
433  m_activeWindow = true;
434  emit activeWindowChanged();
435  } else if (watched == m_dialog && event->type() == QEvent::WindowDeactivate) {
436  m_activeWindow = false;
437  emit activeWindowChanged();
438  }
439  return false;
440 }
441 
442 void DialogProxy::setAttribute(int attribute, bool on)
443 {
444  m_dialog->setAttribute((Qt::WidgetAttribute)attribute, on);
445 
446  if (attribute == Qt::WA_X11NetWmWindowTypeDock) {
447  KWindowSystem::setOnAllDesktops(m_dialog->winId(), on);
448  }
449 }
450 
451 #include "dialog.moc"
452 
QMoveEvent::pos
const QPoint & pos() const
DeclarativeItemContainer::setDeclarativeItem
void setDeclarativeItem(QDeclarativeItem *item, bool reparent=true)
Definition: declarativeitemcontainer.cpp:33
QEvent
QResizeEvent
QApplication::isRightToLeft
bool isRightToLeft()
QEvent::type
Type type() const
DeclarativeItemContainer
Definition: declarativeitemcontainer_p.h:29
QGraphicsScene
QSize::width
int width() const
QMoveEvent
DialogProxy::activateWindow
Q_INVOKABLE void activateWindow()
Ask the window manager to activate the window.
Definition: dialog.cpp:357
DialogMargins::DialogMargins
DialogMargins(Plasma::Dialog *dialog, QObject *parent=0)
Definition: dialog.cpp:41
DialogProxy::popupPosition
Q_INVOKABLE QPoint popupPosition(QGraphicsObject *item, int alignment=Qt::AlignLeft)
Definition: dialog.cpp:222
QRect::right
int right() const
DialogMargins::checkMargins
void checkMargins()
Definition: dialog.cpp:49
QGraphicsItem::setParentItem
void setParentItem(QGraphicsItem *newParent)
DialogProxy::setLocation
void setLocation(int location)
Definition: dialog.cpp:385
DialogProxy::syncMainItem
void syncMainItem()
Definition: dialog.cpp:135
DialogProxy::x
int x() const
DialogProxy::windowId
qulonglong windowId() const
DialogProxy::~DialogProxy
~DialogProxy()
Definition: dialog.cpp:104
DialogProxy::widthChanged
void widthChanged()
QGraphicsItem::sceneBoundingRect
QRectF sceneBoundingRect() const
QWidget::mapToGlobal
QPoint mapToGlobal(const QPoint &pos) const
QMoveEvent::oldPos
const QPoint & oldPos() const
DialogProxy::height
int height() const
DialogProxy::setAttribute
Q_INVOKABLE void setAttribute(int attribute, bool on)
Set a Qt.WidgetAttribute to the dialog window.
Definition: dialog.cpp:442
QGraphicsView::sceneRect
sceneRect
QWeakPointer::data
T * data() const
DialogMargins::bottomChanged
void bottomChanged()
DialogProxy::visibleChanged
void visibleChanged()
QPoint
DialogProxy::mainItem
QGraphicsObject * mainItem() const
QGraphicsItem::scene
QGraphicsScene * scene() const
DialogProxy::margins
QObject * margins() const
QPoint::x
int x() const
QPoint::y
int y() const
QList::size
int size() const
QWidget::geometry
geometry
DialogMargins::bottom
int bottom() const
QObject::event
virtual bool event(QEvent *e)
DialogProxy::yChanged
void yChanged()
QRect
QRect::top
int top() const
QObject
QGraphicsItem::setPos
void setPos(const QPointF &pos)
QRect::left
int left() const
QResizeEvent::oldSize
const QSize & oldSize() const
QGraphicsScene::views
QList< QGraphicsView * > views() const
QGraphicsWidget
QGraphicsView::mapFromScene
QPoint mapFromScene(const QPointF &point) const
QObject::deleteLater
void deleteLater()
QRect::contains
bool contains(const QPoint &point, bool proper) const
QList
DialogProxy::activeWindowChanged
void activeWindowChanged()
QWidget::isActiveWindow
isActiveWindow
DialogProxy::heightChanged
void heightChanged()
QGraphicsObject
DialogProxy::isActiveWindow
bool isActiveWindow() const
Definition: dialog.cpp:352
DeclarativeItemContainer::declarativeItem
QDeclarativeItem * declarativeItem() const
Definition: declarativeitemcontainer.cpp:109
DialogProxy::y
int y() const
QResizeEvent::size
const QSize & size() const
QObject::setParent
void setParent(QObject *parent)
QSize
DialogProxy::mainItemChanged
void mainItemChanged()
DialogProxy::xChanged
void xChanged()
DialogProxy::setWindowFlags
void setWindowFlags(const int)
Definition: dialog.cpp:374
DialogProxy::setMainItem
void setMainItem(QGraphicsObject *mainItem)
Definition: dialog.cpp:115
DialogMargins::leftChanged
void leftChanged()
DialogProxy::setX
void setX(int x)
Definition: dialog.cpp:327
QRectF::width
qreal width() const
dialog.h
QGraphicsObject::parent
parent
DialogMargins::top
int top() const
QApplication::desktop
QDesktopWidget * desktop()
QGraphicsItem::boundingRect
virtual QRectF boundingRect() const =0
DialogProxy::locationChanged
void locationChanged()
DialogProxy::isVisible
bool isVisible() const
Definition: dialog.cpp:195
QSize::height
int height() const
DialogProxy::windowFlags
int windowFlags() const
QRect::bottom
int bottom() const
DialogMargins
Definition: dialog.h:38
declarativeitemcontainer_p.h
DialogProxy::eventFilter
bool eventFilter(QObject *watched, QEvent *event)
Definition: dialog.cpp:400
DialogProxy::setY
void setY(int y)
Definition: dialog.cpp:337
DialogMargins::left
int left() const
QRectF::height
qreal height() const
Qt::WindowFlags
typedef WindowFlags
QDesktopWidget::availableGeometry
const QRect availableGeometry(int screen) const
QDeclarativeItem
DialogProxy::width
int width() const
QGraphicsScene::addItem
void addItem(QGraphicsItem *item)
QObject::parent
QObject * parent() const
DialogProxy::setVisible
void setVisible(const bool visible)
Definition: dialog.cpp:200
DialogMargins::right
int right() const
DialogProxy::visible
bool visible
Visibility of the Dialog window.
Definition: dialog.h:105
QGraphicsView
QGraphicsItem::scenePos
QPointF scenePos() const
DialogMargins::rightChanged
void rightChanged()
DialogProxy::DialogProxy
DialogProxy(QDeclarativeItem *parent=0)
Definition: dialog.cpp:92
DialogProxy::location
int location() const
DialogMargins::topChanged
void topChanged()
QTimer::singleShot
singleShot
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:08:28 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

PlasmaCore

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

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