1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the Qt Labs Platform module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL3$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#include "qquickplatformdialog_p.h"
38
39#include <QtCore/qloggingcategory.h>
40#include <QtGui/private/qguiapplication_p.h>
41#include <QtQuick/qquickitem.h>
42#include <QtQuick/qquickwindow.h>
43
44#include "widgets/qwidgetplatform_p.h"
45
46QT_BEGIN_NAMESPACE
47
48/*!
49 \qmltype Dialog
50 \inherits QtObject
51//! \instantiates QQuickPlatformDialog
52 \inqmlmodule Qt.labs.platform
53 \since 5.8
54 \brief The base class of native dialogs.
55
56 The Dialog type provides common QML API for native platform dialogs.
57
58 To show a native dialog, construct an instance of one of the concrete
59 Dialog implementations, set the desired properties, and call \l open().
60 Dialog emits \l accepted() or \l rejected() when the user is done with
61 the dialog.
62
63 \labs
64*/
65
66/*!
67 \qmlsignal void Qt.labs.platform::Dialog::accepted()
68
69 This signal is emitted when the dialog has been accepted either
70 interactively or by calling \l accept().
71
72 \note This signal is \e not emitted when closing the dialog with \l close().
73
74 \sa rejected()
75*/
76
77/*!
78 \qmlsignal void Qt.labs.platform::Dialog::rejected()
79
80 This signal is emitted when the dialog has been rejected either
81 interactively or by calling \l reject().
82
83 \note This signal is \e not emitted when closing the dialog with \l close().
84
85 \sa accepted()
86*/
87
88Q_DECLARE_LOGGING_CATEGORY(qtLabsPlatformDialogs)
89
90QQuickPlatformDialog::QQuickPlatformDialog(QPlatformTheme::DialogType type, QObject *parent)
91 : QObject(parent),
92 m_visible(false),
93 m_complete(false),
94 m_result(0),
95 m_parentWindow(nullptr),
96 m_flags(Qt::Dialog),
97 m_modality(Qt::WindowModal),
98 m_type(type),
99 m_handle(nullptr)
100{
101}
102
103QQuickPlatformDialog::~QQuickPlatformDialog()
104{
105 destroy();
106}
107
108QPlatformDialogHelper *QQuickPlatformDialog::handle() const
109{
110 return m_handle;
111}
112
113/*!
114 \default
115 \qmlproperty list<Object> Qt.labs.platform::Dialog::data
116
117 This default property holds the list of all objects declared as children of
118 the dialog.
119*/
120QQmlListProperty<QObject> QQuickPlatformDialog::data()
121{
122 return QQmlListProperty<QObject>(this, &m_data);
123}
124
125/*!
126 \qmlproperty Window Qt.labs.platform::Dialog::parentWindow
127
128 This property holds the parent window of the dialog.
129
130 Unless explicitly set, the window is automatically resolved by iterating
131 the QML parent objects until a \l Window or an \l Item that has a window
132 is found.
133*/
134QWindow *QQuickPlatformDialog::parentWindow() const
135{
136 return m_parentWindow;
137}
138
139void QQuickPlatformDialog::setParentWindow(QWindow *window)
140{
141 if (m_parentWindow == window)
142 return;
143
144 m_parentWindow = window;
145 emit parentWindowChanged();
146}
147
148/*!
149 \qmlproperty string Qt.labs.platform::Dialog::title
150
151 This property holds the title of the dialog.
152*/
153QString QQuickPlatformDialog::title() const
154{
155 return m_title;
156}
157
158void QQuickPlatformDialog::setTitle(const QString &title)
159{
160 if (m_title == title)
161 return;
162
163 m_title = title;
164 emit titleChanged();
165}
166
167/*!
168 \qmlproperty Qt::WindowFlags Qt.labs.platform::Dialog::flags
169
170 This property holds the window flags of the dialog. The default value is \c Qt.Dialog.
171*/
172Qt::WindowFlags QQuickPlatformDialog::flags() const
173{
174 return m_flags;
175}
176
177void QQuickPlatformDialog::setFlags(Qt::WindowFlags flags)
178{
179 if (m_flags == flags)
180 return;
181
182 m_flags = flags;
183 emit flagsChanged();
184}
185
186/*!
187 \qmlproperty Qt::WindowModality Qt.labs.platform::Dialog::modality
188
189 This property holds the modality of the dialog. The default value is \c Qt.WindowModal.
190
191 Available values:
192 \value Qt.NonModal The dialog is not modal and does not block input to other windows.
193 \value Qt.WindowModal The dialog is modal to a single window hierarchy and blocks input to its parent window, all grandparent windows, and all siblings of its parent and grandparent windows.
194 \value Qt.ApplicationModal The dialog is modal to the application and blocks input to all windows.
195*/
196Qt::WindowModality QQuickPlatformDialog::modality() const
197{
198 return m_modality;
199}
200
201void QQuickPlatformDialog::setModality(Qt::WindowModality modality)
202{
203 if (m_modality == modality)
204 return;
205
206 m_modality = modality;
207 emit modalityChanged();
208}
209
210/*!
211 \qmlproperty bool Qt.labs.platform::Dialog::visible
212
213 This property holds the visibility of the dialog. The default value is \c false.
214
215 \sa open(), close()
216*/
217bool QQuickPlatformDialog::isVisible() const
218{
219 return m_handle && m_visible;
220}
221
222void QQuickPlatformDialog::setVisible(bool visible)
223{
224 if (visible)
225 open();
226 else
227 close();
228}
229
230/*!
231 \qmlproperty int Qt.labs.platform::Dialog::result
232
233 This property holds the result code.
234
235 Standard result codes:
236 \value Dialog.Accepted
237 \value Dialog.Rejected
238
239 \note MessageDialog sets the result to the value of the clicked standard
240 button instead of using the standard result codes.
241*/
242int QQuickPlatformDialog::result() const
243{
244 return m_result;
245}
246
247void QQuickPlatformDialog::setResult(int result)
248{
249 if (m_result == result)
250 return;
251
252 m_result = result;
253 emit resultChanged();
254}
255
256/*!
257 \qmlmethod void Qt.labs.platform::Dialog::open()
258
259 Opens the dialog.
260
261 \sa visible, close()
262*/
263void QQuickPlatformDialog::open()
264{
265 if (m_visible || !create())
266 return;
267
268 onShow(dialog: m_handle);
269 m_visible = m_handle->show(windowFlags: m_flags, windowModality: m_modality, parent: m_parentWindow);
270 if (m_visible)
271 emit visibleChanged();
272}
273
274/*!
275 \qmlmethod void Qt.labs.platform::Dialog::close()
276
277 Closes the dialog.
278
279 \sa visible, open()
280*/
281void QQuickPlatformDialog::close()
282{
283 if (!m_handle || !m_visible)
284 return;
285
286 onHide(dialog: m_handle);
287 m_handle->hide();
288 m_visible = false;
289 emit visibleChanged();
290}
291
292/*!
293 \qmlmethod void Qt.labs.platform::Dialog::accept()
294
295 Closes the dialog and emits the \l accepted() signal.
296
297 \sa reject()
298*/
299void QQuickPlatformDialog::accept()
300{
301 done(result: Accepted);
302}
303
304/*!
305 \qmlmethod void Qt.labs.platform::Dialog::reject()
306
307 Closes the dialog and emits the \l rejected() signal.
308
309 \sa accept()
310*/
311void QQuickPlatformDialog::reject()
312{
313 done(result: Rejected);
314}
315
316/*!
317 \qmlmethod void Qt.labs.platform::Dialog::done(int result)
318
319 Closes the dialog and sets the \a result.
320
321 \sa accept(), reject(), result
322*/
323void QQuickPlatformDialog::done(int result)
324{
325 close();
326 setResult(result);
327
328 if (result == Accepted)
329 emit accepted();
330 else if (result == Rejected)
331 emit rejected();
332}
333
334void QQuickPlatformDialog::classBegin()
335{
336}
337
338void QQuickPlatformDialog::componentComplete()
339{
340 m_complete = true;
341 if (!m_parentWindow)
342 setParentWindow(findParentWindow());
343}
344
345static const char *qmlTypeName(const QObject *object)
346{
347 return object->metaObject()->className() + qstrlen(str: "QQuickPlatform");
348}
349
350bool QQuickPlatformDialog::create()
351{
352 if (!m_handle) {
353 if (useNativeDialog())
354 m_handle = QGuiApplicationPrivate::platformTheme()->createPlatformDialogHelper(type: m_type);
355 if (!m_handle)
356 m_handle = QWidgetPlatform::createDialog(type: m_type, parent: this);
357 qCDebug(qtLabsPlatformDialogs) << qmlTypeName(object: this) << "->" << m_handle;
358 if (m_handle) {
359 onCreate(dialog: m_handle);
360 connect(sender: m_handle, signal: &QPlatformDialogHelper::accept, receiver: this, slot: &QQuickPlatformDialog::accept);
361 connect(sender: m_handle, signal: &QPlatformDialogHelper::reject, receiver: this, slot: &QQuickPlatformDialog::reject);
362 }
363 }
364 return m_handle;
365}
366
367void QQuickPlatformDialog::destroy()
368{
369 delete m_handle;
370 m_handle = nullptr;
371}
372
373bool QQuickPlatformDialog::useNativeDialog() const
374{
375 return !QCoreApplication::testAttribute(attribute: Qt::AA_DontUseNativeDialogs)
376 && QGuiApplicationPrivate::platformTheme()->usePlatformNativeDialog(type: m_type);
377}
378
379void QQuickPlatformDialog::onCreate(QPlatformDialogHelper *dialog)
380{
381 Q_UNUSED(dialog);
382}
383
384void QQuickPlatformDialog::onShow(QPlatformDialogHelper *dialog)
385{
386 Q_UNUSED(dialog);
387}
388
389void QQuickPlatformDialog::onHide(QPlatformDialogHelper *dialog)
390{
391 Q_UNUSED(dialog);
392}
393
394QWindow *QQuickPlatformDialog::findParentWindow() const
395{
396 QObject *obj = parent();
397 while (obj) {
398 QWindow *window = qobject_cast<QWindow *>(o: obj);
399 if (window)
400 return window;
401 QQuickItem *item = qobject_cast<QQuickItem *>(object: obj);
402 if (item && item->window())
403 return item->window();
404 obj = obj->parent();
405 }
406 return nullptr;
407}
408
409QT_END_NAMESPACE
410

source code of qtquickcontrols2/src/imports/platform/qquickplatformdialog.cpp