Qt 6.x
The Qt SDK
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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
25{
26 hide();
27}
28
29inline QString QIOSMessageDialog::messageTextPlain()
30{
31 // Concatenate text fragments, and remove HTML tags
33 const QString &lineShift = QStringLiteral("\n\n");
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
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
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 = parent ? reinterpret_cast<UIView *>(parent->winId()).window : qt_apple_sharedApplication().keyWindow;
120 if (!window) {
121 qCDebug(lcQpaWindow, "Attempting to exec a dialog without any window/widget visible.");
122
123 auto *primaryScreen = static_cast<QIOSScreen*>(QGuiApplication::primaryScreen()->handle());
124 Q_ASSERT(primaryScreen);
125
126 window = primaryScreen->uiWindow();
127 if (window.hidden) {
128 // With a window hidden, an attempt to present view controller
129 // below fails with a warning, that a view "is not a part of
130 // any view hierarchy". The UIWindow is initially hidden,
131 // as unhiding it is what hides the splash screen.
132 window.hidden = NO;
133 }
134 }
135
136 if (!window)
137 return false;
138
139 [window.rootViewController presentViewController:m_alertController animated:YES completion:nil];
140 return true;
141}
142
144{
145 m_eventLoop.exit();
146 [m_alertController dismissViewControllerAnimated:YES completion:nil];
147 [m_alertController release];
148 m_alertController = nullptr;
149}
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()
QScreen * primaryScreen
the primary (or default) screen of the application.
void exec() override
bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override
Definition qlist.h:74
bool isEmpty() const noexcept
Definition qlist.h:390
const QList< CustomButton > & customButtons()
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
static ButtonRole buttonRole(StandardButton button)
const QSharedPointer< QMessageDialogOptions > & options() const
void clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role)
static QString removeMnemonics(const QString &original)
virtual QString standardButtonText(int button) const
Returns the text of a standard button.
\inmodule QtCore \reentrant
QPlatformScreen * handle() const
Get the platform screen handle.
Definition qscreen.cpp:83
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
QString & replace(qsizetype i, qsizetype len, QChar after)
Definition qstring.cpp:3794
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
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:3435
\inmodule QtGui
Definition qwindow.h:63
QString text
QPushButton * button
[2]
QStyleOptionButton opt
WindowModality
@ NonModal
@ CaseInsensitive
AppleApplication * qt_apple_sharedApplication()
Definition qcore_mac.mm:430
#define qCDebug(category,...)
GLuint GLsizei const GLchar * label
[43]
GLuint GLsizei const GLchar * message
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QStringLiteral(str)
#define emit
#define Q_UNUSED(x)
QObject::connect nullptr
sem release()
aWidget window() -> setWindowTitle("New Window Title")
[2]
QPlatformDialogHelper::ButtonRole role
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent