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