Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qiosmessagedialog.mm
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#import <UIKit/UIKit.h>
6
7#include <QtGui/qwindow.h>
8#include <QtGui/private/qguiapplication_p.h>
9#include <qpa/qplatformtheme.h>
10
11#include <QtCore/private/qcore_mac_p.h>
12
13#include "qiosglobal.h"
14#include "quiview.h"
15#include "qiosscreen.h"
17
18using namespace Qt::StringLiterals;
19
20QIOSMessageDialog::QIOSMessageDialog()
21 : m_alertController(nullptr)
22{
23}
24
25QIOSMessageDialog::~QIOSMessageDialog()
26{
27 hide();
28}
29
30inline QString QIOSMessageDialog::messageTextPlain()
31{
32 // Concatenate text fragments, and remove HTML tags
33 const QSharedPointer<QMessageDialogOptions> &opt = options();
34 constexpr auto lineShift = "\n\n"_L1;
35 const QString &informativeText = opt->informativeText();
36 const QString &detailedText = opt->detailedText();
37
38 QString text = opt->text();
39 if (!informativeText.isEmpty())
40 text += lineShift + informativeText;
41 if (!detailedText.isEmpty())
42 text += lineShift + detailedText;
43
44 text.replace("<p>"_L1, "\n"_L1, Qt::CaseInsensitive);
45 text.remove(QRegularExpression(QStringLiteral("<[^>]*>")));
46
47 return text;
48}
49
50inline UIAlertAction *QIOSMessageDialog::createAction(
51 const QMessageDialogOptions::CustomButton &customButton)
52{
53 const QString label = QPlatformTheme::removeMnemonics(customButton.label);
54 const UIAlertActionStyle style = UIAlertActionStyleDefault;
55
56 return [UIAlertAction actionWithTitle:label.toNSString() style:style handler:^(UIAlertAction *) {
57 hide();
58 emit clicked(static_cast<QPlatformDialogHelper::StandardButton>(customButton.id), customButton.role);
59 }];
60}
61
62inline UIAlertAction *QIOSMessageDialog::createAction(StandardButton button)
63{
64 const StandardButton labelButton = button == NoButton ? Ok : button;
65 const QString &standardLabel = QGuiApplicationPrivate::platformTheme()->standardButtonText(labelButton);
66 const QString &label = QPlatformTheme::removeMnemonics(standardLabel);
67
68 UIAlertActionStyle style = UIAlertActionStyleDefault;
69 if (button == Cancel)
70 style = UIAlertActionStyleCancel;
71 else if (button == Discard)
72 style = UIAlertActionStyleDestructive;
73
74 return [UIAlertAction actionWithTitle:label.toNSString() style:style handler:^(UIAlertAction *) {
75 hide();
76 if (button == NoButton)
77 emit reject();
78 else
79 emit clicked(button, buttonRole(button));
80 }];
81}
82
83void QIOSMessageDialog::exec()
84{
85 m_eventLoop.exec(QEventLoop::DialogExec);
86}
87
88bool QIOSMessageDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
89{
90 Q_UNUSED(windowFlags);
91 if (m_alertController // Ensure that the dialog is not showing already
92 || !options() // Some message dialogs don't have options (QErrorMessage)
93 || windowModality == Qt::NonModal) // We can only do modal dialogs
94 return false;
95
96 if (!options()->checkBoxLabel().isNull())
97 return false; // Can't support
98
99 m_alertController = [[UIAlertController
100 alertControllerWithTitle:options()->windowTitle().toNSString()
101 message:messageTextPlain().toNSString()
102 preferredStyle:UIAlertControllerStyleAlert] retain];
103
104 const QVector<QMessageDialogOptions::CustomButton> customButtons = options()->customButtons();
105 for (const QMessageDialogOptions::CustomButton &button : customButtons) {
106 UIAlertAction *act = createAction(button);
107 [m_alertController addAction:act];
108 }
109
110 if (StandardButtons buttons = options()->standardButtons()) {
111 for (int i = FirstButton; i < LastButton; i<<=1) {
112 if (i & buttons)
113 [m_alertController addAction:createAction(StandardButton(i))];
114 }
115 } else if (customButtons.isEmpty()) {
116 // We need at least one button to allow the user close the dialog
117 [m_alertController addAction:createAction(NoButton)];
118 }
119
120 UIWindow *window = presentationWindow(parent);
121 if (!window)
122 return false;
123
124 if (window.hidden) {
125 // With a window hidden, an attempt to present view controller
126 // below fails with a warning, that a view "is not a part of
127 // any view hierarchy". The UIWindow is initially hidden,
128 // as unhiding it is what hides the splash screen.
129 window.hidden = NO;
130 }
131
132 [window.rootViewController presentViewController:m_alertController animated:YES completion:nil];
133 return true;
134}
135
136void QIOSMessageDialog::hide()
137{
138 m_eventLoop.exit();
139 [m_alertController dismissViewControllerAnimated:YES completion:nil];
140 [m_alertController release];
141 m_alertController = nullptr;
142}
#define QStringLiteral(str)
Definition qstring.h:1826