1/****************************************************************************
2**
3** Copyright (C) 2018 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/qdesktopwidget.h>
51#include <QtWidgets/qpushbutton.h>
52#include <QtWidgets/qcheckbox.h>
53#include <QtGui/qaccessible.h>
54#include <QtGui/qicon.h>
55#include <QtGui/qtextdocument.h>
56#include <QtWidgets/qapplication.h>
57#if QT_CONFIG(textedit)
58#include <QtWidgets/qtextedit.h>
59#endif
60#if QT_CONFIG(menu)
61#include <QtWidgets/qmenu.h>
62#endif
63#include "qdialog_p.h"
64#include <QtGui/qfont.h>
65#include <QtGui/qfontmetrics.h>
66#include <QtGui/qclipboard.h>
67#include "private/qabstractbutton_p.h"
68#include <private/qdesktopwidget_p.h>
69
70#ifdef Q_OS_WIN
71# include <QtCore/qt_windows.h>
72#include <qpa/qplatformnativeinterface.h>
73#endif
74
75QT_BEGIN_NAMESPACE
76
77#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
78HMENU qt_getWindowsSystemMenu(const QWidget *w)
79{
80 if (QWindow *window = QApplicationPrivate::windowForWidget(w))
81 if (void *handle = QGuiApplication::platformNativeInterface()->nativeResourceForWindow("handle", window))
82 return GetSystemMenu(reinterpret_cast<HWND>(handle), false);
83 return 0;
84}
85#endif
86
87enum Button { Old_Ok = 1, Old_Cancel = 2, Old_Yes = 3, Old_No = 4, Old_Abort = 5, Old_Retry = 6,
88 Old_Ignore = 7, Old_YesAll = 8, Old_NoAll = 9, Old_ButtonMask = 0xFF,
89 NewButtonMask = 0xFFFFFC00 };
90
91enum DetailButtonLabel { ShowLabel = 0, HideLabel = 1 };
92#if QT_CONFIG(textedit)
93class QMessageBoxDetailsText : public QWidget
94{
95 Q_OBJECT
96public:
97 class TextEdit : public QTextEdit
98 {
99 public:
100 TextEdit(QWidget *parent=0) : QTextEdit(parent) { }
101#ifndef QT_NO_CONTEXTMENU
102 void contextMenuEvent(QContextMenuEvent * e) override
103 {
104 QMenu *menu = createStandardContextMenu();
105 menu->setAttribute(Qt::WA_DeleteOnClose);
106 menu->popup(e->globalPos());
107 }
108#endif // QT_NO_CONTEXTMENU
109 };
110
111 QMessageBoxDetailsText(QWidget *parent=0)
112 : QWidget(parent)
113 , copyAvailable(false)
114 {
115 QVBoxLayout *layout = new QVBoxLayout;
116 layout->setContentsMargins(QMargins());
117 QFrame *line = new QFrame(this);
118 line->setFrameShape(QFrame::HLine);
119 line->setFrameShadow(QFrame::Sunken);
120 layout->addWidget(line);
121 textEdit = new TextEdit();
122 textEdit->setFixedHeight(100);
123 textEdit->setFocusPolicy(Qt::NoFocus);
124 textEdit->setReadOnly(true);
125 layout->addWidget(textEdit);
126 setLayout(layout);
127
128 connect(textEdit, SIGNAL(copyAvailable(bool)),
129 this, SLOT(textCopyAvailable(bool)));
130 }
131 void setText(const QString &text) { textEdit->setPlainText(text); }
132 QString text() const { return textEdit->toPlainText(); }
133
134 bool copy()
135 {
136#ifdef QT_NO_CLIPBOARD
137 return false;
138#else
139 if (!copyAvailable)
140 return false;
141 textEdit->copy();
142 return true;
143#endif
144 }
145
146 void selectAll()
147 {
148 textEdit->selectAll();
149 }
150
151private slots:
152 void textCopyAvailable(bool available)
153 {
154 copyAvailable = available;
155 }
156
157private:
158 bool copyAvailable;
159 TextEdit *textEdit;
160};
161#endif // QT_CONFIG(textedit)
162
163class DetailButton : public QPushButton
164{
165public:
166 DetailButton(QWidget *parent) : QPushButton(label(ShowLabel), parent)
167 {
168 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
169 }
170
171 QString label(DetailButtonLabel label) const
172 { return label == ShowLabel ? QMessageBox::tr("Show Details...") : QMessageBox::tr("Hide Details..."); }
173
174 void setLabel(DetailButtonLabel lbl)
175 { setText(label(lbl)); }
176
177 QSize sizeHint() const override
178 {
179 ensurePolished();
180 QStyleOptionButton opt;
181 initStyleOption(&opt);
182 const QFontMetrics fm = fontMetrics();
183 opt.text = label(ShowLabel);
184 QSize sz = fm.size(Qt::TextShowMnemonic, opt.text);
185 QSize ret = style()->sizeFromContents(QStyle::CT_PushButton, &opt, sz, this).
186 expandedTo(QApplication::globalStrut());
187 opt.text = label(HideLabel);
188 sz = fm.size(Qt::TextShowMnemonic, opt.text);
189 ret = ret.expandedTo(style()->sizeFromContents(QStyle::CT_PushButton, &opt, sz, this).
190 expandedTo(QApplication::globalStrut()));
191 return ret;
192 }
193};
194
195class QMessageBoxPrivate : public QDialogPrivate
196{
197 Q_DECLARE_PUBLIC(QMessageBox)
198
199public:
200 QMessageBoxPrivate() : escapeButton(0), defaultButton(0), checkbox(0), clickedButton(0), detailsButton(0),
201#if QT_CONFIG(textedit)
202 detailsText(0),
203#endif
204 compatMode(false), autoAddOkButton(true),
205 detectedEscapeButton(0), informativeLabel(0),
206 options(QMessageDialogOptions::create()) { }
207
208 void init(const QString &title = QString(), const QString &text = QString());
209 void setupLayout();
210 void _q_buttonClicked(QAbstractButton *);
211 void _q_clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role);
212 void setClickedButton(QAbstractButton *button);
213
214 QAbstractButton *findButton(int button0, int button1, int button2, int flags);
215 void addOldButtons(int button0, int button1, int button2);
216
217 QAbstractButton *abstractButtonForId(int id) const;
218 int execReturnCode(QAbstractButton *button);
219
220 int dialogCodeForButton(QAbstractButton *button) const;
221
222 void detectEscapeButton();
223 void updateSize();
224 int layoutMinimumWidth();
225 void retranslateStrings();
226
227 static int showOldMessageBox(QWidget *parent, QMessageBox::Icon icon,
228 const QString &title, const QString &text,
229 int button0, int button1, int button2);
230 static int showOldMessageBox(QWidget *parent, QMessageBox::Icon icon,
231 const QString &title, const QString &text,
232 const QString &button0Text,
233 const QString &button1Text,
234 const QString &button2Text,
235 int defaultButtonNumber,
236 int escapeButtonNumber);
237
238 static QMessageBox::StandardButton showNewMessageBox(QWidget *parent,
239 QMessageBox::Icon icon, const QString& title, const QString& text,
240 QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton);
241
242 static QPixmap standardIcon(QMessageBox::Icon icon, QMessageBox *mb);
243
244 QLabel *label;
245 QMessageBox::Icon icon;
246 QLabel *iconLabel;
247 QDialogButtonBox *buttonBox;
248 QList<QAbstractButton *> customButtonList;
249 QAbstractButton *escapeButton;
250 QPushButton *defaultButton;
251 QCheckBox *checkbox;
252 QAbstractButton *clickedButton;
253 DetailButton *detailsButton;
254#if QT_CONFIG(textedit)
255 QMessageBoxDetailsText *detailsText;
256#endif
257 bool compatMode;
258 bool autoAddOkButton;
259 QAbstractButton *detectedEscapeButton;
260 QLabel *informativeLabel;
261 QPointer<QObject> receiverToDisconnectOnClose;
262 QByteArray memberToDisconnectOnClose;
263 QByteArray signalToDisconnectOnClose;
264 QSharedPointer<QMessageDialogOptions> options;
265private:
266 void initHelper(QPlatformDialogHelper *) override;
267 void helperPrepareShow(QPlatformDialogHelper *) override;
268 void helperDone(QDialog::DialogCode, QPlatformDialogHelper *) override;
269};
270
271void QMessageBoxPrivate::init(const QString &title, const QString &text)
272{
273 Q_Q(QMessageBox);
274
275 label = new QLabel;
276 label->setObjectName(QLatin1String("qt_msgbox_label"));
277 label->setTextInteractionFlags(Qt::TextInteractionFlags(q->style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, 0, q)));
278 label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
279 label->setOpenExternalLinks(true);
280 iconLabel = new QLabel(q);
281 iconLabel->setObjectName(QLatin1String("qt_msgboxex_icon_label"));
282 iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
283
284 buttonBox = new QDialogButtonBox;
285 buttonBox->setObjectName(QLatin1String("qt_msgbox_buttonbox"));
286 buttonBox->setCenterButtons(q->style()->styleHint(QStyle::SH_MessageBox_CenterButtons, 0, q));
287 QObject::connect(buttonBox, SIGNAL(clicked(QAbstractButton*)),
288 q, SLOT(_q_buttonClicked(QAbstractButton*)));
289 setupLayout();
290 if (!title.isEmpty() || !text.isEmpty()) {
291 q->setWindowTitle(title);
292 q->setText(text);
293 }
294 q->setModal(true);
295#ifdef Q_OS_MAC
296 QFont f = q->font();
297 f.setBold(true);
298 label->setFont(f);
299#endif
300 icon = QMessageBox::NoIcon;
301}
302
303void QMessageBoxPrivate::setupLayout()
304{
305 Q_Q(QMessageBox);
306 delete q->layout();
307 QGridLayout *grid = new QGridLayout;
308 bool hasIcon = iconLabel->pixmap() && !iconLabel->pixmap()->isNull();
309
310 if (hasIcon)
311 grid->addWidget(iconLabel, 0, 0, 2, 1, Qt::AlignTop);
312 iconLabel->setVisible(hasIcon);
313#ifdef Q_OS_MAC
314 QSpacerItem *indentSpacer = new QSpacerItem(14, 1, QSizePolicy::Fixed, QSizePolicy::Fixed);
315#else
316 QSpacerItem *indentSpacer = new QSpacerItem(hasIcon ? 7 : 15, 1, QSizePolicy::Fixed, QSizePolicy::Fixed);
317#endif
318 grid->addItem(indentSpacer, 0, hasIcon ? 1 : 0, 2, 1);
319 grid->addWidget(label, 0, hasIcon ? 2 : 1, 1, 1);
320 if (informativeLabel) {
321#ifndef Q_OS_MAC
322 informativeLabel->setContentsMargins(0, 7, 0, 7);
323#endif
324 grid->addWidget(informativeLabel, 1, hasIcon ? 2 : 1, 1, 1);
325 }
326 if (checkbox) {
327 grid->addWidget(checkbox, informativeLabel ? 2 : 1, hasIcon ? 2 : 1, 1, 1, Qt::AlignLeft);
328#ifdef Q_OS_MAC
329 grid->addItem(new QSpacerItem(1, 15, QSizePolicy::Fixed, QSizePolicy::Fixed), grid->rowCount(), 0);
330#else
331 grid->addItem(new QSpacerItem(1, 7, QSizePolicy::Fixed, QSizePolicy::Fixed), grid->rowCount(), 0);
332#endif
333 }
334#ifdef Q_OS_MAC
335 grid->addWidget(buttonBox, grid->rowCount(), hasIcon ? 2 : 1, 1, 1);
336 grid->setMargin(0);
337 grid->setVerticalSpacing(8);
338 grid->setHorizontalSpacing(0);
339 q->setContentsMargins(24, 15, 24, 20);
340 grid->setRowStretch(1, 100);
341 grid->setRowMinimumHeight(2, 6);
342#else
343 grid->addWidget(buttonBox, grid->rowCount(), 0, 1, grid->columnCount());
344#endif
345#if QT_CONFIG(textedit)
346 if (detailsText)
347 grid->addWidget(detailsText, grid->rowCount(), 0, 1, grid->columnCount());
348#endif
349 grid->setSizeConstraint(QLayout::SetNoConstraint);
350 q->setLayout(grid);
351
352 retranslateStrings();
353 updateSize();
354}
355
356int QMessageBoxPrivate::layoutMinimumWidth()
357{
358 layout->activate();
359 return layout->totalMinimumSize().width();
360}
361
362void QMessageBoxPrivate::updateSize()
363{
364 Q_Q(QMessageBox);
365
366 if (!q->isVisible())
367 return;
368
369 QSize screenSize = QDesktopWidgetPrivate::availableGeometry(QCursor::pos()).size();
370 int hardLimit = qMin(screenSize.width() - 480, 1000); // can never get bigger than this
371 // on small screens allows the messagebox be the same size as the screen
372 if (screenSize.width() <= 1024)
373 hardLimit = screenSize.width();
374#ifdef Q_OS_MAC
375 int softLimit = qMin(screenSize.width()/2, 420);
376#else
377 // note: ideally on windows, hard and soft limits but it breaks compat
378 int softLimit = qMin(screenSize.width()/2, 500);
379#endif
380
381 if (informativeLabel)
382 informativeLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
383
384 label->setWordWrap(false); // makes the label return min size
385 int width = layoutMinimumWidth();
386
387 if (width > softLimit) {
388 label->setWordWrap(true);
389 width = qMax(softLimit, layoutMinimumWidth());
390
391 if (width > hardLimit) {
392 label->d_func()->ensureTextControl();
393 if (QWidgetTextControl *control = label->d_func()->control) {
394 QTextOption opt = control->document()->defaultTextOption();
395 opt.setWrapMode(QTextOption::WrapAnywhere);
396 control->document()->setDefaultTextOption(opt);
397 }
398 width = hardLimit;
399 }
400 }
401
402 if (informativeLabel) {
403 label->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
404 QSizePolicy policy(QSizePolicy::Minimum, QSizePolicy::Preferred);
405 policy.setHeightForWidth(true);
406 informativeLabel->setSizePolicy(policy);
407 width = qMax(width, layoutMinimumWidth());
408 if (width > hardLimit) { // longest word is really big, so wrap anywhere
409 informativeLabel->d_func()->ensureTextControl();
410 if (QWidgetTextControl *control = informativeLabel->d_func()->control) {
411 QTextOption opt = control->document()->defaultTextOption();
412 opt.setWrapMode(QTextOption::WrapAnywhere);
413 control->document()->setDefaultTextOption(opt);
414 }
415 width = hardLimit;
416 }
417 policy.setHeightForWidth(label->wordWrap());
418 label->setSizePolicy(policy);
419 }
420
421 QFontMetrics fm(QApplication::font("QMdiSubWindowTitleBar"));
422 int windowTitleWidth = qMin(fm.horizontalAdvance(q->windowTitle()) + 50, hardLimit);
423 if (windowTitleWidth > width)
424 width = windowTitleWidth;
425
426 layout->activate();
427 int height = (layout->hasHeightForWidth())
428 ? layout->totalHeightForWidth(width)
429 : layout->totalMinimumSize().height();
430
431 q->setFixedSize(width, height);
432 QCoreApplication::removePostedEvents(q, QEvent::LayoutRequest);
433}
434
435static int oldButton(int button)
436{
437 switch (button & QMessageBox::ButtonMask) {
438 case QMessageBox::Ok:
439 return Old_Ok;
440 case QMessageBox::Cancel:
441 return Old_Cancel;
442 case QMessageBox::Yes:
443 return Old_Yes;
444 case QMessageBox::No:
445 return Old_No;
446 case QMessageBox::Abort:
447 return Old_Abort;
448 case QMessageBox::Retry:
449 return Old_Retry;
450 case QMessageBox::Ignore:
451 return Old_Ignore;
452 case QMessageBox::YesToAll:
453 return Old_YesAll;
454 case QMessageBox::NoToAll:
455 return Old_NoAll;
456 default:
457 return 0;
458 }
459}
460
461int QMessageBoxPrivate::execReturnCode(QAbstractButton *button)
462{
463 int ret = buttonBox->standardButton(button);
464 if (ret == QMessageBox::NoButton) {
465 ret = customButtonList.indexOf(button); // if button == 0, correctly sets ret = -1
466 } else if (compatMode) {
467 ret = oldButton(ret);
468 }
469 return ret;
470}
471
472/*!
473 \internal
474
475 Returns 0 for RejectedRole and NoRole, 1 for AcceptedRole and YesRole, -1 otherwise
476 */
477int QMessageBoxPrivate::dialogCodeForButton(QAbstractButton *button) const
478{
479 Q_Q(const QMessageBox);
480
481 switch (q->buttonRole(button)) {
482 case QMessageBox::AcceptRole:
483 case QMessageBox::YesRole:
484 return QDialog::Accepted;
485 case QMessageBox::RejectRole:
486 case QMessageBox::NoRole:
487 return QDialog::Rejected;
488 default:
489 return -1;
490 }
491}
492
493void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button)
494{
495 Q_Q(QMessageBox);
496#if QT_CONFIG(textedit)
497 if (detailsButton && detailsText && button == detailsButton) {
498 detailsButton->setLabel(detailsText->isHidden() ? HideLabel : ShowLabel);
499 detailsText->setHidden(!detailsText->isHidden());
500 updateSize();
501 } else
502#endif
503 {
504 setClickedButton(button);
505
506 if (receiverToDisconnectOnClose) {
507 QObject::disconnect(q, signalToDisconnectOnClose, receiverToDisconnectOnClose,
508 memberToDisconnectOnClose);
509 receiverToDisconnectOnClose = nullptr;
510 }
511 signalToDisconnectOnClose.clear();
512 memberToDisconnectOnClose.clear();
513 }
514}
515
516void QMessageBoxPrivate::setClickedButton(QAbstractButton *button)
517{
518 Q_Q(QMessageBox);
519
520 clickedButton = button;
521 emit q->buttonClicked(clickedButton);
522
523 auto resultCode = execReturnCode(button);
524 hide(resultCode);
525 finalize(resultCode, dialogCodeForButton(button));
526}
527
528void QMessageBoxPrivate::_q_clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role)
529{
530 Q_Q(QMessageBox);
531 if (button > QPlatformDialogHelper::LastButton) {
532 // It's a custom button, and the QPushButton in options is just a proxy
533 // for the button on the platform dialog. Simulate the user clicking it.
534 clickedButton = static_cast<QAbstractButton *>(options->customButton(button)->button);
535 Q_ASSERT(clickedButton);
536 clickedButton->click();
537 q->done(role);
538 } else {
539 q->done(button);
540 }
541}
542
543/*!
544 \class QMessageBox
545
546 \brief The QMessageBox class provides a modal dialog for informing
547 the user or for asking the user a question and receiving an answer.
548
549 \ingroup standard-dialogs
550 \inmodule QtWidgets
551
552 A message box displays a primary \l{QMessageBox::text}{text} to
553 alert the user to a situation, an \l{QMessageBox::informativeText}
554 {informative text} to further explain the alert or to ask the user
555 a question, and an optional \l{QMessageBox::detailedText}
556 {detailed text} to provide even more data if the user requests
557 it. A message box can also display an \l{QMessageBox::icon} {icon}
558 and \l{QMessageBox::standardButtons} {standard buttons} for
559 accepting a user response.
560
561 Two APIs for using QMessageBox are provided, the property-based
562 API, and the static functions. Calling one of the static functions
563 is the simpler approach, but it is less flexible than using the
564 property-based API, and the result is less informative. Using the
565 property-based API is recommended.
566
567 \section1 The Property-based API
568
569 To use the property-based API, construct an instance of
570 QMessageBox, set the desired properties, and call exec() to show
571 the message. The simplest configuration is to set only the
572 \l{QMessageBox::text} {message text} property.
573
574 \snippet code/src_gui_dialogs_qmessagebox.cpp 5
575
576 The user must click the \uicontrol{OK} button to dismiss the message
577 box. The rest of the GUI is blocked until the message box is
578 dismissed.
579
580 \image msgbox1.png
581
582 A better approach than just alerting the user to an event is to
583 also ask the user what to do about it. Store the question in the
584 \l{QMessageBox::informativeText} {informative text} property, and
585 set the \l{QMessageBox::standardButtons} {standard buttons}
586 property to the set of buttons you want as the set of user
587 responses. The buttons are specified by combining values from
588 StandardButtons using the bitwise OR operator. The display order
589 for the buttons is platform-dependent. For example, on Windows,
590 \uicontrol{Save} is displayed to the left of \uicontrol{Cancel}, whereas on
591 Mac OS, the order is reversed.
592
593 Mark one of your standard buttons to be your
594 \l{QMessageBox::defaultButton()} {default button}.
595
596 \snippet code/src_gui_dialogs_qmessagebox.cpp 6
597
598 This is the approach recommended in the
599 \l{http://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/AppleHIGuidelines/Windows/Windows.html#//apple_ref/doc/uid/20000961-BABCAJID}
600 {\macos Guidelines}. Similar guidelines apply for the other
601 platforms, but note the different ways the
602 \l{QMessageBox::informativeText} {informative text} is handled for
603 different platforms.
604
605 \image msgbox2.png
606
607 The exec() slot returns the StandardButtons value of the button
608 that was clicked.
609
610 \snippet code/src_gui_dialogs_qmessagebox.cpp 7
611
612 To give the user more information to help him answer the question,
613 set the \l{QMessageBox::detailedText} {detailed text} property. If
614 the \l{QMessageBox::detailedText} {detailed text} property is set,
615 the \uicontrol{Show Details...} button will be shown.
616
617 \image msgbox3.png
618
619 Clicking the \uicontrol{Show Details...} button displays the detailed text.
620
621 \image msgbox4.png
622
623 \section2 Rich Text and the Text Format Property
624
625 The \l{QMessageBox::detailedText} {detailed text} property is
626 always interpreted as plain text. The \l{QMessageBox::text} {main
627 text} and \l{QMessageBox::informativeText} {informative text}
628 properties can be either plain text or rich text. These strings
629 are interpreted according to the setting of the
630 \l{QMessageBox::textFormat} {text format} property. The default
631 setting is \l{Qt::AutoText} {auto-text}.
632
633 Note that for some plain text strings containing XML
634 meta-characters, the auto-text \l{Qt::mightBeRichText()} {rich
635 text detection test} may fail causing your plain text string to be
636 interpreted incorrectly as rich text. In these rare cases, use
637 Qt::convertFromPlainText() to convert your plain text string to a
638 visually equivalent rich text string, or set the
639 \l{QMessageBox::textFormat} {text format} property explicitly with
640 setTextFormat().
641
642 \section2 Severity Levels and the Icon and Pixmap Properties
643
644 QMessageBox supports four predefined message severity levels, or message
645 types, which really only differ in the predefined icon they each show.
646 Specify one of the four predefined message types by setting the
647 \l{QMessageBox::icon}{icon} property to one of the
648 \l{QMessageBox::Icon}{predefined icons}. The following rules are
649 guidelines:
650
651 \table
652 \row
653 \li \image qmessagebox-quest.png
654 \li \l Question
655 \li For asking a question during normal operations.
656 \row
657 \li \image qmessagebox-info.png
658 \li \l Information
659 \li For reporting information about normal operations.
660 \row
661 \li \image qmessagebox-warn.png
662 \li \l Warning
663 \li For reporting non-critical errors.
664 \row
665 \li \image qmessagebox-crit.png
666 \li \l Critical
667 \li For reporting critical errors.
668 \endtable
669
670 \l{QMessageBox::Icon}{Predefined icons} are not defined by QMessageBox, but
671 provided by the style. The default value is \l{QMessageBox::NoIcon}
672 {No Icon}. The message boxes are otherwise the same for all cases. When
673 using a standard icon, use the one recommended in the table, or use the
674 one recommended by the style guidelines for your platform. If none of the
675 standard icons is right for your message box, you can use a custom icon by
676 setting the \l{QMessageBox::iconPixmap}{icon pixmap} property instead of
677 setting the \l{QMessageBox::icon}{icon} property.
678
679 In summary, to set an icon, use \e{either} setIcon() for one of the
680 standard icons, \e{or} setIconPixmap() for a custom icon.
681
682 \section1 The Static Functions API
683
684 Building message boxes with the static functions API, although
685 convenient, is less flexible than using the property-based API,
686 because the static function signatures lack parameters for setting
687 the \l{QMessageBox::informativeText} {informative text} and
688 \l{QMessageBox::detailedText} {detailed text} properties. One
689 work-around for this has been to use the \c{title} parameter as
690 the message box main text and the \c{text} parameter as the
691 message box informative text. Because this has the obvious
692 drawback of making a less readable message box, platform
693 guidelines do not recommend it. The \e{Microsoft Windows User
694 Interface Guidelines} recommend using the
695 \l{QCoreApplication::applicationName} {application name} as the
696 \l{QMessageBox::setWindowTitle()} {window's title}, which means
697 that if you have an informative text in addition to your main
698 text, you must concatenate it to the \c{text} parameter.
699
700 Note that the static function signatures have changed with respect
701 to their button parameters, which are now used to set the
702 \l{QMessageBox::standardButtons} {standard buttons} and the
703 \l{QMessageBox::defaultButton()} {default button}.
704
705 Static functions are available for creating information(),
706 question(), warning(), and critical() message boxes.
707
708 \snippet code/src_gui_dialogs_qmessagebox.cpp 0
709
710 The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
711 how to use QMessageBox and the other built-in Qt dialogs.
712
713 \section1 Advanced Usage
714
715 If the \l{QMessageBox::StandardButtons} {standard buttons} are not
716 flexible enough for your message box, you can use the addButton()
717 overload that takes a text and a ButtonRole to add custom
718 buttons. The ButtonRole is used by QMessageBox to determine the
719 ordering of the buttons on screen (which varies according to the
720 platform). You can test the value of clickedButton() after calling
721 exec(). For example,
722
723 \snippet code/src_gui_dialogs_qmessagebox.cpp 2
724
725 \section1 Default and Escape Keys
726
727 The default button (i.e., the button activated when \uicontrol Enter is
728 pressed) can be specified using setDefaultButton(). If a default
729 button is not specified, QMessageBox tries to find one based on
730 the \l{ButtonRole} {button roles} of the buttons used in the
731 message box.
732
733 The escape button (the button activated when \uicontrol Esc is pressed)
734 can be specified using setEscapeButton(). If an escape button is
735 not specified, QMessageBox tries to find one using these rules:
736
737 \list 1
738
739 \li If there is only one button, it is the button activated when
740 \uicontrol Esc is pressed.
741
742 \li If there is a \l Cancel button, it is the button activated when
743 \uicontrol Esc is pressed.
744
745 \li If there is exactly one button having either
746 \l{QMessageBox::RejectRole} {the Reject role} or the
747 \l{QMessageBox::NoRole} {the No role}, it is the button
748 activated when \uicontrol Esc is pressed.
749
750 \endlist
751
752 When an escape button can't be determined using these rules,
753 pressing \uicontrol Esc has no effect.
754
755 \sa QDialogButtonBox, {fowler}{GUI Design Handbook: Message Box}, {Standard Dialogs Example}, {Application Example}
756*/
757
758/*!
759 \enum QMessageBox::StandardButton
760 \since 4.2
761
762 These enums describe flags for standard buttons. Each button has a
763 defined \l ButtonRole.
764
765 \value Ok An "OK" button defined with the \l AcceptRole.
766 \value Open An "Open" button defined with the \l AcceptRole.
767 \value Save A "Save" button defined with the \l AcceptRole.
768 \value Cancel A "Cancel" button defined with the \l RejectRole.
769 \value Close A "Close" button defined with the \l RejectRole.
770 \value Discard A "Discard" or "Don't Save" button, depending on the platform,
771 defined with the \l DestructiveRole.
772 \value Apply An "Apply" button defined with the \l ApplyRole.
773 \value Reset A "Reset" button defined with the \l ResetRole.
774 \value RestoreDefaults A "Restore Defaults" button defined with the \l ResetRole.
775 \value Help A "Help" button defined with the \l HelpRole.
776 \value SaveAll A "Save All" button defined with the \l AcceptRole.
777 \value Yes A "Yes" button defined with the \l YesRole.
778 \value YesToAll A "Yes to All" button defined with the \l YesRole.
779 \value No A "No" button defined with the \l NoRole.
780 \value NoToAll A "No to All" button defined with the \l NoRole.
781 \value Abort An "Abort" button defined with the \l RejectRole.
782 \value Retry A "Retry" button defined with the \l AcceptRole.
783 \value Ignore An "Ignore" button defined with the \l AcceptRole.
784
785 \value NoButton An invalid button.
786
787 \omitvalue FirstButton
788 \omitvalue LastButton
789
790 The following values are obsolete:
791
792 \value YesAll Use YesToAll instead.
793 \value NoAll Use NoToAll instead.
794 \value Default Use the \c defaultButton argument of
795 information(), warning(), etc. instead, or call
796 setDefaultButton().
797 \value Escape Call setEscapeButton() instead.
798 \value FlagMask
799 \value ButtonMask
800
801 \sa ButtonRole, standardButtons
802*/
803
804/*!
805 \fn void QMessageBox::buttonClicked(QAbstractButton *button)
806
807 This signal is emitted whenever a button is clicked inside the QMessageBox.
808 The button that was clicked in returned in \a button.
809*/
810
811/*!
812 Constructs a message box with no text and no buttons. \a parent is
813 passed to the QDialog constructor.
814
815 On \macos, if you want your message box to appear
816 as a Qt::Sheet of its \a parent, set the message box's
817 \l{setWindowModality()} {window modality} to Qt::WindowModal or use open().
818 Otherwise, the message box will be a standard dialog.
819
820*/
821QMessageBox::QMessageBox(QWidget *parent)
822 : QDialog(*new QMessageBoxPrivate, parent, Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
823{
824 Q_D(QMessageBox);
825 d->init();
826}
827
828/*!
829 Constructs a message box with the given \a icon, \a title, \a
830 text, and standard \a buttons. Standard or custom buttons can be
831 added at any time using addButton(). The \a parent and \a f
832 arguments are passed to the QDialog constructor.
833
834 The message box is an \l{Qt::ApplicationModal} {application modal}
835 dialog box.
836
837 On \macos, if \a parent is not \nullptr and you want your message box
838 to appear as a Qt::Sheet of that parent, set the message box's
839 \l{setWindowModality()} {window modality} to Qt::WindowModal
840 (default). Otherwise, the message box will be a standard dialog.
841
842 \sa setWindowTitle(), setText(), setIcon(), setStandardButtons()
843*/
844QMessageBox::QMessageBox(Icon icon, const QString &title, const QString &text,
845 StandardButtons buttons, QWidget *parent,
846 Qt::WindowFlags f)
847: QDialog(*new QMessageBoxPrivate, parent, f | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint)
848{
849 Q_D(QMessageBox);
850 d->init(title, text);
851 setIcon(icon);
852 if (buttons != NoButton)
853 setStandardButtons(buttons);
854}
855
856/*!
857 Destroys the message box.
858*/
859QMessageBox::~QMessageBox()
860{
861}
862
863/*!
864 \since 4.2
865
866 Adds the given \a button to the message box with the specified \a
867 role.
868
869 \sa removeButton(), button(), setStandardButtons()
870*/
871void QMessageBox::addButton(QAbstractButton *button, ButtonRole role)
872{
873 Q_D(QMessageBox);
874 if (!button)
875 return;
876 removeButton(button);
877 d->options->addButton(button->text(), static_cast<QPlatformDialogHelper::ButtonRole>(role),
878 button);
879 d->buttonBox->addButton(button, (QDialogButtonBox::ButtonRole)role);
880 d->customButtonList.append(button);
881 d->autoAddOkButton = false;
882}
883
884/*!
885 \since 4.2
886 \overload
887
888 Creates a button with the given \a text, adds it to the message box for the
889 specified \a role, and returns it.
890*/
891QPushButton *QMessageBox::addButton(const QString& text, ButtonRole role)
892{
893 Q_D(QMessageBox);
894 QPushButton *pushButton = new QPushButton(text);
895 addButton(pushButton, role);
896 d->updateSize();
897 return pushButton;
898}
899
900/*!
901 \since 4.2
902 \overload
903
904 Adds a standard \a button to the message box if it is valid to do so, and
905 returns the push button.
906
907 \sa setStandardButtons()
908*/
909QPushButton *QMessageBox::addButton(StandardButton button)
910{
911 Q_D(QMessageBox);
912 QPushButton *pushButton = d->buttonBox->addButton((QDialogButtonBox::StandardButton)button);
913 if (pushButton)
914 d->autoAddOkButton = false;
915 return pushButton;
916}
917
918/*!
919 \since 4.2
920
921 Removes \a button from the button box without deleting it.
922
923 \sa addButton(), setStandardButtons()
924*/
925void QMessageBox::removeButton(QAbstractButton *button)
926{
927 Q_D(QMessageBox);
928 d->customButtonList.removeAll(button);
929 if (d->escapeButton == button)
930 d->escapeButton = 0;
931 if (d->defaultButton == button)
932 d->defaultButton = 0;
933 d->buttonBox->removeButton(button);
934 d->updateSize();
935}
936
937/*!
938 \property QMessageBox::standardButtons
939 \brief collection of standard buttons in the message box
940 \since 4.2
941
942 This property controls which standard buttons are used by the message box.
943
944 By default, this property contains no standard buttons.
945
946 \sa addButton()
947*/
948void QMessageBox::setStandardButtons(StandardButtons buttons)
949{
950 Q_D(QMessageBox);
951 d->buttonBox->setStandardButtons(QDialogButtonBox::StandardButtons(int(buttons)));
952
953 QList<QAbstractButton *> buttonList = d->buttonBox->buttons();
954 if (!buttonList.contains(d->escapeButton))
955 d->escapeButton = 0;
956 if (!buttonList.contains(d->defaultButton))
957 d->defaultButton = 0;
958 d->autoAddOkButton = false;
959 d->updateSize();
960}
961
962QMessageBox::StandardButtons QMessageBox::standardButtons() const
963{
964 Q_D(const QMessageBox);
965 return QMessageBox::StandardButtons(int(d->buttonBox->standardButtons()));
966}
967
968/*!
969 \since 4.2
970
971 Returns the standard button enum value corresponding to the given \a button,
972 or NoButton if the given \a button isn't a standard button.
973
974 \sa button(), standardButtons()
975*/
976QMessageBox::StandardButton QMessageBox::standardButton(QAbstractButton *button) const
977{
978 Q_D(const QMessageBox);
979 return (QMessageBox::StandardButton)d->buttonBox->standardButton(button);
980}
981
982/*!
983 \since 4.2
984
985 Returns a pointer corresponding to the standard button \a which,
986 or \nullptr if the standard button doesn't exist in this message box.
987
988 \sa standardButtons, standardButton()
989*/
990QAbstractButton *QMessageBox::button(StandardButton which) const
991{
992 Q_D(const QMessageBox);
993 return d->buttonBox->button(QDialogButtonBox::StandardButton(which));
994}
995
996/*!
997 \since 4.2
998
999 Returns the button that is activated when escape is pressed.
1000
1001 By default, QMessageBox attempts to automatically detect an
1002 escape button as follows:
1003
1004 \list 1
1005 \li If there is only one button, it is made the escape button.
1006 \li If there is a \l Cancel button, it is made the escape button.
1007 \li On \macos only, if there is exactly one button with the role
1008 QMessageBox::RejectRole, it is made the escape button.
1009 \endlist
1010
1011 When an escape button could not be automatically detected, pressing
1012 \uicontrol Esc has no effect.
1013
1014 \sa addButton()
1015*/
1016QAbstractButton *QMessageBox::escapeButton() const
1017{
1018 Q_D(const QMessageBox);
1019 return d->escapeButton;
1020}
1021
1022/*!
1023 \since 4.2
1024
1025 Sets the button that gets activated when the \uicontrol Escape key is
1026 pressed to \a button.
1027
1028 \sa addButton(), clickedButton()
1029*/
1030void QMessageBox::setEscapeButton(QAbstractButton *button)
1031{
1032 Q_D(QMessageBox);
1033 if (d->buttonBox->buttons().contains(button))
1034 d->escapeButton = button;
1035}
1036
1037/*!
1038 \since 4.3
1039
1040 Sets the buttons that gets activated when the \uicontrol Escape key is
1041 pressed to \a button.
1042
1043 \sa addButton(), clickedButton()
1044*/
1045void QMessageBox::setEscapeButton(QMessageBox::StandardButton button)
1046{
1047 Q_D(QMessageBox);
1048 setEscapeButton(d->buttonBox->button(QDialogButtonBox::StandardButton(button)));
1049}
1050
1051void QMessageBoxPrivate::detectEscapeButton()
1052{
1053 if (escapeButton) { // escape button explicitly set
1054 detectedEscapeButton = escapeButton;
1055 return;
1056 }
1057
1058 // Cancel button automatically becomes escape button
1059 detectedEscapeButton = buttonBox->button(QDialogButtonBox::Cancel);
1060 if (detectedEscapeButton)
1061 return;
1062
1063 // If there is only one button, make it the escape button
1064 const QList<QAbstractButton *> buttons = buttonBox->buttons();
1065 if (buttons.count() == 1) {
1066 detectedEscapeButton = buttons.first();
1067 return;
1068 }
1069
1070 // If there are two buttons and one of them is the "Show Details..."
1071 // button, then make the other one the escape button
1072 if (buttons.count() == 2 && detailsButton) {
1073 auto idx = buttons.indexOf(detailsButton);
1074 if (idx != -1) {
1075 detectedEscapeButton = buttons.at(1 - idx);
1076 return;
1077 }
1078 }
1079
1080 // if the message box has one RejectRole button, make it the escape button
1081 for (auto *button : buttons) {
1082 if (buttonBox->buttonRole(button) == QDialogButtonBox::RejectRole) {
1083 if (detectedEscapeButton) { // already detected!
1084 detectedEscapeButton = 0;
1085 break;
1086 }
1087 detectedEscapeButton = button;
1088 }
1089 }
1090 if (detectedEscapeButton)
1091 return;
1092
1093 // if the message box has one NoRole button, make it the escape button
1094 for (auto *button : buttons) {
1095 if (buttonBox->buttonRole(button) == QDialogButtonBox::NoRole) {
1096 if (detectedEscapeButton) { // already detected!
1097 detectedEscapeButton = 0;
1098 break;
1099 }
1100 detectedEscapeButton = button;
1101 }
1102 }
1103}
1104
1105/*!
1106 \since 4.2
1107
1108 Returns the button that was clicked by the user,
1109 or \nullptr if the user hit the \uicontrol Esc key and
1110 no \l{setEscapeButton()}{escape button} was set.
1111
1112 If exec() hasn't been called yet, returns nullptr.
1113
1114 Example:
1115
1116 \snippet code/src_gui_dialogs_qmessagebox.cpp 3
1117
1118 \sa standardButton(), button()
1119*/
1120QAbstractButton *QMessageBox::clickedButton() const
1121{
1122 Q_D(const QMessageBox);
1123 return d->clickedButton;
1124}
1125
1126/*!
1127 \since 4.2
1128
1129 Returns the button that should be the message box's
1130 \l{QPushButton::setDefault()}{default button}. Returns nullptr
1131 if no default button was set.
1132
1133 \sa addButton(), QPushButton::setDefault()
1134*/
1135QPushButton *QMessageBox::defaultButton() const
1136{
1137 Q_D(const QMessageBox);
1138 return d->defaultButton;
1139}
1140
1141/*!
1142 \since 4.2
1143
1144 Sets the message box's \l{QPushButton::setDefault()}{default button}
1145 to \a button.
1146
1147 \sa addButton(), QPushButton::setDefault()
1148*/
1149void QMessageBox::setDefaultButton(QPushButton *button)
1150{
1151 Q_D(QMessageBox);
1152 if (!d->buttonBox->buttons().contains(button))
1153 return;
1154 d->defaultButton = button;
1155 button->setDefault(true);
1156 button->setFocus();
1157}
1158
1159/*!
1160 \since 4.3
1161
1162 Sets the message box's \l{QPushButton::setDefault()}{default button}
1163 to \a button.
1164
1165 \sa addButton(), QPushButton::setDefault()
1166*/
1167void QMessageBox::setDefaultButton(QMessageBox::StandardButton button)
1168{
1169 Q_D(QMessageBox);
1170 setDefaultButton(d->buttonBox->button(QDialogButtonBox::StandardButton(button)));
1171}
1172
1173/*! \since 5.2
1174
1175 Sets the checkbox \a cb on the message dialog. The message box takes ownership of the checkbox.
1176 The argument \a cb can be \nullptr to remove an existing checkbox from the message box.
1177
1178 \sa checkBox()
1179*/
1180
1181void QMessageBox::setCheckBox(QCheckBox *cb)
1182{
1183 Q_D(QMessageBox);
1184
1185 if (cb == d->checkbox)
1186 return;
1187
1188 if (d->checkbox) {
1189 d->checkbox->hide();
1190 layout()->removeWidget(d->checkbox);
1191 if (d->checkbox->parentWidget() == this) {
1192 d->checkbox->setParent(0);
1193 d->checkbox->deleteLater();
1194 }
1195 }
1196 d->checkbox = cb;
1197 if (d->checkbox) {
1198 QSizePolicy sp = d->checkbox->sizePolicy();
1199 sp.setHorizontalPolicy(QSizePolicy::MinimumExpanding);
1200 d->checkbox->setSizePolicy(sp);
1201 }
1202 d->setupLayout();
1203}
1204
1205
1206/*! \since 5.2
1207
1208 Returns the checkbox shown on the dialog. This is \nullptr if no checkbox is set.
1209 \sa setCheckBox()
1210*/
1211
1212QCheckBox* QMessageBox::checkBox() const
1213{
1214 Q_D(const QMessageBox);
1215 return d->checkbox;
1216}
1217
1218/*!
1219 \property QMessageBox::text
1220 \brief the message box text to be displayed.
1221
1222 The text will be interpreted either as a plain text or as rich text,
1223 depending on the text format setting (\l QMessageBox::textFormat).
1224 The default setting is Qt::AutoText, i.e., the message box will try
1225 to auto-detect the format of the text.
1226
1227 The default value of this property is an empty string.
1228
1229 \sa textFormat, QMessageBox::informativeText, QMessageBox::detailedText
1230*/
1231QString QMessageBox::text() const
1232{
1233 Q_D(const QMessageBox);
1234 return d->label->text();
1235}
1236
1237void QMessageBox::setText(const QString &text)
1238{
1239 Q_D(QMessageBox);
1240 d->label->setText(text);
1241 d->label->setWordWrap(d->label->textFormat() == Qt::RichText
1242 || (d->label->textFormat() == Qt::AutoText && Qt::mightBeRichText(text)));
1243 d->updateSize();
1244}
1245
1246/*!
1247 \enum QMessageBox::Icon
1248
1249 This enum has the following values:
1250
1251 \value NoIcon the message box does not have any icon.
1252
1253 \value Question an icon indicating that
1254 the message is asking a question.
1255
1256 \value Information an icon indicating that
1257 the message is nothing out of the ordinary.
1258
1259 \value Warning an icon indicating that the
1260 message is a warning, but can be dealt with.
1261
1262 \value Critical an icon indicating that
1263 the message represents a critical problem.
1264
1265*/
1266
1267/*!
1268 \property QMessageBox::icon
1269 \brief the message box's icon
1270
1271 The icon of the message box can be specified with one of the
1272 values:
1273
1274 \list
1275 \li QMessageBox::NoIcon
1276 \li QMessageBox::Question
1277 \li QMessageBox::Information
1278 \li QMessageBox::Warning
1279 \li QMessageBox::Critical
1280 \endlist
1281
1282 The default is QMessageBox::NoIcon.
1283
1284 The pixmap used to display the actual icon depends on the current
1285 \l{QWidget::style()} {GUI style}. You can also set a custom pixmap
1286 for the icon by setting the \l{QMessageBox::iconPixmap} {icon
1287 pixmap} property.
1288
1289 \sa iconPixmap
1290*/
1291QMessageBox::Icon QMessageBox::icon() const
1292{
1293 Q_D(const QMessageBox);
1294 return d->icon;
1295}
1296
1297void QMessageBox::setIcon(Icon icon)
1298{
1299 Q_D(QMessageBox);
1300 setIconPixmap(QMessageBoxPrivate::standardIcon((QMessageBox::Icon)icon,
1301 this));
1302 d->icon = icon;
1303}
1304
1305/*!
1306 \property QMessageBox::iconPixmap
1307 \brief the current icon
1308
1309 The icon currently used by the message box. Note that it's often
1310 hard to draw one pixmap that looks appropriate in all GUI styles;
1311 you may want to supply a different pixmap for each platform.
1312
1313 By default, this property is undefined.
1314
1315 \sa icon
1316*/
1317QPixmap QMessageBox::iconPixmap() const
1318{
1319 Q_D(const QMessageBox);
1320 if (d->iconLabel && d->iconLabel->pixmap())
1321 return *d->iconLabel->pixmap();
1322 return QPixmap();
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, 0, this));
1437 d->label->setTextInteractionFlags(flags);
1438 d->buttonBox->setCenterButtons(style()->styleHint(QStyle::SH_MessageBox_CenterButtons, 0, 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 == int(shortcut[0] & ~Qt::MODIFIER_MASK)) {
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) && !defined(Q_OS_WINRT)
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 != 0);
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("2019"),
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 0;
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 = 0;
2526 removeButton(d->detailsButton);
2527 if (d->detailsButton) {
2528 d->detailsButton->hide();
2529 d->detailsButton->deleteLater();
2530 }
2531 d->detailsButton = 0;
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 = 0;
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, 0, 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, 0, mb);
2648 QIcon tmpIcon;
2649 switch (icon) {
2650 case QMessageBox::Information:
2651 tmpIcon = style->standardIcon(QStyle::SP_MessageBoxInformation, 0, mb);
2652 break;
2653 case QMessageBox::Warning:
2654 tmpIcon = style->standardIcon(QStyle::SP_MessageBoxWarning, 0, mb);
2655 break;
2656 case QMessageBox::Critical:
2657 tmpIcon = style->standardIcon(QStyle::SP_MessageBoxCritical, 0, mb);
2658 break;
2659 case QMessageBox::Question:
2660 tmpIcon = style->standardIcon(QStyle::SP_MessageBoxQuestion, 0, mb);
2661 default:
2662 break;
2663 }
2664 if (!tmpIcon.isNull()) {
2665 QWindow *window = mb
2666 ? qt_widget_private(mb)->windowHandle(QWidgetPrivate::WindowHandleMode::Closest)
2667 : nullptr;
2668 return tmpIcon.pixmap(window, QSize(iconSize, iconSize));
2669 }
2670 return QPixmap();
2671}
2672
2673void QMessageBoxPrivate::initHelper(QPlatformDialogHelper *h)
2674{
2675 Q_Q(QMessageBox);
2676 QObject::connect(h, SIGNAL(clicked(QPlatformDialogHelper::StandardButton,QPlatformDialogHelper::ButtonRole)),
2677 q, SLOT(_q_clicked(QPlatformDialogHelper::StandardButton,QPlatformDialogHelper::ButtonRole)));
2678 static_cast<QPlatformMessageDialogHelper *>(h)->setOptions(options);
2679}
2680
2681static QMessageDialogOptions::Icon helperIcon(QMessageBox::Icon i)
2682{
2683 switch (i) {
2684 case QMessageBox::NoIcon:
2685 return QMessageDialogOptions::NoIcon;
2686 case QMessageBox::Information:
2687 return QMessageDialogOptions::Information;
2688 case QMessageBox::Warning:
2689 return QMessageDialogOptions::Warning;
2690 case QMessageBox::Critical:
2691 return QMessageDialogOptions::Critical;
2692 case QMessageBox::Question:
2693 return QMessageDialogOptions::Question;
2694 }
2695 return QMessageDialogOptions::NoIcon;
2696}
2697
2698static QPlatformDialogHelper::StandardButtons helperStandardButtons(QMessageBox * q)
2699{
2700 QPlatformDialogHelper::StandardButtons buttons(int(q->standardButtons()));
2701 return buttons;
2702}
2703
2704void QMessageBoxPrivate::helperPrepareShow(QPlatformDialogHelper *)
2705{
2706 Q_Q(QMessageBox);
2707 options->setWindowTitle(q->windowTitle());
2708 options->setText(q->text());
2709 options->setInformativeText(q->informativeText());
2710#if QT_CONFIG(textedit)
2711 options->setDetailedText(q->detailedText());
2712#endif
2713 options->setIcon(helperIcon(q->icon()));
2714 options->setStandardButtons(helperStandardButtons(q));
2715}
2716
2717void QMessageBoxPrivate::helperDone(QDialog::DialogCode code, QPlatformDialogHelper *)
2718{
2719 Q_Q(QMessageBox);
2720 QAbstractButton *button = q->button(QMessageBox::StandardButton(code));
2721 // If it was a custom button, a custom ID was used, so we won't get a valid pointer here.
2722 // In that case, clickedButton has already been set in _q_buttonClicked.
2723 if (button)
2724 clickedButton = button;
2725}
2726
2727/*!
2728 \obsolete
2729
2730 Returns the pixmap used for a standard icon. This allows the
2731 pixmaps to be used in more complex message boxes. \a icon
2732 specifies the required icon, e.g. QMessageBox::Question,
2733 QMessageBox::Information, QMessageBox::Warning or
2734 QMessageBox::Critical.
2735
2736 Call QStyle::standardIcon() with QStyle::SP_MessageBoxInformation etc.
2737 instead.
2738*/
2739
2740QPixmap QMessageBox::standardIcon(Icon icon)
2741{
2742 return QMessageBoxPrivate::standardIcon(icon, 0);
2743}
2744
2745/*!
2746 \typedef QMessageBox::Button
2747 \obsolete
2748
2749 Use QMessageBox::StandardButton instead.
2750*/
2751
2752/*!
2753 \fn int QMessageBox::information(QWidget *parent, const QString &title,
2754 const QString& text, StandardButton button0,
2755 StandardButton button1)
2756 \fn int QMessageBox::warning(QWidget *parent, const QString &title,
2757 const QString& text, StandardButton button0,
2758 StandardButton button1)
2759 \fn int QMessageBox::critical(QWidget *parent, const QString &title,
2760 const QString& text, StandardButton button0,
2761 StandardButton button1)
2762 \fn int QMessageBox::question(QWidget *parent, const QString &title,
2763 const QString& text, StandardButton button0,
2764 StandardButton button1)
2765 \internal
2766
2767 ### Needed for Qt 4 source compatibility
2768*/
2769
2770/*!
2771 \fn int QMessageBox::exec()
2772
2773 Shows the message box as a \l{QDialog#Modal Dialogs}{modal dialog},
2774 blocking until the user closes it.
2775
2776 When using a QMessageBox with standard buttons, this function returns a
2777 \l StandardButton value indicating the standard button that was clicked.
2778 When using QMessageBox with custom buttons, this function returns an
2779 opaque value; use clickedButton() to determine which button was clicked.
2780
2781 \note The result() function returns also \l StandardButton value instead
2782 of \l QDialog::DialogCode.
2783
2784 Users cannot interact with any other window in the same
2785 application until they close the dialog, either by clicking a
2786 button or by using a mechanism provided by the window system.
2787
2788 \sa show(), result()
2789*/
2790
2791QT_END_NAMESPACE
2792
2793#include "moc_qmessagebox.cpp"
2794#include "qmessagebox.moc"
2795