10#include <QtCore/qmetaobject.h>
11#include <QtCore/qscopedvaluerollback.h>
12#include <QtCore/qtimer.h>
14#include <QtGui/qtextdocument.h>
15#include <QtGui/private/qguiapplication_p.h>
16#include <QtGui/private/qcoregraphics_p.h>
17#include <QtGui/qpa/qplatformtheme.h>
19#include <AppKit/NSAlert.h>
20#include <AppKit/NSButton.h>
73 qCDebug(lcQpaDialogs) <<
"Asked to show" << windowModality <<
"dialog with parent" <<
parent;
75 if (m_alert.window.visible) {
76 qCDebug(lcQpaDialogs) <<
"Dialog already visible, ignoring request to show";
86 qCWarning(lcQpaDialogs,
"Cannot run window modal dialog without parent window");
96 m_alert = [NSAlert
new];
102 text += u
"\n\n"_s + details;
103 m_alert.messageText =
text.toNSString();
106 switch (
options()->standardIcon()) {
115 m_alert.icon = [NSImage imageFromQImage:iconPixmap.
toImage()];
120 [m_alert setAlertStyle:NSAlertStyleInformational];
123 [m_alert setAlertStyle:NSAlertStyleWarning];
126 [m_alert setAlertStyle:NSAlertStyleCritical];
130 bool defaultButtonAdded =
false;
131 bool cancelButtonAdded =
false;
133 const auto addButton = [&](
auto title,
auto tag,
auto role) {
135 NSButton *
button = [m_alert addButtonWithTitle:
title.toNSString()];
145 if (role ==
AcceptRole && !defaultButtonAdded) {
146 button.keyEquivalent =
@"\r";
147 defaultButtonAdded =
true;
148 }
else if (role ==
RejectRole && !cancelButtonAdded) {
149 button.keyEquivalent =
@"\e";
150 cancelButtonAdded =
true;
153 if (@available(macOS 11, *))
172 if (
auto standardButtons =
options()->standardButtons()) {
174 if (standardButtons & standardButton) {
175 auto title = platformTheme->standardButtonText(standardButton);
182 for (
auto customButton : customButtons)
183 addButton(customButton.label, customButton.id, customButton.role);
190 if (!m_alert.buttons.count) {
195 if (
auto checkBoxLabel =
options()->checkBoxLabel(); !checkBoxLabel.
isNull()) {
197 m_alert.suppressionButton.title = checkBoxLabel.toNSString();
201 m_alert.showsSuppressionButton = YES;
204 qCDebug(lcQpaDialogs) <<
"Showing" << m_alert;
208 [m_alert beginSheetModalForWindow:cocoaWindow->nativeWindow()
210 processResponse(response);
222 if (m_alert && NSApp.modalWindow != m_alert.window) {
223 qCDebug(lcQpaDialogs) <<
"Running deferred modal" << m_alert;
224 QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag();
225 processResponse(runModal());
242 while (response == NSModalResponseContinue)
243 response = [m_alert runModal];
252 qCDebug(lcQpaDialogs) <<
"Running local event loop for window modal" << m_alert;
257 qCDebug(lcQpaDialogs) <<
"Running modal" << m_alert;
259 processResponse(runModal());
278 qCDebug(lcQpaDialogs) <<
"Processing response" << response <<
"for" << m_alert;
283 auto alert = std::exchange(m_alert, nil);
286 if (alert.showsSuppressionButton)
289 if (response >= NSAlertFirstButtonReturn) {
293 qCDebug(lcQpaDialogs) <<
"Dialog was hidden; ignoring response";
311 case NSModalResponseContinue:
314 case NSModalResponseOK:
317 case NSModalResponseCancel:
318 case NSModalResponseStop:
319 case NSModalResponseAbort:
323 qCWarning(lcQpaDialogs) <<
"Unrecognized modal response" << response;
328 m_eventLoop->
exit(response);
336 if (m_alert.window.visible) {
337 qCDebug(lcQpaDialogs) <<
"Hiding" << modality() << m_alert;
346 if (NSApp.modalWindow == m_alert.window) {
350 qCWarning(lcQpaDialogs,
"Dialog is not top level modal window. Cannot hide.");
354 qCDebug(lcQpaDialogs) <<
"No need to hide already hidden" << m_alert;
355 auto alert = std::exchange(m_alert, nil);
362 Q_ASSERT(m_alert && m_alert.window);
static void clearCurrentThreadCocoaEventDispatcherInterruptFlag()
bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override
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()
Qt::CheckState checkBoxState() const
QPixmap iconPixmap() const
QString windowTitle() const
const CustomButton * customButton(int id)
const QList< CustomButton > & customButtons()
Native interface for QPlatformWindow on \macos. \inmodule QtGui.
QObject * parent() const
Returns a pointer to the parent object.
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
QImage toImage() const
Converts the pixmap to a QImage.
bool isNull() const
Returns true if this is a null pixmap; otherwise returns false.
bool isNull() const noexcept
Returns true if this object refers to \nullptr.
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
\reentrant \inmodule QtGui
void setHtml(const QString &html)
Replaces the entire contents of the document with the given HTML-formatted text in the html string.
QString toPlainText() const
Returns the plain text contained in the document.
bool singleShot
whether the timer is a single-shot timer
Combined button and popup list for selecting options.
Q_GUI_EXPORT bool mightBeRichText(const QString &)
Returns true if the string text is likely to be rich text; otherwise returns false.
NSInteger NSModalResponse
static NSControlStateValue controlStateFor(Qt::CheckState state)
static QString toPlainText(const QString &text)
static const NSInteger kModalResponseDialogHidden
static Qt::CheckState checkStateFor(NSControlStateValue state)
AudioChannelLayoutTag tag
#define qCWarning(category,...)
#define qCDebug(category,...)
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent