Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
4#import <UIKit/UIKit.h>
5
6#include <QtGui/qwindow.h>
7#include <QtGui/private/qguiapplication_p.h>
8#include <qpa/qplatformtheme.h>
9
10#include <QtCore/private/qcore_mac_p.h>
11
12#include "qiosglobal.h"
13#include "quiview.h"
14#include "qiosscreen.h"
15#include "qiosmessagedialog.h"
16
17using namespace Qt::StringLiterals;
18
20 : m_alertController(nullptr)
21{
22}
23
28
29inline QString QIOSMessageDialog::messageTextPlain()
30{
31 // Concatenate text fragments, and remove HTML tags
32 const QSharedPointer<QMessageDialogOptions> &opt = options();
33 constexpr auto lineShift = "\n\n"_L1;
34 const QString &informativeText = opt->informativeText();
35 const QString &detailedText = opt->detailedText();
36
37 QString text = opt->text();
38 if (!informativeText.isEmpty())
39 text += lineShift + informativeText;
40 if (!detailedText.isEmpty())
41 text += lineShift + detailedText;
42
43 text.replace("<p>"_L1, "\n"_L1, Qt::CaseInsensitive);
45
46 return text;
47}
48
49inline UIAlertAction *QIOSMessageDialog::createAction(
50 const QMessageDialogOptions::CustomButton &customButton)
51{
53 const UIAlertActionStyle style = UIAlertActionStyleDefault;
54
55 return [UIAlertAction actionWithTitle:label.toNSString() style:style handler:^(UIAlertAction *) {
56 hide();
57 emit clicked(static_cast<QPlatformDialogHelper::StandardButton>(customButton.id), customButton.role);
58 }];
59}
60
61inline UIAlertAction *QIOSMessageDialog::createAction(StandardButton button)
62{
63 const StandardButton labelButton = button == NoButton ? Ok : button;
64 const QString &standardLabel = QGuiApplicationPrivate::platformTheme()->standardButtonText(labelButton);
65 const QString &label = QPlatformTheme::removeMnemonics(standardLabel);
66
67 UIAlertActionStyle style = UIAlertActionStyleDefault;
68 if (button == Cancel)
69 style = UIAlertActionStyleCancel;
70 else if (button == Discard)
71 style = UIAlertActionStyleDestructive;
72
73 return [UIAlertAction actionWithTitle:label.toNSString() style:style handler:^(UIAlertAction *) {
74 hide();
75 if (button == NoButton)
76 emit reject();
77 else
79 }];
80}
81
83{
84 m_eventLoop.exec(QEventLoop::DialogExec);
85}
86
87bool QIOSMessageDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
88{
89 Q_UNUSED(windowFlags);
90 if (m_alertController // Ensure that the dialog is not showing already
91 || !options() // Some message dialogs don't have options (QErrorMessage)
92 || windowModality == Qt::NonModal) // We can only do modal dialogs
93 return false;
94
95 if (!options()->checkBoxLabel().isNull())
96 return false; // Can't support
97
98 m_alertController = [[UIAlertController
99 alertControllerWithTitle:options()->windowTitle().toNSString()
100 message:messageTextPlain().toNSString()
101 preferredStyle:UIAlertControllerStyleAlert] retain];
102
103 const QVector<QMessageDialogOptions::CustomButton> customButtons = options()->customButtons();
104 for (const QMessageDialogOptions::CustomButton &button : customButtons) {
105 UIAlertAction *act = createAction(button);
106 [m_alertController addAction:act];
107 }
108
109 if (StandardButtons buttons = options()->standardButtons()) {
110 for (int i = FirstButton; i < LastButton; i<<=1) {
111 if (i & buttons)
112 [m_alertController addAction:createAction(StandardButton(i))];
113 }
114 } else if (customButtons.isEmpty()) {
115 // We need at least one button to allow the user close the dialog
116 [m_alertController addAction:createAction(NoButton)];
117 }
118
119 UIWindow *window = presentationWindow(parent);
120 if (!window)
121 return false;
122
123 if (window.hidden) {
124 // With a window hidden, an attempt to present view controller
125 // below fails with a warning, that a view "is not a part of
126 // any view hierarchy". The UIWindow is initially hidden,
127 // as unhiding it is what hides the splash screen.
128 window.hidden = NO;
129 }
130
131 [window.rootViewController presentViewController:m_alertController animated:YES completion:nil];
132 return true;
133}
134
136{
137 m_eventLoop.exit();
138 [m_alertController dismissViewControllerAnimated:YES completion:nil];
139 [m_alertController release];
140 m_alertController = nullptr;
141}
int exec(ProcessEventsFlags flags=AllEvents)
Enters the main event loop and waits until exit() is called.
void exit(int returnCode=0)
Tells the event loop to exit with a return code.
static QPlatformTheme * platformTheme()
void exec() override
bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override
const QList< CustomButton > & customButtons()
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
static ButtonRole buttonRole(StandardButton button)
const QSharedPointer< QMessageDialogOptions > & options() const
void clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role)
static QString removeMnemonics(const QString &original)
\inmodule QtCore \reentrant
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString & replace(qsizetype i, qsizetype len, QChar after)
Definition qstring.cpp:3824
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
QString & remove(qsizetype i, qsizetype len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
Definition qstring.cpp:3466
\inmodule QtGui
Definition qwindow.h:63
QString text
QPushButton * button
[2]
QStyleOptionButton opt
WindowModality
@ NonModal
@ CaseInsensitive
UIWindow * presentationWindow(QWindow *)
Definition qiosglobal.mm:96
GLuint GLsizei const GLchar * label
[43]
GLuint GLsizei const GLchar * message
#define QStringLiteral(str)
#define emit
#define Q_UNUSED(x)
QObject::connect nullptr
sem release()
aWidget window() -> setWindowTitle("New Window Title")
[2]
QPlatformDialogHelper::ButtonRole role