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