KWidgetsAddons

kpopupframe.cpp
1 /* -*- C++ -*-
2  This file is part of the KDE libraries
3  SPDX-FileCopyrightText: 1997 Tim D. Gilman <[email protected]>
4  SPDX-FileCopyrightText: 1998-2001 Mirko Boehm <[email protected]>
5  SPDX-FileCopyrightText: 2007 John Layt <[email protected]>
6 
7  SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9 
10 #include "kpopupframe.h"
11 
12 #include <QDesktopWidget>
13 #include <QEventLoop>
14 #include <QGuiApplication>
15 #include <QKeyEvent>
16 #include <QScreen>
17 
18 class Q_DECL_HIDDEN KPopupFrame::KPopupFramePrivate
19 {
20 public:
21  KPopupFramePrivate(KPopupFrame *q);
22  ~KPopupFramePrivate();
23 
24  KPopupFrame *q;
25 
29  int result;
30 
34  QWidget *main;
35 
36  // ### KDE 5: Remove this, add a hideEvent() reimplementation instead.
37  class OutsideClickCatcher;
38  OutsideClickCatcher *outsideClickCatcher;
39 };
40 
41 class KPopupFrame::KPopupFramePrivate::OutsideClickCatcher
42  : public QObject
43 {
44  Q_OBJECT
45 public:
46  explicit OutsideClickCatcher(QObject *parent = nullptr)
47  : QObject(parent), m_popup(nullptr) { }
48  ~OutsideClickCatcher() override { }
49 
50  void setPopupFrame(KPopupFrame *popup)
51  {
52  m_popup = popup;
53  popup->installEventFilter(this);
54  }
55 
56  KPopupFrame *m_popup;
57 
58  bool eventFilter(QObject *object, QEvent *event) override
59  {
60  Q_UNUSED(object);
61 
62  // To catch outside clicks, it is sufficient to check for
63  // hide events on Qt::Popup type widgets
64  if (event->type() == QEvent::Hide && m_popup) {
65  // do not set d->result here, because the popup
66  // hides itself after leaving the event loop.
67  emit m_popup->leaveModality();
68  }
69  return false;
70  }
71 };
72 
73 KPopupFrame::KPopupFramePrivate::KPopupFramePrivate(KPopupFrame *q):
74  q(q),
75  result(0), // rejected
76  main(nullptr),
77  outsideClickCatcher(new OutsideClickCatcher)
78 {
79  outsideClickCatcher->setPopupFrame(q);
80 }
81 
82 KPopupFrame::KPopupFramePrivate::~KPopupFramePrivate()
83 {
84  delete outsideClickCatcher;
85 }
86 
88  : QFrame(parent, Qt::Popup), d(new KPopupFramePrivate(this))
89 {
91  setMidLineWidth(2);
92 }
93 
95 {
96  delete d;
97 }
98 
100 {
101  if (e->key() == Qt::Key_Escape) {
102  d->result = 0; // rejected
103  emit leaveModality();
104  //qApp->exit_loop();
105  }
106 }
107 
109 {
111 }
112 
114 {
115  d->result = r;
116  emit leaveModality();
117  //qApp->exit_loop();
118 }
119 
121 {
122  d->main = m;
123  if (d->main) {
124  resize(d->main->width() + 2 * frameWidth(), d->main->height() + 2 * frameWidth());
125  }
126 }
127 
129 {
130  Q_UNUSED(e);
131 
132  if (d->main) {
133  d->main->setGeometry(frameWidth(), frameWidth(),
134  width() - 2 * frameWidth(), height() - 2 * frameWidth());
135  }
136 }
137 
139 {
140  // Make sure the whole popup is visible.
142 
143  int x = pos.x();
144  int y = pos.y();
145  int w = width();
146  int h = height();
147  if (screen) {
148  const QRect desktopGeometry = screen->geometry();
149  if (x + w > desktopGeometry.x() + desktopGeometry.width()) {
150  x = desktopGeometry.width() - w;
151  }
152  if (y + h > desktopGeometry.y() + desktopGeometry.height()) {
153  y = desktopGeometry.height() - h;
154  }
155  if (x < desktopGeometry.x()) {
156  x = 0;
157  }
158  if (y < desktopGeometry.y()) {
159  y = 0;
160  }
161  }
162 
163  // Pop the thingy up.
164  move(x, y);
165  show();
166  d->main->setFocus();
167 }
168 
170 {
171  popup(pos);
172  repaint();
173  d->result = 0; // rejected
174  QEventLoop eventLoop;
175  connect(this, &KPopupFrame::leaveModality,
176  &eventLoop, &QEventLoop::quit);
177  eventLoop.exec();
178 
179  hide();
180  return d->result;
181 }
182 
183 int KPopupFrame::exec(int x, int y)
184 {
185  return exec(QPoint(x, y));
186 }
187 
188 #include "kpopupframe.moc"
void resize(int w, int h)
bool close()
QEvent::Type type() const const
void quit()
void popup(const QPoint &pos)
Open the popup window at position pos.
QScreen * screenAt(const QPoint &point)
int y() const const
void resizeEvent(QResizeEvent *resize) override
The resize event.
int height() const const
int x() const const
int y() const const
QScreen * screen() const const
void setFrameStyle(int style)
int x() const const
int y() const const
int width() const const
void installEventFilter(QObject *filterObj)
void hideEvent(QHideEvent *e) override
Catch hide events.
int x() const const
int exec(QEventLoop::ProcessEventsFlags flags)
virtual void hideEvent(QHideEvent *event)
QPoint pos() const const
KPopupFrame(QWidget *parent=nullptr)
The contructor.
Definition: kpopupframe.cpp:87
int exec(const QPoint &p)
Execute the popup window.
void hide()
~KPopupFrame()
The destructor.
Definition: kpopupframe.cpp:94
void setMidLineWidth(int)
int key() const const
void move(int x, int y)
void repaint()
int width() const const
int frameWidth() const const
Frame with popup menu behavior.
Definition: kpopupframe.h:23
void show()
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
Key_Escape
void keyPressEvent(QKeyEvent *e) override
Catch key press events.
Definition: kpopupframe.cpp:99
int height() const const
void setMainWidget(QWidget *m)
Set the main widget.
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Wed Aug 5 2020 22:42:24 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.