1/****************************************************************************
2**
3** Copyright (C) 2020 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtWidgets module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
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 https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include <QtWidgets/qmessagebox.h>
41
42#include <QtWidgets/qdialogbuttonbox.h>
43#include "private/qlabel_p.h"
44#include "private/qapplication_p.h"
45#include <QtCore/qlist.h>
46#include <QtCore/qdebug.h>
47#include <QtWidgets/qstyle.h>
48#include <QtWidgets/qstyleoption.h>
49#include <QtWidgets/qgridlayout.h>
50#include <QtWidgets/qpushbutton.h>
51#include <QtWidgets/qcheckbox.h>
52#include <QtGui/qaccessible.h>
53#include <QtGui/qicon.h>
54#include <QtGui/qtextdocument.h>
55#include <QtWidgets/qapplication.h>
56#if QT_CONFIG(textedit)
57#include <QtWidgets/qtextedit.h>
58#endif
59#if QT_CONFIG(menu)
60#include <QtWidgets/qmenu.h>
61#endif
62#include "qdialog_p.h"
63#include <QtGui/qfont.h>
64#include <QtGui/qfontmetrics.h>
65#include <QtGui/qclipboard.h>
66#include "private/qabstractbutton_p.h"
67
68#ifdef Q_OS_WIN
69# include <QtCore/qt_windows.h>
70#include <qpa/qplatformnativeinterface.h>
71#endif
72
73QT_BEGIN_NAMESPACE
74
75#if defined(Q_OS_WIN)
76HMENU qt_getWindowsSystemMenu(const QWidget *w)
77{
78 if (QWindow *window = QApplicationPrivate::windowForWidget(w))
79 if (void *handle = QGuiApplication::platformNativeInterface()->nativeResourceForWindow("handle", window))
80 return GetSystemMenu(reinterpret_cast<HWND>(handle), false);
81 return 0;
82}
83#endif
84
85enum Button { Old_Ok = 1, Old_Cancel = 2, Old_Yes = 3, Old_No = 4, Old_Abort = 5, Old_Retry = 6,
86 Old_Ignore = 7, Old_YesAll = 8, Old_NoAll = 9, Old_ButtonMask = 0xFF,
87 NewButtonMask = 0xFFFFFC00 };
88
89enum DetailButtonLabel { ShowLabel = 0, HideLabel = 1 };
90#if QT_CONFIG(textedit)
91class QMessageBoxDetailsText : public QWidget
92{
93 Q_OBJECT
94public:
95 class TextEdit : public QTextEdit
96 {
97 public:
98 TextEdit(QWidget *parent=nullptr) : QTextEdit(parent) { }
99#ifndef QT_NO_CONTEXTMENU
100 void contextMenuEvent(QContextMenuEvent * e) override
101 {
102 QMenu *menu = createStandardContextMenu();
103 menu->setAttribute(Qt::WA_DeleteOnClose);
104 menu->popup(e->globalPos());
105 }
106#endif // QT_NO_CONTEXTMENU
107 };
108
109 QMessageBoxDetailsText(QWidget *parent=nullptr)
110 : QWidget(parent)
111 , copyAvailable(false)
112 {
113 QVBoxLayout *layout = new QVBoxLayout;
114 layout->setContentsMargins(QMargins());
115 QFrame *line = new QFrame(this);
116 line->setFrameShape(QFrame::HLine);
117 line->setFrameShadow(QFrame::Sunken);
118 layout->addWidget(line);
119 textEdit = new TextEdit();
120 textEdit->setFixedHeight(100);
121 textEdit->setFocusPolicy(Qt::NoFocus);
122 textEdit->setReadOnly(true);
123 layout->addWidget(textEdit);
124 setLayout(layout);
125
126 connect(textEdit, SIGNAL(copyAvailable(bool)),
127 this, SLOT(textCopyAvailable(bool)));
128 }
129 void setText(const QString &text) { textEdit->setPlainText(text); }
130 QString text() const { return textEdit->toPlainText(); }
131
132 bool copy()
133 {
134#ifdef QT_NO_CLIPBOARD
135 return false;
136#else
137 if (!copyAvailable)
138 return false;
139 textEdit->copy();
140 return true;
141#endif
142 }
143
144 void selectAll()
145 {
146 textEdit->selectAll();
147 }
148
149private slots:
150 void textCopyAvailable(bool available)
151 {
152 copyAvailable = available;
153 }
154
155private:
156 bool copyAvailable;
157 TextEdit *textEdit;
158};
159#endif // QT_CONFIG(textedit)
160
161class DetailButton : public QPushButton
162{
163public:
164 DetailButton(QWidget *parent) : QPushButton(label(ShowLabel), parent)
165 {
166 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
167 }
168
169 QString label(DetailButtonLabel label) const
170 { return label == ShowLabel ? QMessageBox::tr("Show Details...") : QMessageBox::tr("Hide Details..."); }
171
172 void setLabel(DetailButtonLabel lbl)
173 { setText(label(lbl)); }
174
175 QSize sizeHint() const override
176 {
177 ensurePolished();
178 QStyleOptionButton opt;
179 initStyleOption(&opt);
180 const QFontMetrics fm = fontMetrics();
181 opt.text = label(ShowLabel);
182 QSize sz = fm.size(Qt::TextShowMnemonic, opt.text);
183 QSize ret = style()->sizeFromContents(QStyle::CT_PushButton, &opt, sz, this);
184 opt.text = label(HideLabel);
185 sz = fm.size(Qt::TextShowMnemonic, opt.text);
186 ret = ret.expandedTo(style()->sizeFromContents(QStyle::CT_PushButton, &opt, sz, this));
187 return ret;
188 }
189};
190
191class QMessageBoxPrivate : public QDialogPrivate
192{
193 Q_DECLARE_PUBLIC(QMessageBox)
194
195public:
196 QMessageBoxPrivate() : escapeButton(nullptr), defaultButton(nullptr), checkbox(nullptr), clickedButton(nullptr), detailsButton(nullptr),
197#if QT_CONFIG(textedit)
198 detailsText(nullptr),
199#endif
200 compatMode(false), autoAddOkButton(true),
201 detectedEscapeButton(nullptr), informativeLabel(nullptr),
202 options(QMessageDialogOptions::create()) { }
203
204 void init(const QString &title = QString(), const QString &text = QString());
205 void setupLayout();
206 void _q_buttonClicked(QAbstractButton *);
207 void _q_clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role);
208 void setClickedButton(QAbstractButton *button);
209
210 QAbstractButton *findButton(int button0, int button1, int button2, int flags);
211 void addOldButtons(int button0, int button1, int button2);
212
213 QAbstractButton *abstractButtonForId(int id) const;
214 int execReturnCode(QAbstractButton *button);
215
216 int dialogCodeForButton(QAbstractButton *button) const;
217
218 void detectEscapeButton();
219 void updateSize();
220 int layoutMinimumWidth();
221 void retranslateStrings();
222
223 static int showOldMessageBox(QWidget *parent, QMessageBox::Icon icon,
224 const QString &title, const QString &text,
225 int button0, int button1, int button2);
226 static int showOldMessageBox(QWidget *parent, QMessageBox::Icon icon,
227 const QString &title, const QString &text,
228 const QString &button0Text,
229 const QString &button1Text,
230 const QString &button2Text,
231 int defaultButtonNumber,
232 int escapeButtonNumber);
233
234 static QMessageBox::StandardButton showNewMessageBox(QWidget *parent,
235 QMessageBox::Icon icon, const QString& title, const QString& text,
236 QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton);
237
238 static QPixmap standardIcon(QMessageBox::Icon icon, QMessageBox *mb);
239
240 QLabel *label;
241 QMessageBox::Icon icon;
242 QLabel *iconLabel;
243 QDialogButtonBox *buttonBox;
244 QList<QAbstractButton *> customButtonList;
245 QAbstractButton *escapeButton;
246 QPushButton *defaultButton;
247 QCheckBox *checkbox;
248 QAbstractButton *clickedButton;
249 DetailButton *detailsButton;
250#if QT_CONFIG(textedit)
251 QMessageBoxDetailsText *detailsText;
252#endif
253 bool compatMode;
254 bool autoAddOkButton;
255 QAbstractButton *detectedEscapeButton;
256 QLabel *informativeLabel;
257 QPointer<QObject> receiverToDisconnectOnClose;
258 QByteArray memberToDisconnectOnClose;
259 QByteArray signalToDisconnectOnClose;
260 QSharedPointer<QMessageDialogOptions> options;
261private:
262 void initHelper(QPlatformDialogHelper *) override;
263 void helperPrepareShow(QPlatformDialogHelper *) override;
264 void helperDone(QDialog::DialogCode, QPlatformDialogHelper *) override;
265};
266
267void QMessageBoxPrivate::init(const QString &title, const QString &text)
268{
269 Q_Q(QMessageBox);
270
271 label = new QLabel;
272 label->setObjectName(QLatin1String("qt_msgbox_label"));
273 label->setTextInteractionFlags(Qt::TextInteractionFlags(q->style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, nullptr, q)));
274 label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
275 label->setOpenExternalLinks(true);
276 iconLabel = new QLabel(q);
277 iconLabel->setObjectName(QLatin1String("qt_msgboxex_icon_label"));
278 iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
279
280 buttonBox = new QDialogButtonBox;
281 buttonBox->setObjectName(QLatin1String("qt_msgbox_buttonbox"));
282 buttonBox->setCenterButtons(q->style()->styleHint(QStyle::SH_MessageBox_CenterButtons, nullptr, q));
283 QObject::connect(buttonBox, SIGNAL(clicked(QAbstractButton*)),
284 q, SLOT(_q_buttonClicked(QAbstractButton*)));
285 setupLayout();
286 if (!title.isEmpty() || !text.isEmpty()) {
287 q->setWindowTitle(title);
288 q->setText(text);
289 }
290 q->setModal(true);
291#ifdef Q_OS_MAC
292 QFont f = q->font();
293 f.setBold(true);
294 label->setFont(f);
295#endif
296 icon = QMessageBox::NoIcon;
297}
298
299void QMessageBoxPrivate::setupLayout()
300{
301 Q_Q(QMessageBox);
302 delete q->layout();
303 QGridLayout *grid = new QGridLayout;
304 bool hasIcon = !iconLabel->pixmap(Qt::ReturnByValue).isNull();
305
306 if (hasIcon)
307 grid->addWidget(iconLabel, 0, 0, 2, 1, Qt::AlignTop);
308 iconLabel->setVisible(hasIcon);
309#ifdef Q_OS_MAC
310 QSpacerItem *indentSpacer = new QSpacerItem(14, 1, QSizePolicy::Fixed, QSizePolicy::Fixed);
311#else
312 QSpacerItem *indentSpacer = new QSpacerItem(hasIcon ? 7 : 15, 1, QSizePolicy::Fixed, QSizePolicy::Fixed);
313#endif
314 grid->addItem(indentSpacer, 0, hasIcon ? 1 : 0, 2, 1);
315 grid->addWidget(label, 0, hasIcon ? 2 : 1, 1, 1);
316 if (informativeLabel) {
317#ifndef Q_OS_MAC
318 informativeLabel->setContentsMargins(0, 7, 0, 7);
319#endif
320 grid->addWidget(informativeLabel, 1, hasIcon ? 2 : 1, 1, 1);
321 }
322 if (checkbox) {
323 grid->addWidget(checkbox, informativeLabel ? 2 : 1, hasIcon ? 2 : 1, 1, 1, Qt::AlignLeft);
324#ifdef Q_OS_MAC
325 grid->addItem(new QSpacerItem(1, 15, QSizePolicy::Fixed, QSizePolicy::Fixed), grid->rowCount(), 0);
326#else
327 grid->addItem(new QSpacerItem(1, 7, QSizePolicy::Fixed, QSizePolicy::Fixed), grid->rowCount(), 0);
328#endif
329 }
330#ifdef Q_OS_MAC
331 grid->addWidget(buttonBox, grid->rowCount(), hasIcon ? 2 : 1, 1, 1);
332 grid->setContentsMargins(0, 0, 0, 0);
333 grid->setVerticalSpacing(8);
334 grid->setHorizontalSpacing(0);
335 q->setContentsMargins(24, 15, 24, 20);
336 grid->setRowStretch(1, 100);
337 grid->setRowMinimumHeight(2, 6);
338#else
339 grid->addWidget(buttonBox, grid->rowCount(), 0, 1, grid->columnCount());
340#endif
341#if QT_CONFIG(textedit)
342 if (detailsText)
343 grid->addWidget(detailsText, grid->rowCount(), 0, 1, grid->columnCount());
344#endif
345 grid->setSizeConstraint(QLayout::SetNoConstraint);
346 q->setLayout(grid);
347
348 retranslateStrings();
349 updateSize();
350}
351
352int QMessageBoxPrivate::layoutMinimumWidth()
353{
354 layout->activate();
355 return layout->totalMinimumSize().width();
356}
357
358void QMessageBoxPrivate::updateSize()
359{
360 Q_Q(QMessageBox);
361
362 if (!q->isVisible())
363 return;
364
365 const QSize screenSize = QGuiApplication::screenAt(QCursor::pos())->availableGeometry().size();
366 int hardLimit = qMin(screenSize.width() - 480, 1000); // can never get bigger than this
367 // on small screens allows the messagebox be the same size as the screen
368 if (screenSize.width() <= 1024)
369 hardLimit = screenSize.width();
370#ifdef Q_OS_MAC
371 int softLimit = qMin(screenSize.width()/2, 420);
372#else
373 // note: ideally on windows, hard and soft limits but it breaks compat
374 int softLimit = qMin(screenSize.width()/2, 500);
375#endif
376
377 if (informativeLabel)
378 informativeLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
379
380 label->setWordWrap(false); // makes the label return min size
381 int width = layoutMinimumWidth();
382
383 if (width > softLimit) {
384 label->setWordWrap(true);
385 width = qMax(softLimit, layoutMinimumWidth());
386
387 if (width > hardLimit) {
388 label->d_func()->ensureTextControl();
389 if (QWidgetTextControl *control = label->d_func()->control) {
390 QTextOption opt = control->document()->defaultTextOption();
391 opt.setWrapMode(QTextOption::WrapAnywhere);
392 control->document()->setDefaultTextOption(opt);
393 }
394 width = hardLimit;
395 }
396 }
397
398 if (informativeLabel) {
399 label->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
400 QSizePolicy policy(QSizePolicy::Minimum, QSizePolicy::Preferred);
401 policy.setHeightForWidth(true);
402 informativeLabel->setSizePolicy(policy);
403 width = qMax(width, layoutMinimumWidth());
404 if (width > hardLimit) { // longest word is really big, so wrap anywhere
405 informativeLabel->d_func()->ensureTextControl();
406 if (QWidgetTextControl *control = informativeLabel->d_func()->control) {
407 QTextOption opt = control->document()->defaultTextOption();
408 opt.setWrapMode(QTextOption::WrapAnywhere);
409 control->document()->setDefaultTextOption(opt);
410 }
411 width = hardLimit;
412 }
413 policy.setHeightForWidth(label->wordWrap());
414 label->setSizePolicy(policy);
415 }
416
417 QFontMetrics fm(QApplication::font("QMdiSubWindowTitleBar"));
418 int windowTitleWidth = qMin(fm.horizontalAdvance(q->windowTitle()) + 50, hardLimit);
419 if (windowTitleWidth > width)
420 width = windowTitleWidth;
421
422 layout->activate();
423 int height = (layout->hasHeightForWidth())
424 ? layout->totalHeightForWidth(width)
425 : layout->totalMinimumSize().height();
426
427 q->setFixedSize(width, height);
428 QCoreApplication::removePostedEvents(q, QEvent::LayoutRequest);
429}
430
431static int oldButton(int button)
432{
433 switch (button & QMessageBox::ButtonMask) {
434 case QMessageBox::Ok:
435 return Old_Ok;
436 case QMessageBox::Cancel:
437 return Old_Cancel;
438 case QMessageBox::Yes:
439 return Old_Yes;
440 case QMessageBox::No:
441 return Old_No;
442 case QMessageBox::Abort:
443 return Old_Abort;
444 case QMessageBox::Retry:
445 return Old_Retry;
446 case QMessageBox::Ignore:
447 return Old_Ignore;
448 case QMessageBox::YesToAll:
449 return Old_YesAll;
450 case QMessageBox::NoToAll:
451 return Old_NoAll;
452 default:
453 return 0;
454 }
455}
456
457int QMessageBoxPrivate::execReturnCode(QAbstractButton *button)
458{
459 int ret = buttonBox->standardButton(button);
460 if (ret == QMessageBox::NoButton) {
461 ret = customButtonList.indexOf(button); // if button == 0, correctly sets ret = -1
462 } else if (compatMode) {
463 ret = oldButton(ret);
464 }
465 return ret;
466}
467
468/*!
469 \internal
470
471 Returns 0 for RejectedRole and NoRole, 1 for AcceptedRole and YesRole, -1 otherwise
472 */
473int QMessageBoxPrivate::dialogCodeForButton(QAbstractButton *button) const
474{
475 Q_Q(const QMessageBox);
476
477 switch (q->buttonRole(button)) {
478 case QMessageBox::AcceptRole:
479 case QMessageBox::YesRole:
480 return QDialog::Accepted;
481 case QMessageBox::RejectRole:
482 case QMessageBox::NoRole:
483 return QDialog::Rejected;
484 default:
485 return -1;
486 }
487}
488
489void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button)
490{
491 Q_Q(QMessageBox);
492#if QT_CONFIG(textedit)
493 if (detailsButton && detailsText && button == detailsButton) {
494 detailsButton->setLabel(detailsText->isHidden() ? HideLabel : ShowLabel);
495 detailsText->setHidden(!detailsText->isHidden());
496 updateSize();
497 } else
498#endif
499 {
500 setClickedButton(button);
501
502 if (receiverToDisconnectOnClose) {
503 QObject::disconnect(q, signalToDisconnectOnClose, receiverToDisconnectOnClose,
504 memberToDisconnectOnClose);
505 receiverToDisconnectOnClose = nullptr;
506 }
507 signalToDisconnectOnClose.clear();
508 memberToDisconnectOnClose.clear();
509 }
510}
511
512void QMessageBoxPrivate::setClickedButton(QAbstractButton *button)
513{
514 Q_Q(QMessageBox);
515
516 clickedButton = button;
517 emit q->buttonClicked(clickedButton);
518
519 auto resultCode = execReturnCode(button);
520 hide(resultCode);
521 finalize(resultCode, dialogCodeForButton(button));
522}
523
524void QMessageBoxPrivate::_q_clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role)
525{
526 Q_Q(QMessageBox);
527 if (button > QPlatformDialogHelper::LastButton) {
528 // It's a custom button, and the QPushButton in options is just a proxy
529 // for the button on the platform dialog. Simulate the user clicking it.
530 clickedButton = static_cast<QAbstractButton *>(options->customButton(button)->button);
531 Q_ASSERT(clickedButton);
532 clickedButton->click();
533 q->done(role);
534 } else {
535 q->done(button);
536 }
537}
538
539/*!
540 \class QMessageBox
541
542 \brief The QMessageBox class provides a modal dialog for informing
543 the user or for asking the user a question and receiving an answer.
544
545 \ingroup standard-dialogs
546 \inmodule QtWidgets
547
548 A message box displays a primary \l{QMessageBox::text}{text} to
549 alert the user to a situation, an \l{QMessageBox::informativeText}
550 {informative text} to further explain the alert or to ask the user
551 a question, and an optional \l{QMessageBox::detailedText}
552 {detailed text} to provide even more data if the user requests
553 it. A message box can also display an \l{QMessageBox::icon} {icon}
554 and \l{QMessageBox::standardButtons} {standard buttons} for
555 accepting a user response.
556
557 Two APIs for using QMessageBox are provided, the property-based
558 API, and the static functions. Calling one of the static functions
559 is the simpler approach, but it is less flexible than using the
560 property-based API, and the result is less informative. Using the
561 property-based API is recommended.
562
563 \section1 The Property-based API
564
565 To use the property-based API, construct an instance of
566 QMessageBox, set the desired properties, and call exec() to show
567 the message. The simplest configuration is to set only the
568 \l{QMessageBox::text} {message text} property.
569
570 \snippet code/src_gui_dialogs_qmessagebox.cpp 5
571
572 The user must click the \uicontrol{OK} button to dismiss the message
573 box. The rest of the GUI is blocked until the message box is
574 dismissed.
575
576 \image msgbox1.png
577
578 A better approach than just alerting the user to an event is to
579 also ask the user what to do about it. Store the question in the
580 \l{QMessageBox::informativeText} {informative text} property, and
581 set the \l{QMessageBox::standardButtons} {standard buttons}
582 property to the set of buttons you want as the set of user
583 responses. The buttons are specified by combining values from
584 StandardButtons using the bitwise OR operator. The display order
585 for the buttons is platform-dependent. For example, on Windows,
586 \uicontrol{Save} is displayed to the left of \uicontrol{Cancel}, whereas on
587 Mac OS, the order is reversed.
588
589 Mark one of your standard buttons to be your
590 \l{QMessageBox::defaultButton()} {default button}.
591
592 \snippet code/src_gui_dialogs_qmessagebox.cpp 6
593
594 This is the approach recommended in the
595 \l{http://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/AppleHIGuidelines/Windows/Windows.html#//apple_ref/doc/uid/20000961-BABCAJID}
596 {\macos Guidelines}. Similar guidelines apply for the other
597 platforms, but note the different ways the
598 \l{QMessageBox::informativeText} {informative text} is handled for
599 different platforms.
600
601 \image msgbox2.png
602
603 The exec() slot returns the StandardButtons value of the button
604 that was clicked.
605
606 \snippet code/src_gui_dialogs_qmessagebox.cpp 7
607
608 To give the user more information to help him answer the question,
609 set the \l{QMessageBox::detailedText} {detailed text} property. If
610 the \l{QMessageBox::detailedText} {detailed text} property is set,
611 the \uicontrol{Show Details...} button will be shown.
612
613 \image msgbox3.png
614
615 Clicking the \uicontrol{Show Details...} button displays the detailed text.
616
617 \image msgbox4.png
618
619 \section2 Rich Text and the Text Format Property
620
621 The \l{QMessageBox::detailedText} {detailed text} property is
622 always interpreted as plain text. The \l{QMessageBox::text} {main
623 text} and \l{QMessageBox::informativeText} {informative text}
624 properties can be either plain text or rich text. These strings
625 are interpreted according to the setting of the
626 \l{QMessageBox::textFormat} {text format} property. The default
627 setting is \l{Qt::AutoText} {auto-text}.
628
629 Note that for some plain text strings containing XML
630 meta-characters, the auto-text \l{Qt::mightBeRichText()} {rich
631 text detection test} may fail causing your plain text string to be
632 interpreted incorrectly as rich text. In these rare cases, use
633 Qt::convertFromPlainText() to convert your plain text string to a
634 visually equivalent rich text string, or set the
635 \l{QMessageBox::textFormat} {text format} property explicitly with
636 setTextFormat().
637
638 \section2 Severity Levels and the Icon and Pixmap Properties
639
640 QMessageBox supports four predefined message severity levels, or message
641 types, which really only differ in the predefined icon they each show.
642 Specify one of the four predefined message types by setting the
643 \l{QMessageBox::icon}{icon} property to one of the
644 \l{QMessageBox::Icon}{predefined icons}. The following rules are
645 guidelines:
646
647 \table
648 \row
649 \li \image qmessagebox-quest.png
650 \li \l Question
651 \li For asking a question during normal operations.
652 \row
653 \li \image qmessagebox-info.png
654 \li \l Information
655 \li For reporting information about normal operations.
656 \row
657 \li \image qmessagebox-warn.png
658 \li \l Warning
659 \li For reporting non-critical errors.
660 \row
661 \li \image qmessagebox-crit.png
662 \li \l Critical
663 \li For reporting critical errors.
664 \endtable
665
666 \l{QMessageBox::Icon}{Predefined icons} are not defined by QMessageBox, but
667 provided by the style. The default value is \l{QMessageBox::NoIcon}
668 {No Icon}. The message boxes are otherwise the same for all cases. When
669 using a standard icon, use the one recommended in the table, or use the
670 one recommended by the style guidelines for your platform. If none of the
671 standard icons is right for your message box, you can use a custom icon by
672 setting the \l{QMessageBox::iconPixmap}{icon pixmap} property instead of
673 setting the \l{QMessageBox::icon}{icon} property.
674
675 In summary, to set an icon, use \e{either} setIcon() for one of the
676 standard icons, \e{or} setIconPixmap() for a custom icon.
677
678 \section1 The Static Functions API
679
680 Building message boxes with the static functions API, although
681 convenient, is less flexible than using the property-based API,
682 because the static function signatures lack parameters for setting
683 the \l{QMessageBox::informativeText} {informative text} and
684 \l{QMessageBox::detailedText} {detailed text} properties. One
685 work-around for this has been to use the \c{title} parameter as
686 the message box main text and the \c{text} parameter as the
687 message box informative text. Because this has the obvious
688 drawback of making a less readable message box, platform
689 guidelines do not recommend it. The \e{Microsoft Windows User
690 Interface Guidelines} recommend using the
691 \l{QCoreApplication::applicationName} {application name} as the
692 \l{QMessageBox::setWindowTitle()} {window's title}, which means
693 that if you have an informative text in addition to your main
694 text, you must concatenate it to the \c{text} parameter.
695
696 Note that the static function signatures have changed with respect
697 to their button parameters, which are now used to set the
698 \l{QMessageBox::standardButtons} {standard buttons} and the
699 \l{QMessageBox::defaultButton()} {default button}.
700
701 Static functions are available for creating information(),
702 question(), warning(), and critical() message boxes.
703
704 \snippet code/src_gui_dialogs_qmessagebox.cpp 0
705
706 The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
707 how to use QMessageBox and the other built-in Qt dialogs.
708
709 \section1 Advanced Usage
710
711 If the \l{QMessageBox::StandardButtons} {standard buttons} are not
712 flexible enough for your message box, you can use the addButton()
713 overload that takes a text and a ButtonRole to add custom
714 buttons. The ButtonRole is used by QMessageBox to determine the
715 ordering of the buttons on screen (which varies according to the
716 platform). You can test the value of clickedButton() after calling
717 exec(). For example,
718
719 \snippet code/src_gui_dialogs_qmessagebox.cpp 2
720
721 \section1 Default and Escape Keys
722
723 The default button (i.e., the button activated when \uicontrol Enter is
724 pressed) can be specified using setDefaultButton(). If a default
725 button is not specified, QMessageBox tries to find one based on
726 the \l{ButtonRole} {button roles} of the buttons used in the
727 message box.
728
729 The escape button (the button activated when \uicontrol Esc is pressed)
730 can be specified using setEscapeButton(). If an escape button is
731 not specified, QMessageBox tries to find one using these rules:
732
733 \list 1
734
735 \li If there is only one button, it is the button activated when
736 \uicontrol Esc is pressed.
737
738 \li If there is a \l Cancel button, it is the button activated when
739 \uicontrol Esc is pressed.
740
741 \li If there is exactly one button having either
742 \l{QMessageBox::RejectRole} {the Reject role} or the
743 \l{QMessageBox::NoRole} {the No role}, it is the button
744 activated when \uicontrol Esc is pressed.
745
746 \endlist
747
748 When an escape button can't be determined using these rules,
749 pressing \uicontrol Esc has no effect.
750
751 \sa QDialogButtonBox, {fowler}{GUI Design Handbook: Message Box}, {Standard Dialogs Example}, {Application Example}
752*/
753
754/*!
755 \enum QMessageBox::ButtonRole
756
757 \include qdialogbuttonbox.cpp buttonrole-enum
758*/
759
760/*!
761 \enum QMessageBox::StandardButton
762 \since 4.2
763
764 These enums describe flags for standard buttons. Each button has a
765 defined \l ButtonRole.
766
767 \value Ok An "OK" button defined with the \l AcceptRole.
768 \value Open An "Open" button defined with the \l AcceptRole.
769 \value Save A "Save" button defined with the \l AcceptRole.
770 \value Cancel A "Cancel" button defined with the \l RejectRole.
771 \value Close A "Close" button defined with the \l RejectRole.
772 \value Discard A "Discard" or "Don't Save" button, depending on the platform,
773 defined with the \l DestructiveRole.
774 \value Apply An "Apply" button defined with the \l ApplyRole.
775 \value Reset A "Reset" button defined with the \l ResetRole.
776 \value RestoreDefaults A "Restore Defaults" button defined with the \l ResetRole.
777 \value Help A "Help" button defined with the \l HelpRole.
778 \value SaveAll A "Save All" button defined with the \l AcceptRole.
779 \value Yes A "Yes" button defined with the \l YesRole.
780 \value YesToAll A "Yes to All" button defined with the \l YesRole.
781 \value No A "No" button defined with the \l NoRole.
782 \value NoToAll A "No to All" button defined with the \l NoRole.
783 \value Abort An "Abort" button defined with the \l RejectRole.
784 \value Retry A "Retry" button defined with the \l AcceptRole.
785 \value Ignore An "Ignore" button defined with the \l AcceptRole.
786
787 \value NoButton An invalid button.
788
789 \omitvalue FirstButton
790 \omitvalue LastButton
791
792 The following values are obsolete:
793
794 \value YesAll Use YesToAll instead.
795 \value NoAll Use NoToAll instead.
796 \value Default Use the \c defaultButton argument of
797 information(), warning(), etc. instead, or call
798 setDefaultButton().
799 \value Escape Call setEscapeButton() instead.
800 \value FlagMask
801 \value ButtonMask
802
803 \sa ButtonRole, standardButtons
804*/
805
806/*!
807 \fn void QMessageBox::buttonClicked(QAbstractButton *button)
808
809 This signal is emitted whenever a button is clicked inside the QMessageBox.
810 The button that was clicked in returned in \a button.
811*/
812
813/*!
814 Constructs a message box with no text and no buttons. \a parent is
815 passed to the QDialog constructor.
816
817 On \macos, if you want your message box to appear
818 as a Qt::Sheet of its \a parent, set the message box's
819 \l{setWindowModality()} {window modality} to Qt::WindowModal or use open().
820 Otherwise, the message box will be a standard dialog.
821
822*/
823QMessageBox::QMessageBox(QWidget *parent)
824 : QDialog(*new QMessageBoxPrivate, parent, Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
825{
826 Q_D(QMessageBox);
827 d->init();
828}
829
830/*!
831 Constructs a message box with the given \a icon, \a title, \a
832 text, and standard \a buttons. Standard or custom buttons can be
833 added at any time using addButton(). The \a parent and \a f
834 arguments are passed to the QDialog constructor.
835
836 The message box is an \l{Qt::ApplicationModal} {application modal}
837 dialog box.
838
839 On \macos, if \a parent is not \nullptr and you want your message box
840 to appear as a Qt::Sheet of that parent, set the message box's
841 \l{setWindowModality()} {window modality} to Qt::WindowModal
842 (default). Otherwise, the message box will be a standard dialog.
843
844 \sa setWindowTitle(), setText(), setIcon(), setStandardButtons()
845*/
846QMessageBox::QMessageBox(Icon icon, const QString &title, const QString &text,
847 StandardButtons buttons, QWidget *parent,
848 Qt::WindowFlags f)
849: QDialog(*new QMessageBoxPrivate, parent, f | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
850{
851 Q_D(QMessageBox);
852 d->init(title, text);
853 setIcon(icon);
854 if (buttons != NoButton)
855 setStandardButtons(buttons);
856}
857
858/*!
859 Destroys the message box.
860*/
861QMessageBox::~QMessageBox()
862{
863}
864
865/*!
866 \since 4.2
867
868 Adds the given \a button to the message box with the specified \a
869 role.
870
871 \sa removeButton(), button(), setStandardButtons()
872*/
873void QMessageBox::addButton(QAbstractButton *button, ButtonRole role)
874{
875 Q_D(QMessageBox);
876 if (!button)
877 return;
878 removeButton(button);
879 d->options->addButton(button->text(), static_cast<QPlatformDialogHelper::ButtonRole>(role),
880 button);
881 d->buttonBox->addButton(button, (QDialogButtonBox::ButtonRole)role);
882 d->customButtonList.append(button);
883 d->autoAddOkButton = false;
884}
885
886/*!
887 \since 4.2
888 \overload
889
890 Creates a button with the given \a text, adds it to the message box for the
891 specified \a role, and returns it.
892*/
893QPushButton *QMessageBox::addButton(const QString& text, ButtonRole role)
894{
895 Q_D(QMessageBox);
896 QPushButton *pushButton = new QPushButton(text);
897 addButton(pushButton, role);
898 d->updateSize();
899 return pushButton;
900}
901
902/*!
903 \since 4.2
904 \overload
905
906 Adds a standard \a button to the message box if it is valid to do so, and
907 returns the push button.
908
909 \sa setStandardButtons()
910*/
911QPushButton *QMessageBox::addButton(StandardButton button)
912{
913 Q_D(QMessageBox);
914 QPushButton *pushButton = d->buttonBox->addButton((QDialogButtonBox::StandardButton)button);
915 if (pushButton)
916 d->autoAddOkButton = false;
917 return pushButton;
918}
919
920/*!
921 \since 4.2
922
923 Removes \a button from the button box without deleting it.
924
925 \sa addButton(), setStandardButtons()
926*/
927void QMessageBox::removeButton(QAbstractButton *button)
928{
929 Q_D(QMessageBox);
930 d->customButtonList.removeAll(button);
931 if (d->escapeButton == button)
932 d->escapeButton = nullptr;
933 if (d->defaultButton == button)
934 d->defaultButton = nullptr;
935 d->buttonBox->removeButton(button);
936 d->updateSize();
937}
938
939/*!
940 \property QMessageBox::standardButtons
941 \brief collection of standard buttons in the message box
942 \since 4.2
943
944 This property controls which standard buttons are used by the message box.
945
946 By default, this property contains no standard buttons.
947
948 \sa addButton()
949*/
950void QMessageBox::setStandardButtons(StandardButtons buttons)
951{
952 Q_D(QMessageBox);
953 d->buttonBox->setStandardButtons(QDialogButtonBox::StandardButtons(int(buttons)));
954
955 QList<QAbstractButton *> buttonList = d->buttonBox->buttons();
956 if (!buttonList.contains(d->escapeButton))
957 d->escapeButton = nullptr;
958 if (!buttonList.contains(d->defaultButton))
959 d->defaultButton = nullptr;
960 d->autoAddOkButton = false;
961 d->updateSize();
962}
963
964QMessageBox::StandardButtons QMessageBox::standardButtons() const
965{
966 Q_D(const QMessageBox);
967 return QMessageBox::StandardButtons(int(d->buttonBox->standardButtons()));
968}
969
970/*!
971 \since 4.2
972
973 Returns the standard button enum value corresponding to the given \a button,
974 or NoButton if the given \a button isn't a standard button.
975
976 \sa button(), standardButtons()
977*/
978QMessageBox::StandardButton QMessageBox::standardButton(QAbstractButton *button) const
979{
980 Q_D(const QMessageBox);
981 return (QMessageBox::StandardButton)d->buttonBox->standardButton(button);
982}
983
984/*!
985 \since 4.2
986
987 Returns a pointer corresponding to the standard button \a which,
988 or \nullptr if the standard button doesn't exist in this message box.
989
990 \sa standardButtons, standardButton()
991*/
992QAbstractButton *QMessageBox::button(StandardButton which) const
993{
994 Q_D(const QMessageBox);
995 return d->buttonBox->button(QDialogButtonBox::StandardButton(which));
996}
997
998/*!
999 \since 4.2
1000
1001 Returns the button that is activated when escape is pressed.
1002
1003 By default, QMessageBox attempts to automatically detect an
1004 escape button as follows:
1005
1006 \list 1
1007 \li If there is only one button, it is made the escape button.
1008 \li If there is a \l Cancel button, it is made the escape button.
1009 \li On \macos only, if there is exactly one button with the role
1010 QMessageBox::RejectRole, it is made the escape button.
1011 \endlist
1012
1013 When an escape button could not be automatically detected, pressing
1014 \uicontrol Esc has no effect.
1015
1016 \sa addButton()
1017*/
1018QAbstractButton *QMessageBox::escapeButton() const
1019{
1020 Q_D(const QMessageBox);
1021 return d->escapeButton;
1022}
1023
1024/*!
1025 \since 4.2
1026
1027 Sets the button that gets activated when the \uicontrol Escape key is
1028 pressed to \a button.
1029
1030 \sa addButton(), clickedButton()
1031*/
1032void QMessageBox::setEscapeButton(QAbstractButton *button)
1033{
1034 Q_D(QMessageBox);
1035 if (d->buttonBox->buttons().contains(button))
1036 d->escapeButton = button;
1037}
1038
1039/*!
1040 \since 4.3
1041
1042 Sets the buttons that gets activated when the \uicontrol Escape key is
1043 pressed to \a button.
1044
1045 \sa addButton(), clickedButton()
1046*/
1047void QMessageBox::setEscapeButton(QMessageBox::StandardButton button)
1048{
1049 Q_D(QMessageBox);
1050 setEscapeButton(d->buttonBox->button(QDialogButtonBox::StandardButton(button)));
1051}
1052
1053void QMessageBoxPrivate::detectEscapeButton()
1054{
1055 if (escapeButton) { // escape button explicitly set
1056 detectedEscapeButton = escapeButton;
1057 return;
1058 }
1059
1060 // Cancel button automatically becomes escape button
1061 detectedEscapeButton = buttonBox->button(QDialogButtonBox::Cancel);
1062 if (detectedEscapeButton)
1063 return;
1064
1065 // If there is only one button, make it the escape button
1066 const QList<QAbstractButton *> buttons = buttonBox->buttons();
1067 if (buttons.count() == 1) {
1068 detectedEscapeButton = buttons.first();
1069 return;
1070 }
1071
1072 // If there are two buttons and one of them is the "Show Details..."
1073 // button, then make the other one the escape button
1074 if (buttons.count() == 2 && detailsButton) {
1075 auto idx = buttons.indexOf(detailsButton);
1076 if (idx != -1) {
1077 detectedEscapeButton = buttons.at(1 - idx);
1078 return;
1079 }
1080 }
1081
1082 // if the message box has one RejectRole button, make it the escape button
1083 for (auto *button : buttons) {
1084 if (buttonBox->buttonRole(button) == QDialogButtonBox::RejectRole) {
1085 if (detectedEscapeButton) { // already detected!
1086 detectedEscapeButton = nullptr;
1087 break;
1088 }
1089 detectedEscapeButton = button;
1090 }
1091 }
1092 if (detectedEscapeButton)
1093 return;
1094
1095 // if the message box has one NoRole button, make it the escape button
1096 for (auto *button : buttons) {
1097 if (buttonBox->buttonRole(button) == QDialogButtonBox::NoRole) {
1098 if (detectedEscapeButton) { // already detected!
1099 detectedEscapeButton = nullptr;
1100 break;
1101 }
1102 detectedEscapeButton = button;
1103 }
1104 }
1105}
1106
1107/*!
1108 \since 4.2
1109
1110 Returns the button that was clicked by the user,
1111 or \nullptr if the user hit the \uicontrol Esc key and
1112 no \l{setEscapeButton()}{escape button} was set.
1113
1114 If exec() hasn't been called yet, returns nullptr.
1115
1116 Example:
1117
1118 \snippet code/src_gui_dialogs_qmessagebox.cpp 3
1119
1120 \sa standardButton(), button()
1121*/
1122QAbstractButton *QMessageBox::clickedButton() const
1123{
1124 Q_D(const QMessageBox);
1125 return d->clickedButton;
1126}
1127
1128/*!
1129 \since 4.2
1130
1131 Returns the button that should be the message box's
1132 \l{QPushButton::setDefault()}{default button}. Returns nullptr
1133 if no default button was set.
1134
1135 \sa addButton(), QPushButton::setDefault()
1136*/
1137QPushButton *QMessageBox::defaultButton() const
1138{
1139 Q_D(const QMessageBox);
1140 return d->defaultButton;
1141}
1142
1143/*!
1144 \since 4.2
1145
1146 Sets the message box's \l{QPushButton::setDefault()}{default button}
1147 to \a button.
1148
1149 \sa addButton(), QPushButton::setDefault()
1150*/
1151void QMessageBox::setDefaultButton(QPushButton *button)
1152{
1153 Q_D(QMessageBox);
1154 if (!d->buttonBox->buttons().contains(button))
1155 return;
1156 d->defaultButton = button;
1157 button->setDefault(true);
1158 button->setFocus();
1159}
1160
1161/*!
1162 \since 4.3
1163
1164 Sets the message box's \l{QPushButton::setDefault()}{default button}
1165 to \a button.
1166
1167 \sa addButton(), QPushButton::setDefault()
1168*/
1169void QMessageBox::setDefaultButton(QMessageBox::StandardButton button)
1170{
1171 Q_D(QMessageBox);
1172 setDefaultButton(d->buttonBox->button(QDialogButtonBox::StandardButton(button)));
1173}
1174
1175/*! \since 5.2
1176
1177 Sets the checkbox \a cb on the message dialog. The message box takes ownership of the checkbox.
1178 The argument \a cb can be \nullptr to remove an existing checkbox from the message box.
1179
1180 \sa checkBox()
1181*/
1182
1183void QMessageBox::setCheckBox(QCheckBox *cb)
1184{
1185 Q_D(QMessageBox);
1186
1187 if (cb == d->checkbox)
1188 return;
1189
1190 if (d->checkbox) {
1191 d->checkbox->hide();
1192 layout()->removeWidget(d->checkbox);
1193 if (d->checkbox->parentWidget() == this) {
1194 d->checkbox->setParent(nullptr);
1195 d->checkbox->deleteLater();
1196 }
1197 }
1198 d->checkbox = cb;
1199 if (d->checkbox) {
1200 QSizePolicy sp = d->checkbox->sizePolicy();
1201 sp.setHorizontalPolicy(QSizePolicy::MinimumExpanding);
1202 d->checkbox->setSizePolicy(sp);
1203 }
1204 d->setupLayout();
1205}
1206
1207
1208/*! \since 5.2
1209
1210 Returns the checkbox shown on the dialog. This is \nullptr if no checkbox is set.
1211 \sa setCheckBox()
1212*/
1213
1214QCheckBox* QMessageBox::checkBox() const
1215{
1216 Q_D(const QMessageBox);
1217 return d->checkbox;
1218}
1219
1220/*!
1221 \property QMessageBox::text
1222 \brief the message box text to be displayed.
1223
1224 The text will be interpreted either as a plain text or as rich text,
1225 depending on the text format setting (\l QMessageBox::textFormat).
1226 The default setting is Qt::AutoText, i.e., the message box will try
1227 to auto-detect the format of the text.
1228
1229 The default value of this property is an empty string.
1230
1231 \sa textFormat, QMessageBox::informativeText, QMessageBox::detailedText
1232*/
1233QString QMessageBox::text() const
1234{
1235 Q_D(const QMessageBox);
1236 return d->label->text();
1237}
1238
1239void QMessageBox::setText(const QString &text)
1240{
1241 Q_D(QMessageBox);
1242 d->label->setText(text);
1243 d->label->setWordWrap(d->label->textFormat() == Qt::RichText
1244 || (d->label->textFormat() == Qt::AutoText && Qt::mightBeRichText(text)));
1245 d->updateSize();
1246}
1247
1248/*!
1249 \enum QMessageBox::Icon
1250
1251 This enum has the following values:
1252
1253 \value NoIcon the message box does not have any icon.
1254
1255 \value Question an icon indicating that
1256 the message is asking a question.
1257
1258 \value Information an icon indicating that
1259 the message is nothing out of the ordinary.
1260
1261 \value Warning an icon indicating that the
1262 message is a warning, but can be dealt with.
1263
1264 \value Critical an icon indicating that
1265 the message represents a critical problem.
1266
1267*/
1268
1269/*!
1270 \property QMessageBox::icon
1271 \brief the message box's icon
1272
1273 The icon of the message box can be specified with one of the
1274 values:
1275
1276 \list
1277 \li QMessageBox::NoIcon
1278 \li QMessageBox::Question
1279 \li QMessageBox::Information
1280 \li QMessageBox::Warning
1281 \li QMessageBox::Critical
1282 \endlist
1283
1284 The default is QMessageBox::NoIcon.
1285
1286 The pixmap used to display the actual icon depends on the current
1287 \l{QWidget::style()} {GUI style}. You can also set a custom pixmap
1288 for the icon by setting the \l{QMessageBox::iconPixmap} {icon
1289 pixmap} property.
1290
1291 \sa iconPixmap
1292*/
1293QMessageBox::Icon QMessageBox::icon() const
1294{
1295 Q_D(const QMessageBox);
1296 return d->icon;
1297}
1298
1299void QMessageBox::setIcon(Icon icon)
1300{
1301 Q_D(QMessageBox);
1302 setIconPixmap(QMessageBoxPrivate::standardIcon((QMessageBox::Icon)icon,
1303 this));
1304 d->icon = icon;
1305}
1306
1307/*!
1308 \property QMessageBox::iconPixmap
1309 \brief the current icon
1310
1311 The icon currently used by the message box. Note that it's often
1312 hard to draw one pixmap that looks appropriate in all GUI styles;
1313 you may want to supply a different pixmap for each platform.
1314
1315 By default, this property is undefined.
1316
1317 \sa icon
1318*/
1319QPixmap QMessageBox::iconPixmap() const
1320{
1321 Q_D(const QMessageBox);
1322 return d->iconLabel->pixmap(Qt::ReturnByValue);
1323}
1324
1325void QMessageBox::setIconPixmap(const QPixmap &pixmap)
1326{
1327 Q_D(QMessageBox);
1328 d->iconLabel->setPixmap(pixmap);
1329 d->icon = NoIcon;
1330 d->setupLayout();
1331}
1332
1333/*!
1334 \property QMessageBox::textFormat
1335 \brief the format of the text displayed by the message box
1336
1337 The current text format used by the message box. See the \l
1338 Qt::TextFormat enum for an explanation of the possible options.
1339
1340 The default format is Qt::AutoText.
1341
1342 \sa setText()
1343*/
1344Qt::TextFormat QMessageBox::textFormat() const
1345{
1346 Q_D(const QMessageBox);
1347 return d->label->textFormat();
1348}
1349
1350void QMessageBox::setTextFormat(Qt::TextFormat format)
1351{
1352 Q_D(QMessageBox);
1353 d->label->setTextFormat(format);
1354 d->label->setWordWrap(format == Qt::RichText
1355 || (format == Qt::AutoText && Qt::mightBeRichText(d->label->text())));
1356 d->updateSize();
1357}
1358
1359/*!
1360 \property QMessageBox::textInteractionFlags
1361 \since 5.1
1362
1363 Specifies how the label of the message box should interact with user
1364 input.
1365
1366 The default value depends on the style.
1367
1368 \sa QStyle::SH_MessageBox_TextInteractionFlags
1369*/
1370
1371Qt::TextInteractionFlags QMessageBox::textInteractionFlags() const
1372{
1373 Q_D(const QMessageBox);
1374 return d->label->textInteractionFlags();
1375}
1376
1377void QMessageBox::setTextInteractionFlags(Qt::TextInteractionFlags flags)
1378{
1379 Q_D(QMessageBox);
1380 d->label->setTextInteractionFlags(flags);
1381}
1382
1383/*!
1384 \reimp
1385*/
1386bool QMessageBox::event(QEvent *e)
1387{
1388 bool result =QDialog::event(e);
1389 switch (e->type()) {
1390 case QEvent::LayoutRequest:
1391 d_func()->updateSize();
1392 break;
1393 case QEvent::LanguageChange:
1394 d_func()->retranslateStrings();
1395 break;
1396 default:
1397 break;
1398 }
1399 return result;
1400}
1401
1402/*!
1403 \reimp
1404*/
1405void QMessageBox::resizeEvent(QResizeEvent *event)
1406{
1407 QDialog::resizeEvent(event);
1408}
1409
1410/*!
1411 \reimp
1412*/
1413void QMessageBox::closeEvent(QCloseEvent *e)
1414{
1415 Q_D(QMessageBox);
1416 if (!d->detectedEscapeButton) {
1417 e->ignore();
1418 return;
1419 }
1420 QDialog::closeEvent(e);
1421 d->clickedButton = d->detectedEscapeButton;
1422 setResult(d->execReturnCode(d->detectedEscapeButton));
1423}
1424
1425/*!
1426 \reimp
1427*/
1428void QMessageBox::changeEvent(QEvent *ev)
1429{
1430 Q_D(QMessageBox);
1431 switch (ev->type()) {
1432 case QEvent::StyleChange:
1433 {
1434 if (d->icon != NoIcon)
1435 setIcon(d->icon);
1436 Qt::TextInteractionFlags flags(style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, nullptr, this));
1437 d->label->setTextInteractionFlags(flags);
1438 d->buttonBox->setCenterButtons(style()->styleHint(QStyle::SH_MessageBox_CenterButtons, nullptr, this));
1439 if (d->informativeLabel)
1440 d->informativeLabel->setTextInteractionFlags(flags);
1441 Q_FALLTHROUGH();
1442 }
1443 case QEvent::FontChange:
1444 case QEvent::ApplicationFontChange:
1445#ifdef Q_OS_MAC
1446 {
1447 QFont f = font();
1448 f.setBold(true);
1449 d->label->setFont(f);
1450 }
1451#endif
1452 Q_FALLTHROUGH();
1453 default:
1454 break;
1455 }
1456 QDialog::changeEvent(ev);
1457}
1458
1459/*!
1460 \reimp
1461*/
1462void QMessageBox::keyPressEvent(QKeyEvent *e)
1463{
1464#if QT_CONFIG(shortcut)
1465 Q_D(QMessageBox);
1466 if (e->matches(QKeySequence::Cancel)) {
1467 if (d->detectedEscapeButton) {
1468#ifdef Q_OS_MAC
1469 d->detectedEscapeButton->animateClick();
1470#else
1471 d->detectedEscapeButton->click();
1472#endif
1473 }
1474 return;
1475 }
1476#endif // QT_CONFIG(shortcut)
1477
1478#if !defined(QT_NO_CLIPBOARD) && !defined(QT_NO_SHORTCUT)
1479
1480#if QT_CONFIG(textedit)
1481 if (e == QKeySequence::Copy) {
1482 if (d->detailsText && d->detailsText->isVisible() && d->detailsText->copy()) {
1483 e->setAccepted(true);
1484 return;
1485 }
1486 } else if (e == QKeySequence::SelectAll && d->detailsText && d->detailsText->isVisible()) {
1487 d->detailsText->selectAll();
1488 e->setAccepted(true);
1489 return;
1490 }
1491#endif // QT_CONFIG(textedit)
1492
1493#if defined(Q_OS_WIN)
1494 if (e == QKeySequence::Copy) {
1495 const QLatin1String separator("---------------------------\n");
1496 QString textToCopy;
1497 textToCopy += separator + windowTitle() + QLatin1Char('\n') + separator // title
1498 + d->label->text() + QLatin1Char('\n') + separator; // text
1499
1500 if (d->informativeLabel)
1501 textToCopy += d->informativeLabel->text() + QLatin1Char('\n') + separator;
1502
1503 const QList<QAbstractButton *> buttons = d->buttonBox->buttons();
1504 for (const auto *button : buttons)
1505 textToCopy += button->text() + QLatin1String(" ");
1506 textToCopy += QLatin1Char('\n') + separator;
1507#if QT_CONFIG(textedit)
1508 if (d->detailsText)
1509 textToCopy += d->detailsText->text() + QLatin1Char('\n') + separator;
1510#endif
1511 QGuiApplication::clipboard()->setText(textToCopy);
1512 return;
1513 }
1514#endif // Q_OS_WIN
1515
1516#endif // !QT_NO_CLIPBOARD && !QT_NO_SHORTCUT
1517
1518#ifndef QT_NO_SHORTCUT
1519 if (!(e->modifiers() & (Qt::AltModifier | Qt::ControlModifier | Qt::MetaModifier))) {
1520 int key = e->key() & ~Qt::MODIFIER_MASK;
1521 if (key) {
1522 const QList<QAbstractButton *> buttons = d->buttonBox->buttons();
1523 for (auto *pb : buttons) {
1524 QKeySequence shortcut = pb->shortcut();
1525 if (!shortcut.isEmpty() && key == shortcut[0].key()) {
1526 pb->animateClick();
1527 return;
1528 }
1529 }
1530 }
1531 }
1532#endif
1533 QDialog::keyPressEvent(e);
1534}
1535
1536/*!
1537 Opens the dialog and connects its finished() or buttonClicked() signal to
1538 the slot specified by \a receiver and \a member. If the slot in \a member
1539 has a pointer for its first parameter the connection is to buttonClicked(),
1540 otherwise the connection is to finished().
1541
1542 The signal will be disconnected from the slot when the dialog is closed.
1543*/
1544void QMessageBox::open(QObject *receiver, const char *member)
1545{
1546 Q_D(QMessageBox);
1547 const char *signal = member && strchr(member, '*') ? SIGNAL(buttonClicked(QAbstractButton*))
1548 : SIGNAL(finished(int));
1549 connect(this, signal, receiver, member);
1550 d->signalToDisconnectOnClose = signal;
1551 d->receiverToDisconnectOnClose = receiver;
1552 d->memberToDisconnectOnClose = member;
1553 QDialog::open();
1554}
1555
1556/*!
1557 \since 4.5
1558
1559 Returns a list of all the buttons that have been added to the message box.
1560
1561 \sa buttonRole(), addButton(), removeButton()
1562*/
1563QList<QAbstractButton *> QMessageBox::buttons() const
1564{
1565 Q_D(const QMessageBox);
1566 return d->buttonBox->buttons();
1567}
1568
1569/*!
1570 \since 4.5
1571
1572 Returns the button role for the specified \a button. This function returns
1573 \l InvalidRole if \a button is \nullptr or has not been added to the message box.
1574
1575 \sa buttons(), addButton()
1576*/
1577QMessageBox::ButtonRole QMessageBox::buttonRole(QAbstractButton *button) const
1578{
1579 Q_D(const QMessageBox);
1580 return QMessageBox::ButtonRole(d->buttonBox->buttonRole(button));
1581}
1582
1583/*!
1584 \reimp
1585*/
1586void QMessageBox::showEvent(QShowEvent *e)
1587{
1588 Q_D(QMessageBox);
1589 if (d->autoAddOkButton) {
1590 addButton(Ok);
1591 }
1592 if (d->detailsButton)
1593 addButton(d->detailsButton, QMessageBox::ActionRole);
1594 d->detectEscapeButton();
1595 d->updateSize();
1596
1597#ifndef QT_NO_ACCESSIBILITY
1598 QAccessibleEvent event(this, QAccessible::Alert);
1599 QAccessible::updateAccessibility(&event);
1600#endif
1601#if defined(Q_OS_WIN)
1602 if (const HMENU systemMenu = qt_getWindowsSystemMenu(this)) {
1603 EnableMenuItem(systemMenu, SC_CLOSE, d->detectedEscapeButton ?
1604 MF_BYCOMMAND|MF_ENABLED : MF_BYCOMMAND|MF_GRAYED);
1605 }
1606#endif
1607 QDialog::showEvent(e);
1608}
1609
1610
1611static QMessageBox::StandardButton showNewMessageBox(QWidget *parent,
1612 QMessageBox::Icon icon,
1613 const QString& title, const QString& text,
1614 QMessageBox::StandardButtons buttons,
1615 QMessageBox::StandardButton defaultButton)
1616{
1617 // necessary for source compatibility with Qt 4.0 and 4.1
1618 // handles (Yes, No) and (Yes|Default, No)
1619 if (defaultButton && !(buttons & defaultButton))
1620 return (QMessageBox::StandardButton)
1621 QMessageBoxPrivate::showOldMessageBox(parent, icon, title,
1622 text, int(buttons),
1623 int(defaultButton), 0);
1624
1625 QMessageBox msgBox(icon, title, text, QMessageBox::NoButton, parent);
1626 QDialogButtonBox *buttonBox = msgBox.findChild<QDialogButtonBox*>();
1627 Q_ASSERT(buttonBox != nullptr);
1628
1629 uint mask = QMessageBox::FirstButton;
1630 while (mask <= QMessageBox::LastButton) {
1631 uint sb = buttons & mask;
1632 mask <<= 1;
1633 if (!sb)
1634 continue;
1635 QPushButton *button = msgBox.addButton((QMessageBox::StandardButton)sb);
1636 // Choose the first accept role as the default
1637 if (msgBox.defaultButton())
1638 continue;
1639 if ((defaultButton == QMessageBox::NoButton && buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole)
1640 || (defaultButton != QMessageBox::NoButton && sb == uint(defaultButton)))
1641 msgBox.setDefaultButton(button);
1642 }
1643 if (msgBox.exec() == -1)
1644 return QMessageBox::Cancel;
1645 return msgBox.standardButton(msgBox.clickedButton());
1646}
1647
1648/*!
1649 \since 4.2
1650
1651 Opens an information message box with the given \a title and
1652 \a text in front of the specified \a parent widget.
1653
1654 The standard \a buttons are added to the message box.
1655 \a defaultButton specifies the button used when \uicontrol Enter is pressed.
1656 \a defaultButton must refer to a button that was given in \a buttons.
1657 If \a defaultButton is QMessageBox::NoButton, QMessageBox
1658 chooses a suitable default automatically.
1659
1660 Returns the identity of the standard button that was clicked. If
1661 \uicontrol Esc was pressed instead, the \l{Default and Escape Keys}
1662 {escape button} is returned.
1663
1664 The message box is an \l{Qt::ApplicationModal}{application modal}
1665 dialog box.
1666
1667 \warning Do not delete \a parent during the execution of the dialog.
1668 If you want to do this, you should create the dialog
1669 yourself using one of the QMessageBox constructors.
1670
1671 \sa question(), warning(), critical()
1672*/
1673QMessageBox::StandardButton QMessageBox::information(QWidget *parent, const QString &title,
1674 const QString& text, StandardButtons buttons,
1675 StandardButton defaultButton)
1676{
1677 return showNewMessageBox(parent, Information, title, text, buttons,
1678 defaultButton);
1679}
1680
1681
1682/*!
1683 \since 4.2
1684
1685 Opens a question message box with the given \a title and \a
1686 text in front of the specified \a parent widget.
1687
1688 The standard \a buttons are added to the message box. \a
1689 defaultButton specifies the button used when \uicontrol Enter is
1690 pressed. \a defaultButton must refer to a button that was given in \a buttons.
1691 If \a defaultButton is QMessageBox::NoButton, QMessageBox
1692 chooses a suitable default automatically.
1693
1694 Returns the identity of the standard button that was clicked. If
1695 \uicontrol Esc was pressed instead, the \l{Default and Escape Keys}
1696 {escape button} is returned.
1697
1698 The message box is an \l{Qt::ApplicationModal} {application modal}
1699 dialog box.
1700
1701 \warning Do not delete \a parent during the execution of the dialog.
1702 If you want to do this, you should create the dialog
1703 yourself using one of the QMessageBox constructors.
1704
1705 \sa information(), warning(), critical()
1706*/
1707QMessageBox::StandardButton QMessageBox::question(QWidget *parent, const QString &title,
1708 const QString& text, StandardButtons buttons,
1709 StandardButton defaultButton)
1710{
1711 return showNewMessageBox(parent, Question, title, text, buttons, defaultButton);
1712}
1713
1714/*!
1715 \since 4.2
1716
1717 Opens a warning message box with the given \a title and \a
1718 text in front of the specified \a parent widget.
1719
1720 The standard \a buttons are added to the message box. \a
1721 defaultButton specifies the button used when \uicontrol Enter is
1722 pressed. \a defaultButton must refer to a button that was given in \a buttons.
1723 If \a defaultButton is QMessageBox::NoButton, QMessageBox
1724 chooses a suitable default automatically.
1725
1726 Returns the identity of the standard button that was clicked. If
1727 \uicontrol Esc was pressed instead, the \l{Default and Escape Keys}
1728 {escape button} is returned.
1729
1730 The message box is an \l{Qt::ApplicationModal} {application modal}
1731 dialog box.
1732
1733 \warning Do not delete \a parent during the execution of the dialog.
1734 If you want to do this, you should create the dialog
1735 yourself using one of the QMessageBox constructors.
1736
1737 \sa question(), information(), critical()
1738*/
1739QMessageBox::StandardButton QMessageBox::warning(QWidget *parent, const QString &title,
1740 const QString& text, StandardButtons buttons,
1741 StandardButton defaultButton)
1742{
1743 return showNewMessageBox(parent, Warning, title, text, buttons, defaultButton);
1744}
1745
1746/*!
1747 \since 4.2
1748
1749 Opens a critical message box with the given \a title and \a
1750 text in front of the specified \a parent widget.
1751
1752 The standard \a buttons are added to the message box. \a
1753 defaultButton specifies the button used when \uicontrol Enter is
1754 pressed. \a defaultButton must refer to a button that was given in \a buttons.
1755 If \a defaultButton is QMessageBox::NoButton, QMessageBox
1756 chooses a suitable default automatically.
1757
1758 Returns the identity of the standard button that was clicked. If
1759 \uicontrol Esc was pressed instead, the \l{Default and Escape Keys}
1760 {escape button} is returned.
1761
1762 The message box is an \l{Qt::ApplicationModal} {application modal}
1763 dialog box.
1764
1765 \warning Do not delete \a parent during the execution of the dialog.
1766 If you want to do this, you should create the dialog
1767 yourself using one of the QMessageBox constructors.
1768
1769 \sa question(), warning(), information()
1770*/
1771QMessageBox::StandardButton QMessageBox::critical(QWidget *parent, const QString &title,
1772 const QString& text, StandardButtons buttons,
1773 StandardButton defaultButton)
1774{
1775 return showNewMessageBox(parent, Critical, title, text, buttons, defaultButton);
1776}
1777
1778/*!
1779 Displays a simple about box with title \a title and text \a
1780 text. The about box's parent is \a parent.
1781
1782 about() looks for a suitable icon in four locations:
1783
1784 \list 1
1785 \li It prefers \l{QWidget::windowIcon()}{parent->icon()}
1786 if that exists.
1787 \li If not, it tries the top-level widget containing \a parent.
1788 \li If that fails, it tries the \l{QApplication::activeWindow()}{active window.}
1789 \li As a last resort it uses the Information icon.
1790 \endlist
1791
1792 The about box has a single button labelled "OK". On \macos, the
1793 about box is popped up as a modeless window; on other platforms,
1794 it is currently application modal.
1795
1796 \sa QWidget::windowIcon(), QApplication::activeWindow()
1797*/
1798void QMessageBox::about(QWidget *parent, const QString &title, const QString &text)
1799{
1800#ifdef Q_OS_MAC
1801 static QPointer<QMessageBox> oldMsgBox;
1802
1803 if (oldMsgBox && oldMsgBox->text() == text) {
1804 oldMsgBox->show();
1805 oldMsgBox->raise();
1806 oldMsgBox->activateWindow();
1807 return;
1808 }
1809#endif
1810
1811 QMessageBox *msgBox = new QMessageBox(title, text, Information, 0, 0, 0, parent
1812#ifdef Q_OS_MAC
1813 , Qt::WindowTitleHint | Qt::WindowSystemMenuHint
1814#endif
1815 );
1816 msgBox->setAttribute(Qt::WA_DeleteOnClose);
1817 QIcon icon = msgBox->windowIcon();
1818 QSize size = icon.actualSize(QSize(64, 64));
1819 msgBox->setIconPixmap(icon.pixmap(size));
1820
1821 // should perhaps be a style hint
1822#ifdef Q_OS_MAC
1823 oldMsgBox = msgBox;
1824#if 0
1825 // ### doesn't work until close button is enabled in title bar
1826 msgBox->d_func()->autoAddOkButton = false;
1827#else
1828 msgBox->d_func()->buttonBox->setCenterButtons(true);
1829#endif
1830 msgBox->show();
1831#else
1832 msgBox->exec();
1833#endif
1834}
1835
1836/*!
1837 Displays a simple message box about Qt, with the given \a title
1838 and centered over \a parent (if \a parent is not \nullptr). The message
1839 includes the version number of Qt being used by the application.
1840
1841 This is useful for inclusion in the \uicontrol Help menu of an application,
1842 as shown in the \l{mainwindows/menus}{Menus} example.
1843
1844 QApplication provides this functionality as a slot.
1845
1846 On \macos, the about box is popped up as a modeless window; on
1847 other platforms, it is currently application modal.
1848
1849 \sa QApplication::aboutQt()
1850*/
1851void QMessageBox::aboutQt(QWidget *parent, const QString &title)
1852{
1853#ifdef Q_OS_MAC
1854 static QPointer<QMessageBox> oldMsgBox;
1855
1856 if (oldMsgBox) {
1857 oldMsgBox->show();
1858 oldMsgBox->raise();
1859 oldMsgBox->activateWindow();
1860 return;
1861 }
1862#endif
1863
1864 QString translatedTextAboutQtCaption;
1865 translatedTextAboutQtCaption = QMessageBox::tr(
1866 "<h3>About Qt</h3>"
1867 "<p>This program uses Qt version %1.</p>"
1868 ).arg(QLatin1String(QT_VERSION_STR));
1869 //: Leave this text untranslated or include a verbatim copy of it below
1870 //: and note that it is the authoritative version in case of doubt.
1871 const QString translatedTextAboutQtText = QMessageBox::tr(
1872 "<p>Qt is a C++ toolkit for cross-platform application "
1873 "development.</p>"
1874 "<p>Qt provides single-source portability across all major desktop "
1875 "operating systems. It is also available for embedded Linux and other "
1876 "embedded and mobile operating systems.</p>"
1877 "<p>Qt is available under multiple licensing options designed "
1878 "to accommodate the needs of our various users.</p>"
1879 "<p>Qt licensed under our commercial license agreement is appropriate "
1880 "for development of proprietary/commercial software where you do not "
1881 "want to share any source code with third parties or otherwise cannot "
1882 "comply with the terms of GNU (L)GPL.</p>"
1883 "<p>Qt licensed under GNU (L)GPL is appropriate for the "
1884 "development of Qt&nbsp;applications provided you can comply with the terms "
1885 "and conditions of the respective licenses.</p>"
1886 "<p>Please see <a href=\"http://%2/\">%2</a> "
1887 "for an overview of Qt licensing.</p>"
1888 "<p>Copyright (C) %1 The Qt Company Ltd and other "
1889 "contributors.</p>"
1890 "<p>Qt and the Qt logo are trademarks of The Qt Company Ltd.</p>"
1891 "<p>Qt is The Qt Company Ltd product developed as an open source "
1892 "project. See <a href=\"http://%3/\">%3</a> for more information.</p>"
1893 ).arg(QStringLiteral("2020"),
1894 QStringLiteral("qt.io/licensing"),
1895 QStringLiteral("qt.io"));
1896 QMessageBox *msgBox = new QMessageBox(parent);
1897 msgBox->setAttribute(Qt::WA_DeleteOnClose);
1898 msgBox->setWindowTitle(title.isEmpty() ? tr("About Qt") : title);
1899 msgBox->setText(translatedTextAboutQtCaption);
1900 msgBox->setInformativeText(translatedTextAboutQtText);
1901
1902 QPixmap pm(QLatin1String(":/qt-project.org/qmessagebox/images/qtlogo-64.png"));
1903 if (!pm.isNull())
1904 msgBox->setIconPixmap(pm);
1905
1906 // should perhaps be a style hint
1907#ifdef Q_OS_MAC
1908 oldMsgBox = msgBox;
1909#if 0
1910 // ### doesn't work until close button is enabled in title bar
1911 msgBox->d_func()->autoAddOkButton = false;
1912#else
1913 msgBox->d_func()->buttonBox->setCenterButtons(true);
1914#endif
1915 msgBox->show();
1916#else
1917 msgBox->exec();
1918#endif
1919}
1920
1921/////////////////////////////////////////////////////////////////////////////////////////
1922// Source and binary compatibility routines for 4.0 and 4.1
1923
1924static QMessageBox::StandardButton newButton(int button)
1925{
1926 // this is needed for source compatibility with Qt 4.0 and 4.1
1927 if (button == QMessageBox::NoButton || (button & NewButtonMask))
1928 return QMessageBox::StandardButton(button & QMessageBox::ButtonMask);
1929
1930#if QT_VERSION < 0x050000
1931 // this is needed for binary compatibility with Qt 4.0 and 4.1
1932 switch (button & Old_ButtonMask) {
1933 case Old_Ok:
1934 return QMessageBox::Ok;
1935 case Old_Cancel:
1936 return QMessageBox::Cancel;
1937 case Old_Yes:
1938 return QMessageBox::Yes;
1939 case Old_No:
1940 return QMessageBox::No;
1941 case Old_Abort:
1942 return QMessageBox::Abort;
1943 case Old_Retry:
1944 return QMessageBox::Retry;
1945 case Old_Ignore:
1946 return QMessageBox::Ignore;
1947 case Old_YesAll:
1948 return QMessageBox::YesToAll;
1949 case Old_NoAll:
1950 return QMessageBox::NoToAll;
1951 default:
1952 return QMessageBox::NoButton;
1953 }
1954#else
1955 return QMessageBox::NoButton;
1956#endif
1957}
1958
1959static bool detectedCompat(int button0, int button1, int button2)
1960{
1961 if (button0 != 0 && !(button0 & NewButtonMask))
1962 return true;
1963 if (button1 != 0 && !(button1 & NewButtonMask))
1964 return true;
1965 if (button2 != 0 && !(button2 & NewButtonMask))
1966 return true;
1967 return false;
1968}
1969
1970QAbstractButton *QMessageBoxPrivate::findButton(int button0, int button1, int button2, int flags)
1971{
1972 Q_Q(QMessageBox);
1973 int button = 0;
1974
1975 if (button0 & flags) {
1976 button = button0;
1977 } else if (button1 & flags) {
1978 button = button1;
1979 } else if (button2 & flags) {
1980 button = button2;
1981 }
1982 return q->button(newButton(button));
1983}
1984
1985void QMessageBoxPrivate::addOldButtons(int button0, int button1, int button2)
1986{
1987 Q_Q(QMessageBox);
1988 q->addButton(newButton(button0));
1989 q->addButton(newButton(button1));
1990 q->addButton(newButton(button2));
1991 q->setDefaultButton(
1992 static_cast<QPushButton *>(findButton(button0, button1, button2, QMessageBox::Default)));
1993 q->setEscapeButton(findButton(button0, button1, button2, QMessageBox::Escape));
1994 compatMode = detectedCompat(button0, button1, button2);
1995}
1996
1997QAbstractButton *QMessageBoxPrivate::abstractButtonForId(int id) const
1998{
1999 Q_Q(const QMessageBox);
2000 QAbstractButton *result = customButtonList.value(id);
2001 if (result)
2002 return result;
2003 if (id & QMessageBox::FlagMask) // for compatibility with Qt 4.0/4.1 (even if it is silly)
2004 return nullptr;
2005 return q->button(newButton(id));
2006}
2007
2008int QMessageBoxPrivate::showOldMessageBox(QWidget *parent, QMessageBox::Icon icon,
2009 const QString &title, const QString &text,
2010 int button0, int button1, int button2)
2011{
2012 QMessageBox messageBox(icon, title, text, QMessageBox::NoButton, parent);
2013 messageBox.d_func()->addOldButtons(button0, button1, button2);
2014 return messageBox.exec();
2015}
2016
2017int QMessageBoxPrivate::showOldMessageBox(QWidget *parent, QMessageBox::Icon icon,
2018 const QString &title, const QString &text,
2019 const QString &button0Text,
2020 const QString &button1Text,
2021 const QString &button2Text,
2022 int defaultButtonNumber,
2023 int escapeButtonNumber)
2024{
2025 QMessageBox messageBox(icon, title, text, QMessageBox::NoButton, parent);
2026 QString myButton0Text = button0Text;
2027 if (myButton0Text.isEmpty())
2028 myButton0Text = QDialogButtonBox::tr("OK");
2029 messageBox.addButton(myButton0Text, QMessageBox::ActionRole);
2030 if (!button1Text.isEmpty())
2031 messageBox.addButton(button1Text, QMessageBox::ActionRole);
2032 if (!button2Text.isEmpty())
2033 messageBox.addButton(button2Text, QMessageBox::ActionRole);
2034
2035 const QList<QAbstractButton *> &buttonList = messageBox.d_func()->customButtonList;
2036 messageBox.setDefaultButton(static_cast<QPushButton *>(buttonList.value(defaultButtonNumber)));
2037 messageBox.setEscapeButton(buttonList.value(escapeButtonNumber));
2038
2039 return messageBox.exec();
2040}
2041
2042void QMessageBoxPrivate::retranslateStrings()
2043{
2044#if QT_CONFIG(textedit)
2045 if (detailsButton)
2046 detailsButton->setLabel(detailsText->isHidden() ? ShowLabel : HideLabel);
2047#endif
2048}
2049
2050/*!
2051 \obsolete
2052
2053 Constructs a message box with a \a title, a \a text, an \a icon,
2054 and up to three buttons.
2055
2056 The \a icon must be one of the following:
2057 \list
2058 \li QMessageBox::NoIcon
2059 \li QMessageBox::Question
2060 \li QMessageBox::Information
2061 \li QMessageBox::Warning
2062 \li QMessageBox::Critical
2063 \endlist
2064
2065 Each button, \a button0, \a button1 and \a button2, can have one
2066 of the following values:
2067 \list
2068 \li QMessageBox::NoButton
2069 \li QMessageBox::Ok
2070 \li QMessageBox::Cancel
2071 \li QMessageBox::Yes
2072 \li QMessageBox::No
2073 \li QMessageBox::Abort
2074 \li QMessageBox::Retry
2075 \li QMessageBox::Ignore
2076 \li QMessageBox::YesAll
2077 \li QMessageBox::NoAll
2078 \endlist
2079
2080 Use QMessageBox::NoButton for the later parameters to have fewer
2081 than three buttons in your message box. If you don't specify any
2082 buttons at all, QMessageBox will provide an Ok button.
2083
2084 One of the buttons can be OR-ed with the QMessageBox::Default
2085 flag to make it the default button (clicked when Enter is
2086 pressed).
2087
2088 One of the buttons can be OR-ed with the QMessageBox::Escape flag
2089 to make it the cancel or close button (clicked when \uicontrol Esc is
2090 pressed).
2091
2092 \snippet dialogs/dialogs.cpp 2
2093
2094 The message box is an \l{Qt::ApplicationModal} {application modal}
2095 dialog box.
2096
2097 The \a parent and \a f arguments are passed to
2098 the QDialog constructor.
2099
2100 \sa setWindowTitle(), setText(), setIcon()
2101*/
2102QMessageBox::QMessageBox(const QString &title, const QString &text, Icon icon,
2103 int button0, int button1, int button2, QWidget *parent,
2104 Qt::WindowFlags f)
2105 : QDialog(*new QMessageBoxPrivate, parent,
2106 f /*| Qt::MSWindowsFixedSizeDialogHint #### */| Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
2107{
2108 Q_D(QMessageBox);
2109 d->init(title, text);
2110 setIcon(icon);
2111 d->addOldButtons(button0, button1, button2);
2112}
2113
2114/*!
2115 \obsolete
2116
2117 Opens an information message box with the given \a title and the
2118 \a text. The dialog may have up to three buttons. Each of the
2119 buttons, \a button0, \a button1 and \a button2 may be set to one
2120 of the following values:
2121
2122 \list
2123 \li QMessageBox::NoButton
2124 \li QMessageBox::Ok
2125 \li QMessageBox::Cancel
2126 \li QMessageBox::Yes
2127 \li QMessageBox::No
2128 \li QMessageBox::Abort
2129 \li QMessageBox::Retry
2130 \li QMessageBox::Ignore
2131 \li QMessageBox::YesAll
2132 \li QMessageBox::NoAll
2133 \endlist
2134
2135 If you don't want all three buttons, set the last button, or last
2136 two buttons to QMessageBox::NoButton.
2137
2138 One button can be OR-ed with QMessageBox::Default, and one
2139 button can be OR-ed with QMessageBox::Escape.
2140
2141 Returns the identity (QMessageBox::Ok, or QMessageBox::No, etc.)
2142 of the button that was clicked.
2143
2144 The message box is an \l{Qt::ApplicationModal} {application modal}
2145 dialog box.
2146
2147 \warning Do not delete \a parent during the execution of the dialog.
2148 If you want to do this, you should create the dialog
2149 yourself using one of the QMessageBox constructors.
2150
2151 \sa question(), warning(), critical()
2152*/
2153int QMessageBox::information(QWidget *parent, const QString &title, const QString& text,
2154 int button0, int button1, int button2)
2155{
2156 return QMessageBoxPrivate::showOldMessageBox(parent, Information, title, text,
2157 button0, button1, button2);
2158}
2159
2160/*!
2161 \obsolete
2162 \overload
2163
2164 Displays an information message box with the given \a title and
2165 \a text, as well as one, two or three buttons. Returns the index
2166 of the button that was clicked (0, 1 or 2).
2167
2168 \a button0Text is the text of the first button, and is optional.
2169 If \a button0Text is not supplied, "OK" (translated) will be
2170 used. \a button1Text is the text of the second button, and is
2171 optional. \a button2Text is the text of the third button, and is
2172 optional. \a defaultButtonNumber (0, 1 or 2) is the index of the
2173 default button; pressing Return or Enter is the same as clicking
2174 the default button. It defaults to 0 (the first button). \a
2175 escapeButtonNumber is the index of the escape button; pressing
2176 \uicontrol Esc is the same as clicking this button. It defaults to -1;
2177 supply 0, 1 or 2 to make pressing \uicontrol Esc equivalent to clicking
2178 the relevant button.
2179
2180 The message box is an \l{Qt::ApplicationModal} {application modal}
2181 dialog box.
2182
2183 \warning Do not delete \a parent during the execution of the dialog.
2184 If you want to do this, you should create the dialog
2185 yourself using one of the QMessageBox constructors.
2186
2187 \sa question(), warning(), critical()
2188*/
2189
2190int QMessageBox::information(QWidget *parent, const QString &title, const QString& text,
2191 const QString& button0Text, const QString& button1Text,
2192 const QString& button2Text, int defaultButtonNumber,
2193 int escapeButtonNumber)
2194{
2195 return QMessageBoxPrivate::showOldMessageBox(parent, Information, title, text,
2196 button0Text, button1Text, button2Text,
2197 defaultButtonNumber, escapeButtonNumber);
2198}
2199
2200/*!
2201 \obsolete
2202
2203 Opens a question message box with the given \a title and \a text.
2204 The dialog may have up to three buttons. Each of the buttons, \a
2205 button0, \a button1 and \a button2 may be set to one of the
2206 following values:
2207
2208 \list
2209 \li QMessageBox::NoButton
2210 \li QMessageBox::Ok
2211 \li QMessageBox::Cancel
2212 \li QMessageBox::Yes
2213 \li QMessageBox::No
2214 \li QMessageBox::Abort
2215 \li QMessageBox::Retry
2216 \li QMessageBox::Ignore
2217 \li QMessageBox::YesAll
2218 \li QMessageBox::NoAll
2219 \endlist
2220
2221 If you don't want all three buttons, set the last button, or last
2222 two buttons to QMessageBox::NoButton.
2223
2224 One button can be OR-ed with QMessageBox::Default, and one
2225 button can be OR-ed with QMessageBox::Escape.
2226
2227 Returns the identity (QMessageBox::Yes, or QMessageBox::No, etc.)
2228 of the button that was clicked.
2229
2230 The message box is an \l{Qt::ApplicationModal} {application modal}
2231 dialog box.
2232
2233 \warning Do not delete \a parent during the execution of the dialog.
2234 If you want to do this, you should create the dialog
2235 yourself using one of the QMessageBox constructors.
2236
2237 \sa information(), warning(), critical()
2238*/
2239int QMessageBox::question(QWidget *parent, const QString &title, const QString& text,
2240 int button0, int button1, int button2)
2241{
2242 return QMessageBoxPrivate::showOldMessageBox(parent, Question, title, text,
2243 button0, button1, button2);
2244}
2245
2246/*!
2247 \obsolete
2248 \overload
2249
2250 Displays a question message box with the given \a title and \a
2251 text, as well as one, two or three buttons. Returns the index of
2252 the button that was clicked (0, 1 or 2).
2253
2254 \a button0Text is the text of the first button, and is optional.
2255 If \a button0Text is not supplied, "OK" (translated) will be used.
2256 \a button1Text is the text of the second button, and is optional.
2257 \a button2Text is the text of the third button, and is optional.
2258 \a defaultButtonNumber (0, 1 or 2) is the index of the default
2259 button; pressing Return or Enter is the same as clicking the
2260 default button. It defaults to 0 (the first button). \a
2261 escapeButtonNumber is the index of the Escape button; pressing
2262 Escape is the same as clicking this button. It defaults to -1;
2263 supply 0, 1 or 2 to make pressing Escape equivalent to clicking
2264 the relevant button.
2265
2266 The message box is an \l{Qt::ApplicationModal} {application modal}
2267 dialog box.
2268
2269 \warning Do not delete \a parent during the execution of the dialog.
2270 If you want to do this, you should create the dialog
2271 yourself using one of the QMessageBox constructors.
2272
2273 \sa information(), warning(), critical()
2274*/
2275int QMessageBox::question(QWidget *parent, const QString &title, const QString& text,
2276 const QString& button0Text, const QString& button1Text,
2277 const QString& button2Text, int defaultButtonNumber,
2278 int escapeButtonNumber)
2279{
2280 return QMessageBoxPrivate::showOldMessageBox(parent, Question, title, text,
2281 button0Text, button1Text, button2Text,
2282 defaultButtonNumber, escapeButtonNumber);
2283}
2284
2285
2286/*!
2287 \obsolete
2288
2289 Opens a warning message box with the given \a title and \a text.
2290 The dialog may have up to three buttons. Each of the button
2291 parameters, \a button0, \a button1 and \a button2 may be set to
2292 one of the following values:
2293
2294 \list
2295 \li QMessageBox::NoButton
2296 \li QMessageBox::Ok
2297 \li QMessageBox::Cancel
2298 \li QMessageBox::Yes
2299 \li QMessageBox::No
2300 \li QMessageBox::Abort
2301 \li QMessageBox::Retry
2302 \li QMessageBox::Ignore
2303 \li QMessageBox::YesAll
2304 \li QMessageBox::NoAll
2305 \endlist
2306
2307 If you don't want all three buttons, set the last button, or last
2308 two buttons to QMessageBox::NoButton.
2309
2310 One button can be OR-ed with QMessageBox::Default, and one
2311 button can be OR-ed with QMessageBox::Escape.
2312
2313 Returns the identity (QMessageBox::Ok or QMessageBox::No or ...)
2314 of the button that was clicked.
2315
2316 The message box is an \l{Qt::ApplicationModal} {application modal}
2317 dialog box.
2318
2319 \warning Do not delete \a parent during the execution of the dialog.
2320 If you want to do this, you should create the dialog
2321 yourself using one of the QMessageBox constructors.
2322
2323 \sa information(), question(), critical()
2324*/
2325int QMessageBox::warning(QWidget *parent, const QString &title, const QString& text,
2326 int button0, int button1, int button2)
2327{
2328 return QMessageBoxPrivate::showOldMessageBox(parent, Warning, title, text,
2329 button0, button1, button2);
2330}
2331
2332/*!
2333 \obsolete
2334 \overload
2335
2336 Displays a warning message box with the given \a title and \a
2337 text, as well as one, two, or three buttons. Returns the number
2338 of the button that was clicked (0, 1, or 2).
2339
2340 \a button0Text is the text of the first button, and is optional.
2341 If \a button0Text is not supplied, "OK" (translated) will be used.
2342 \a button1Text is the text of the second button, and is optional,
2343 and \a button2Text is the text of the third button, and is
2344 optional. \a defaultButtonNumber (0, 1 or 2) is the index of the
2345 default button; pressing Return or Enter is the same as clicking
2346 the default button. It defaults to 0 (the first button). \a
2347 escapeButtonNumber is the index of the Escape button; pressing
2348 Escape is the same as clicking this button. It defaults to -1;
2349 supply 0, 1, or 2 to make pressing Escape equivalent to clicking
2350 the relevant button.
2351
2352 The message box is an \l{Qt::ApplicationModal} {application modal}
2353 dialog box.
2354
2355 \warning Do not delete \a parent during the execution of the dialog.
2356 If you want to do this, you should create the dialog
2357 yourself using one of the QMessageBox constructors.
2358
2359 \sa information(), question(), critical()
2360*/
2361int QMessageBox::warning(QWidget *parent, const QString &title, const QString& text,
2362 const QString& button0Text, const QString& button1Text,
2363 const QString& button2Text, int defaultButtonNumber,
2364 int escapeButtonNumber)
2365{
2366 return QMessageBoxPrivate::showOldMessageBox(parent, Warning, title, text,
2367 button0Text, button1Text, button2Text,
2368 defaultButtonNumber, escapeButtonNumber);
2369}
2370
2371/*!
2372 \obsolete
2373
2374 Opens a critical message box with the given \a title and \a text.
2375 The dialog may have up to three buttons. Each of the button
2376 parameters, \a button0, \a button1 and \a button2 may be set to
2377 one of the following values:
2378
2379 \list
2380 \li QMessageBox::NoButton
2381 \li QMessageBox::Ok
2382 \li QMessageBox::Cancel
2383 \li QMessageBox::Yes
2384 \li QMessageBox::No
2385 \li QMessageBox::Abort
2386 \li QMessageBox::Retry
2387 \li QMessageBox::Ignore
2388 \li QMessageBox::YesAll
2389 \li QMessageBox::NoAll
2390 \endlist
2391
2392 If you don't want all three buttons, set the last button, or last
2393 two buttons to QMessageBox::NoButton.
2394
2395 One button can be OR-ed with QMessageBox::Default, and one
2396 button can be OR-ed with QMessageBox::Escape.
2397
2398 Returns the identity (QMessageBox::Ok, or QMessageBox::No, etc.)
2399 of the button that was clicked.
2400
2401 The message box is an \l{Qt::ApplicationModal} {application modal}
2402 dialog box.
2403
2404 \warning Do not delete \a parent during the execution of the dialog.
2405 If you want to do this, you should create the dialog
2406 yourself using one of the QMessageBox constructors.
2407
2408 \sa information(), question(), warning()
2409*/
2410
2411int QMessageBox::critical(QWidget *parent, const QString &title, const QString& text,
2412 int button0, int button1, int button2)
2413{
2414 return QMessageBoxPrivate::showOldMessageBox(parent, Critical, title, text,
2415 button0, button1, button2);
2416}
2417
2418/*!
2419 \obsolete
2420 \overload
2421
2422 Displays a critical error message box with the given \a title and
2423 \a text, as well as one, two, or three buttons. Returns the
2424 number of the button that was clicked (0, 1 or 2).
2425
2426 \a button0Text is the text of the first button, and is optional.
2427 If \a button0Text is not supplied, "OK" (translated) will be used.
2428 \a button1Text is the text of the second button, and is optional,
2429 and \a button2Text is the text of the third button, and is
2430 optional. \a defaultButtonNumber (0, 1 or 2) is the index of the
2431 default button; pressing Return or Enter is the same as clicking
2432 the default button. It defaults to 0 (the first button). \a
2433 escapeButtonNumber is the index of the Escape button; pressing
2434 Escape is the same as clicking this button. It defaults to -1;
2435 supply 0, 1, or 2 to make pressing Escape equivalent to clicking
2436 the relevant button.
2437
2438 The message box is an \l{Qt::ApplicationModal} {application modal}
2439 dialog box.
2440
2441 \warning Do not delete \a parent during the execution of the dialog.
2442 If you want to do this, you should create the dialog
2443 yourself using one of the QMessageBox constructors.
2444
2445 \sa information(), question(), warning()
2446*/
2447int QMessageBox::critical(QWidget *parent, const QString &title, const QString& text,
2448 const QString& button0Text, const QString& button1Text,
2449 const QString& button2Text, int defaultButtonNumber,
2450 int escapeButtonNumber)
2451{
2452 return QMessageBoxPrivate::showOldMessageBox(parent, Critical, title, text,
2453 button0Text, button1Text, button2Text,
2454 defaultButtonNumber, escapeButtonNumber);
2455}
2456
2457
2458/*!
2459 \obsolete
2460
2461 Returns the text of the message box button \a button, or
2462 an empty string if the message box does not contain the button.
2463
2464 Use button() and QPushButton::text() instead.
2465*/
2466QString QMessageBox::buttonText(int button) const
2467{
2468 Q_D(const QMessageBox);
2469
2470 if (QAbstractButton *abstractButton = d->abstractButtonForId(button)) {
2471 return abstractButton->text();
2472 } else if (d->buttonBox->buttons().isEmpty() && (button == Ok || button == Old_Ok)) {
2473 // for compatibility with Qt 4.0/4.1
2474 return QDialogButtonBox::tr("OK");
2475 }
2476 return QString();
2477}
2478
2479/*!
2480 \obsolete
2481
2482 Sets the text of the message box button \a button to \a text.
2483 Setting the text of a button that is not in the message box is
2484 silently ignored.
2485
2486 Use addButton() instead.
2487*/
2488void QMessageBox::setButtonText(int button, const QString &text)
2489{
2490 Q_D(QMessageBox);
2491 if (QAbstractButton *abstractButton = d->abstractButtonForId(button)) {
2492 abstractButton->setText(text);
2493 } else if (d->buttonBox->buttons().isEmpty() && (button == Ok || button == Old_Ok)) {
2494 // for compatibility with Qt 4.0/4.1
2495 addButton(QMessageBox::Ok)->setText(text);
2496 }
2497}
2498
2499#if QT_CONFIG(textedit)
2500/*!
2501 \property QMessageBox::detailedText
2502 \brief the text to be displayed in the details area.
2503 \since 4.2
2504
2505 The text will be interpreted as a plain text.
2506
2507 By default, this property contains an empty string.
2508
2509 \sa QMessageBox::text, QMessageBox::informativeText
2510*/
2511QString QMessageBox::detailedText() const
2512{
2513 Q_D(const QMessageBox);
2514 return d->detailsText ? d->detailsText->text() : QString();
2515}
2516
2517void QMessageBox::setDetailedText(const QString &text)
2518{
2519 Q_D(QMessageBox);
2520 if (text.isEmpty()) {
2521 if (d->detailsText) {
2522 d->detailsText->hide();
2523 d->detailsText->deleteLater();
2524 }
2525 d->detailsText = nullptr;
2526 removeButton(d->detailsButton);
2527 if (d->detailsButton) {
2528 d->detailsButton->hide();
2529 d->detailsButton->deleteLater();
2530 }
2531 d->detailsButton = nullptr;
2532 } else {
2533 if (!d->detailsText) {
2534 d->detailsText = new QMessageBoxDetailsText(this);
2535 d->detailsText->hide();
2536 }
2537 if (!d->detailsButton) {
2538 const bool autoAddOkButton = d->autoAddOkButton; // QTBUG-39334, addButton() clears the flag.
2539 d->detailsButton = new DetailButton(this);
2540 addButton(d->detailsButton, QMessageBox::ActionRole);
2541 d->autoAddOkButton = autoAddOkButton;
2542 }
2543 d->detailsText->setText(text);
2544 }
2545 d->setupLayout();
2546}
2547#endif // QT_CONFIG(textedit)
2548
2549/*!
2550 \property QMessageBox::informativeText
2551
2552 \brief the informative text that provides a fuller description for
2553 the message
2554
2555 \since 4.2
2556
2557 Infromative text can be used to expand upon the text() to give more
2558 information to the user. On the Mac, this text appears in small
2559 system font below the text(). On other platforms, it is simply
2560 appended to the existing text.
2561
2562 By default, this property contains an empty string.
2563
2564 \sa QMessageBox::text, QMessageBox::detailedText
2565*/
2566QString QMessageBox::informativeText() const
2567{
2568 Q_D(const QMessageBox);
2569 return d->informativeLabel ? d->informativeLabel->text() : QString();
2570}
2571
2572void QMessageBox::setInformativeText(const QString &text)
2573{
2574 Q_D(QMessageBox);
2575 if (text.isEmpty()) {
2576 if (d->informativeLabel) {
2577 d->informativeLabel->hide();
2578 d->informativeLabel->deleteLater();
2579 }
2580 d->informativeLabel = nullptr;
2581 } else {
2582 if (!d->informativeLabel) {
2583 QLabel *label = new QLabel;
2584 label->setObjectName(QLatin1String("qt_msgbox_informativelabel"));
2585 label->setTextInteractionFlags(Qt::TextInteractionFlags(style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, nullptr, this)));
2586 label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
2587 label->setOpenExternalLinks(true);
2588 label->setWordWrap(true);
2589#ifdef Q_OS_MAC
2590 // apply a smaller font the information label on the mac
2591 label->setFont(qt_app_fonts_hash()->value("QTipLabel"));
2592#endif
2593 label->setWordWrap(true);
2594 d->informativeLabel = label;
2595 }
2596 d->informativeLabel->setText(text);
2597 }
2598 d->setupLayout();
2599}
2600
2601/*!
2602 \since 4.2
2603
2604 This function shadows QWidget::setWindowTitle().
2605
2606 Sets the title of the message box to \a title. On \macos,
2607 the window title is ignored (as required by the \macos
2608 Guidelines).
2609*/
2610void QMessageBox::setWindowTitle(const QString &title)
2611{
2612 // Message boxes on the mac do not have a title
2613#ifndef Q_OS_MAC
2614 QDialog::setWindowTitle(title);
2615#else
2616 Q_UNUSED(title);
2617#endif
2618}
2619
2620
2621/*!
2622 \since 4.2
2623
2624 This function shadows QWidget::setWindowModality().
2625
2626 Sets the modality of the message box to \a windowModality.
2627
2628 On \macos, if the modality is set to Qt::WindowModal and the message box
2629 has a parent, then the message box will be a Qt::Sheet, otherwise the
2630 message box will be a standard dialog.
2631*/
2632void QMessageBox::setWindowModality(Qt::WindowModality windowModality)
2633{
2634 QDialog::setWindowModality(windowModality);
2635
2636 if (parentWidget() && windowModality == Qt::WindowModal)
2637 setParent(parentWidget(), Qt::Sheet);
2638 else
2639 setParent(parentWidget(), Qt::Dialog);
2640 setDefaultButton(d_func()->defaultButton);
2641}
2642
2643
2644QPixmap QMessageBoxPrivate::standardIcon(QMessageBox::Icon icon, QMessageBox *mb)
2645{
2646 QStyle *style = mb ? mb->style() : QApplication::style();
2647 int iconSize = style->pixelMetric(QStyle::PM_MessageBoxIconSize, nullptr, mb);
2648 QIcon tmpIcon;
2649 switch (icon) {
2650 case QMessageBox::Information:
2651 tmpIcon = style->standardIcon(QStyle::SP_MessageBoxInformation, nullptr, mb);
2652 break;
2653 case QMessageBox::Warning:
2654 tmpIcon = style->standardIcon(QStyle::SP_MessageBoxWarning, nullptr, mb);
2655 break;
2656 case QMessageBox::Critical:
2657 tmpIcon = style->standardIcon(QStyle::SP_MessageBoxCritical, nullptr, mb);
2658 break;
2659 case QMessageBox::Question:
2660 tmpIcon = style->standardIcon(QStyle::SP_MessageBoxQuestion, nullptr, mb);
2661 default:
2662 break;
2663 }
2664 if (!tmpIcon.isNull()) {
2665 qreal dpr = mb ? mb->devicePixelRatio() : qApp->devicePixelRatio();
2666 return tmpIcon.pixmap(QSize(iconSize, iconSize), dpr);
2667 }
2668 return QPixmap();
2669}
2670
2671void QMessageBoxPrivate::initHelper(QPlatformDialogHelper *h)
2672{
2673 Q_Q(QMessageBox);
2674 QObject::connect(h, SIGNAL(clicked(QPlatformDialogHelper::StandardButton,QPlatformDialogHelper::ButtonRole)),
2675 q, SLOT(_q_clicked(QPlatformDialogHelper::StandardButton,QPlatformDialogHelper::ButtonRole)));
2676 static_cast<QPlatformMessageDialogHelper *>(h)->setOptions(options);
2677}
2678
2679static QMessageDialogOptions::Icon helperIcon(QMessageBox::Icon i)
2680{
2681 switch (i) {
2682 case QMessageBox::NoIcon:
2683 return QMessageDialogOptions::NoIcon;
2684 case QMessageBox::Information:
2685 return QMessageDialogOptions::Information;
2686 case QMessageBox::Warning:
2687 return QMessageDialogOptions::Warning;
2688 case QMessageBox::Critical:
2689 return QMessageDialogOptions::Critical;
2690 case QMessageBox::Question:
2691 return QMessageDialogOptions::Question;
2692 }
2693 return QMessageDialogOptions::NoIcon;
2694}
2695
2696static QPlatformDialogHelper::StandardButtons helperStandardButtons(QMessageBox * q)
2697{
2698 QPlatformDialogHelper::StandardButtons buttons(int(q->standardButtons()));
2699 return buttons;
2700}
2701
2702void QMessageBoxPrivate::helperPrepareShow(QPlatformDialogHelper *)
2703{
2704 Q_Q(QMessageBox);
2705 options->setWindowTitle(q->windowTitle());
2706 options->setText(q->text());
2707 options->setInformativeText(q->informativeText());
2708#if QT_CONFIG(textedit)
2709 options->setDetailedText(q->detailedText());
2710#endif
2711 options->setIcon(helperIcon(q->icon()));
2712 options->setStandardButtons(helperStandardButtons(q));
2713}
2714
2715void QMessageBoxPrivate::helperDone(QDialog::DialogCode code, QPlatformDialogHelper *)
2716{
2717 Q_Q(QMessageBox);
2718 QAbstractButton *button = q->button(QMessageBox::StandardButton(code));
2719 // If it was a custom button, a custom ID was used, so we won't get a valid pointer here.
2720 // In that case, clickedButton has already been set in _q_buttonClicked.
2721 if (button)
2722 clickedButton = button;
2723}
2724
2725/*!
2726 \obsolete
2727
2728 Returns the pixmap used for a standard icon. This allows the
2729 pixmaps to be used in more complex message boxes. \a icon
2730 specifies the required icon, e.g. QMessageBox::Question,
2731 QMessageBox::Information, QMessageBox::Warning or
2732 QMessageBox::Critical.
2733
2734 Call QStyle::standardIcon() with QStyle::SP_MessageBoxInformation etc.
2735 instead.
2736*/
2737
2738QPixmap QMessageBox::standardIcon(Icon icon)
2739{
2740 return QMessageBoxPrivate::standardIcon(icon, nullptr);
2741}
2742
2743/*!
2744 \typedef QMessageBox::Button
2745 \obsolete
2746
2747 Use QMessageBox::StandardButton instead.
2748*/
2749
2750/*!
2751 \fn int QMessageBox::information(QWidget *parent, const QString &title,
2752 const QString& text, StandardButton button0,
2753 StandardButton button1)
2754 \fn int QMessageBox::warning(QWidget *parent, const QString &title,
2755 const QString& text, StandardButton button0,
2756 StandardButton button1)
2757 \fn int QMessageBox::critical(QWidget *parent, const QString &title,
2758 const QString& text, StandardButton button0,
2759 StandardButton button1)
2760 \fn int QMessageBox::question(QWidget *parent, const QString &title,
2761 const QString& text, StandardButton button0,
2762 StandardButton button1)
2763 \internal
2764
2765 ### Needed for Qt 4 source compatibility
2766*/
2767
2768/*!
2769 \fn int QMessageBox::exec()
2770
2771 Shows the message box as a \l{QDialog#Modal Dialogs}{modal dialog},
2772 blocking until the user closes it.
2773
2774 When using a QMessageBox with standard buttons, this function returns a
2775 \l StandardButton value indicating the standard button that was clicked.
2776 When using QMessageBox with custom buttons, this function returns an
2777 opaque value; use clickedButton() to determine which button was clicked.
2778
2779 \note The result() function returns also \l StandardButton value instead
2780 of \l QDialog::DialogCode.
2781
2782 Users cannot interact with any other window in the same
2783 application until they close the dialog, either by clicking a
2784 button or by using a mechanism provided by the window system.
2785
2786 \sa show(), result()
2787*/
2788
2789QT_END_NAMESPACE
2790
2791#include "moc_qmessagebox.cpp"
2792#include "qmessagebox.moc"
2793