KWidgetsAddons

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

KDE's Doxygen guidelines are available online.