src/gui/widgets/qdialogbuttonbox.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <QtCore/qhash.h>
       
    43 #include <QtGui/qpushbutton.h>
       
    44 #include <QtGui/qstyle.h>
       
    45 #include <QtGui/qlayout.h>
       
    46 #include <QtGui/qdialog.h>
       
    47 #include <QtGui/qapplication.h>
       
    48 #include <QtGui/private/qwidget_p.h>
       
    49 
       
    50 #include "qdialogbuttonbox.h"
       
    51 
       
    52 #ifdef QT_SOFTKEYS_ENABLED
       
    53 #include <QtGui/qaction.h>
       
    54 #endif
       
    55 
       
    56 
       
    57 QT_BEGIN_NAMESPACE
       
    58 
       
    59 /*!
       
    60     \class QDialogButtonBox
       
    61     \since 4.2
       
    62     \brief The QDialogButtonBox class is a widget that presents buttons in a
       
    63     layout that is appropriate to the current widget style.
       
    64 
       
    65     \ingroup dialog-classes
       
    66 
       
    67 
       
    68     Dialogs and message boxes typically present buttons in a layout that
       
    69     conforms to the interface guidelines for that platform. Invariably,
       
    70     different platforms have different layouts for their dialogs.
       
    71     QDialogButtonBox allows a developer to add buttons to it and will
       
    72     automatically use the appropriate layout for the user's desktop
       
    73     environment.
       
    74 
       
    75     Most buttons for a dialog follow certain roles. Such roles include:
       
    76 
       
    77     \list
       
    78     \o Accepting or rejecting the dialog.
       
    79     \o Asking for help.
       
    80     \o Performing actions on the dialog itself (such as resetting fields or
       
    81        applying changes).
       
    82     \endlist
       
    83 
       
    84     There can also be alternate ways of dismissing the dialog which may cause
       
    85     destructive results.
       
    86 
       
    87     Most dialogs have buttons that can almost be considered standard (e.g.
       
    88     \gui OK and \gui Cancel buttons). It is sometimes convenient to create these
       
    89     buttons in a standard way.
       
    90 
       
    91     There are a couple ways of using QDialogButtonBox. One ways is to create
       
    92     the buttons (or button texts) yourself and add them to the button box,
       
    93     specifying their role.
       
    94 
       
    95     \snippet examples/dialogs/extension/finddialog.cpp 1
       
    96 
       
    97     Alternatively, QDialogButtonBox provides several standard buttons (e.g. OK, Cancel, Save)
       
    98     that you can use. They exist as flags so you can OR them together in the constructor.
       
    99 
       
   100     \snippet examples/dialogs/tabdialog/tabdialog.cpp 2
       
   101 
       
   102     You can mix and match normal buttons and standard buttons.
       
   103 
       
   104     Currently the buttons are laid out in the following way if the button box is horizontal:
       
   105     \table 100%
       
   106     \row \o \inlineimage buttonbox-gnomelayout-horizontal.png GnomeLayout Horizontal
       
   107          \o Button box laid out in horizontal GnomeLayout
       
   108     \row \o \inlineimage buttonbox-kdelayout-horizontal.png KdeLayout Horizontal
       
   109          \o Button box laid out in horizontal KdeLayout
       
   110     \row \o \inlineimage buttonbox-maclayout-horizontal.png MacLayout Horizontal
       
   111          \o Button box laid out in horizontal MacLayout
       
   112     \row \o \inlineimage buttonbox-winlayout-horizontal.png  WinLayout Horizontal
       
   113          \o Button box laid out in horizontal WinLayout
       
   114     \endtable
       
   115 
       
   116     The buttons are laid out the following way if the button box is vertical:
       
   117 
       
   118     \table 100%
       
   119     \row \o \inlineimage buttonbox-gnomelayout-vertical.png GnomeLayout Vertical
       
   120          \o Button box laid out in vertical GnomeLayout
       
   121     \row \o \inlineimage buttonbox-kdelayout-vertical.png KdeLayout Vertical
       
   122          \o Button box laid out in vertical KdeLayout
       
   123     \row \o \inlineimage buttonbox-maclayout-vertical.png MacLayout Vertical
       
   124          \o Button box laid out in vertical MacLayout
       
   125     \row \o \inlineimage buttonbox-winlayout-vertical.png WinLayout Vertical
       
   126          \o Button box laid out in vertical WinLayout
       
   127     \endtable
       
   128 
       
   129     Additionally, button boxes that contain only buttons with ActionRole or
       
   130     HelpRole can be considered modeless and have an alternate look on the mac:
       
   131 
       
   132     \table 100%
       
   133     \row \o \inlineimage buttonbox-mac-modeless-horizontal.png Screenshot of modeless horizontal MacLayout
       
   134          \o modeless horizontal MacLayout
       
   135     \row \o \inlineimage buttonbox-mac-modeless-vertical.png Screenshot of modeless vertical MacLayout
       
   136          \o modeless vertical MacLayout
       
   137     \endtable
       
   138 
       
   139     When a button is clicked in the button box, the clicked() signal is emitted
       
   140     for the actual button is that is pressed. For convenience, if the button
       
   141     has an AcceptRole, RejectRole, or HelpRole, the accepted(), rejected(), or
       
   142     helpRequested() signals are emitted respectively.
       
   143 
       
   144     If you want a specific button to be default you need to call
       
   145     QPushButton::setDefault() on it yourself. However, if there is no default
       
   146     button set and to preserve which button is the default button across
       
   147     platforms when using the QPushButton::autoDefault property, the first push
       
   148     button with the accept role is made the default button when the
       
   149     QDialogButtonBox is shown,
       
   150 
       
   151     \sa QMessageBox, QPushButton, QDialog
       
   152 */
       
   153 
       
   154 enum {
       
   155     AcceptRole      = QDialogButtonBox::AcceptRole,
       
   156     RejectRole      = QDialogButtonBox::RejectRole,
       
   157     DestructiveRole = QDialogButtonBox::DestructiveRole,
       
   158     ActionRole      = QDialogButtonBox::ActionRole,
       
   159     HelpRole        = QDialogButtonBox::HelpRole,
       
   160     YesRole         = QDialogButtonBox::YesRole,
       
   161     NoRole          = QDialogButtonBox::NoRole,
       
   162     ApplyRole       = QDialogButtonBox::ApplyRole,
       
   163     ResetRole       = QDialogButtonBox::ResetRole,
       
   164 
       
   165     AlternateRole   = 0x10000000,
       
   166     Stretch         = 0x20000000,
       
   167     EOL             = 0x40000000,
       
   168     Reverse         = 0x80000000
       
   169 };
       
   170 
       
   171 static QDialogButtonBox::ButtonRole roleFor(QDialogButtonBox::StandardButton button)
       
   172 {
       
   173     switch (button) {
       
   174     case QDialogButtonBox::Ok:
       
   175     case QDialogButtonBox::Save:
       
   176     case QDialogButtonBox::Open:
       
   177     case QDialogButtonBox::SaveAll:
       
   178     case QDialogButtonBox::Retry:
       
   179     case QDialogButtonBox::Ignore:
       
   180         return QDialogButtonBox::AcceptRole;
       
   181 
       
   182     case QDialogButtonBox::Cancel:
       
   183     case QDialogButtonBox::Close:
       
   184     case QDialogButtonBox::Abort:
       
   185         return QDialogButtonBox::RejectRole;
       
   186 
       
   187     case QDialogButtonBox::Discard:
       
   188         return QDialogButtonBox::DestructiveRole;
       
   189 
       
   190     case QDialogButtonBox::Help:
       
   191         return QDialogButtonBox::HelpRole;
       
   192 
       
   193     case QDialogButtonBox::Apply:
       
   194         return QDialogButtonBox::ApplyRole;
       
   195 
       
   196     case QDialogButtonBox::Yes:
       
   197     case QDialogButtonBox::YesToAll:
       
   198         return QDialogButtonBox::YesRole;
       
   199 
       
   200     case QDialogButtonBox::No:
       
   201     case QDialogButtonBox::NoToAll:
       
   202         return QDialogButtonBox::NoRole;
       
   203 
       
   204     case QDialogButtonBox::RestoreDefaults:
       
   205     case QDialogButtonBox::Reset:
       
   206         return QDialogButtonBox::ResetRole;
       
   207 
       
   208     case QDialogButtonBox::NoButton:    // NoButton means zero buttons, not "No" button
       
   209         ;
       
   210     }
       
   211 
       
   212     return QDialogButtonBox::InvalidRole;
       
   213 }
       
   214 
       
   215 static const int layouts[2][5][14] =
       
   216 {
       
   217     // Qt::Horizontal
       
   218     {
       
   219         // WinLayout
       
   220         { ResetRole, Stretch, YesRole, AcceptRole, AlternateRole, DestructiveRole, NoRole, ActionRole, RejectRole, ApplyRole,
       
   221            HelpRole, EOL, EOL, EOL },
       
   222 
       
   223         // MacLayout
       
   224         { HelpRole, ResetRole, ApplyRole, ActionRole, Stretch, DestructiveRole | Reverse,
       
   225           AlternateRole | Reverse, RejectRole | Reverse, AcceptRole | Reverse, NoRole | Reverse, YesRole | Reverse, EOL, EOL },
       
   226 
       
   227         // KdeLayout
       
   228         { HelpRole, ResetRole, Stretch, YesRole, NoRole, ActionRole, AcceptRole, AlternateRole,
       
   229           ApplyRole, DestructiveRole, RejectRole, EOL },
       
   230 
       
   231         // GnomeLayout
       
   232         { HelpRole, ResetRole, Stretch, ActionRole, ApplyRole | Reverse, DestructiveRole | Reverse,
       
   233           AlternateRole | Reverse, RejectRole | Reverse, AcceptRole | Reverse, NoRole | Reverse, YesRole | Reverse, EOL },
       
   234 
       
   235         // Mac modeless
       
   236         { ResetRole, ApplyRole, ActionRole, Stretch, HelpRole, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL }
       
   237     },
       
   238 
       
   239     // Qt::Vertical
       
   240     {
       
   241         // WinLayout
       
   242         { ActionRole, YesRole, AcceptRole, AlternateRole, DestructiveRole, NoRole, RejectRole, ApplyRole, ResetRole,
       
   243           HelpRole, Stretch, EOL, EOL, EOL },
       
   244 
       
   245         // MacLayout
       
   246         { YesRole, NoRole, AcceptRole, RejectRole, AlternateRole, DestructiveRole, Stretch, ActionRole, ApplyRole,
       
   247           ResetRole, HelpRole, EOL, EOL },
       
   248 
       
   249         // KdeLayout
       
   250         { AcceptRole, AlternateRole, ApplyRole, ActionRole, YesRole, NoRole, Stretch, ResetRole,
       
   251           DestructiveRole, RejectRole, HelpRole, EOL },
       
   252 
       
   253         // GnomeLayout
       
   254         { YesRole, NoRole, AcceptRole, RejectRole, AlternateRole, DestructiveRole, ApplyRole, ActionRole, Stretch,
       
   255           ResetRole, HelpRole, EOL, EOL, EOL },
       
   256 
       
   257         // Mac modeless
       
   258         { ActionRole, ApplyRole, ResetRole, Stretch, HelpRole, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL }
       
   259     }
       
   260 };
       
   261 
       
   262 class QDialogButtonBoxPrivate : public QWidgetPrivate
       
   263 {
       
   264     Q_DECLARE_PUBLIC(QDialogButtonBox)
       
   265 
       
   266 public:
       
   267     QDialogButtonBoxPrivate(Qt::Orientation orient);
       
   268 
       
   269     QList<QAbstractButton *> buttonLists[QDialogButtonBox::NRoles];
       
   270     QHash<QPushButton *, QDialogButtonBox::StandardButton> standardButtonHash;
       
   271 #ifdef QT_SOFTKEYS_ENABLED
       
   272     QHash<QAbstractButton *, QAction *> softKeyActions;
       
   273 #endif
       
   274 
       
   275     Qt::Orientation orientation;
       
   276     QDialogButtonBox::ButtonLayout layoutPolicy;
       
   277     QBoxLayout *buttonLayout;
       
   278     bool internalRemove;
       
   279     bool center;
       
   280 
       
   281     void createStandardButtons(QDialogButtonBox::StandardButtons buttons);
       
   282 
       
   283     void layoutButtons();
       
   284     void initLayout();
       
   285     void resetLayout();
       
   286     QPushButton *createButton(QDialogButtonBox::StandardButton button, bool doLayout = true);
       
   287     void addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role, bool doLayout = true);
       
   288     void _q_handleButtonDestroyed();
       
   289     void _q_handleButtonClicked();
       
   290     void addButtonsToLayout(const QList<QAbstractButton *> &buttonList, bool reverse);
       
   291     void retranslateStrings();
       
   292     const char *standardButtonText(QDialogButtonBox::StandardButton sbutton) const;
       
   293 #ifdef QT_SOFTKEYS_ENABLED
       
   294     QAction *createSoftKey(QAbstractButton *button, QDialogButtonBox::ButtonRole role);
       
   295 #endif
       
   296 };
       
   297 
       
   298 QDialogButtonBoxPrivate::QDialogButtonBoxPrivate(Qt::Orientation orient)
       
   299     : orientation(orient), buttonLayout(0), internalRemove(false), center(false)
       
   300 {
       
   301 }
       
   302 
       
   303 void QDialogButtonBoxPrivate::initLayout()
       
   304 {
       
   305     Q_Q(QDialogButtonBox);
       
   306     layoutPolicy = QDialogButtonBox::ButtonLayout(q->style()->styleHint(QStyle::SH_DialogButtonLayout, 0, q));
       
   307     bool createNewLayout = buttonLayout == 0
       
   308         || (orientation == Qt::Horizontal && qobject_cast<QVBoxLayout *>(buttonLayout) != 0)
       
   309         || (orientation == Qt::Vertical && qobject_cast<QHBoxLayout *>(buttonLayout) != 0);
       
   310     if (createNewLayout) {
       
   311         delete buttonLayout;
       
   312         if (orientation == Qt::Horizontal)
       
   313             buttonLayout = new QHBoxLayout(q);
       
   314         else
       
   315             buttonLayout = new QVBoxLayout(q);
       
   316     }
       
   317 
       
   318 	int left, top, right, bottom;
       
   319     setLayoutItemMargins(QStyle::SE_PushButtonLayoutItem);
       
   320 	getLayoutItemMargins(&left, &top, &right, &bottom);
       
   321     buttonLayout->setContentsMargins(-left, -top, -right, -bottom);
       
   322 
       
   323     if (!q->testAttribute(Qt::WA_WState_OwnSizePolicy)) {
       
   324         QSizePolicy sp(QSizePolicy::Expanding, QSizePolicy::Fixed, QSizePolicy::ButtonBox);
       
   325         if (orientation == Qt::Vertical)
       
   326             sp.transpose();
       
   327         q->setSizePolicy(sp);
       
   328         q->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
       
   329     }
       
   330 
       
   331     // ### move to a real init() function
       
   332     q->setFocusPolicy(Qt::TabFocus);
       
   333 }
       
   334 
       
   335 void QDialogButtonBoxPrivate::resetLayout()
       
   336 {
       
   337     //delete buttonLayout;
       
   338     initLayout();
       
   339     layoutButtons();
       
   340 }
       
   341 
       
   342 void QDialogButtonBoxPrivate::addButtonsToLayout(const QList<QAbstractButton *> &buttonList,
       
   343                                                  bool reverse)
       
   344 {
       
   345     int start = reverse ? buttonList.count() - 1 : 0;
       
   346     int end = reverse ? -1 : buttonList.count();
       
   347     int step = reverse ? -1 : 1;
       
   348 
       
   349     for (int i = start; i != end; i += step) {
       
   350         QAbstractButton *button = buttonList.at(i);
       
   351         buttonLayout->addWidget(button);
       
   352         button->show();
       
   353     }
       
   354 }
       
   355 
       
   356 void QDialogButtonBoxPrivate::layoutButtons()
       
   357 {
       
   358     Q_Q(QDialogButtonBox);
       
   359     const int MacGap = 36 - 8;	// 8 is the default gap between a widget and a spacer item
       
   360 
       
   361     for (int i = buttonLayout->count() - 1; i >= 0; --i) {
       
   362         QLayoutItem *item = buttonLayout->takeAt(i);
       
   363         if (QWidget *widget = item->widget())
       
   364             widget->hide();
       
   365         delete item;
       
   366     }
       
   367 
       
   368     int tmpPolicy = layoutPolicy;
       
   369 
       
   370     static const int M = 5;
       
   371     static const int ModalRoles[M] = { AcceptRole, RejectRole, DestructiveRole, YesRole, NoRole };
       
   372     if (tmpPolicy == QDialogButtonBox::MacLayout) {
       
   373         bool hasModalButton = false;
       
   374         for (int i = 0; i < M; ++i) {
       
   375             if (!buttonLists[ModalRoles[i]].isEmpty()) {
       
   376                 hasModalButton = true;
       
   377                 break;
       
   378             }
       
   379         }
       
   380         if (!hasModalButton)
       
   381             tmpPolicy = 4;  // Mac modeless
       
   382     }
       
   383 
       
   384     const int *currentLayout = layouts[orientation == Qt::Vertical][tmpPolicy];
       
   385 
       
   386     if (center)
       
   387         buttonLayout->addStretch();
       
   388 
       
   389     QList<QAbstractButton *> acceptRoleList = buttonLists[AcceptRole];
       
   390 
       
   391     while (*currentLayout != EOL) {
       
   392         int role = (*currentLayout & ~Reverse);
       
   393         bool reverse = (*currentLayout & Reverse);
       
   394 
       
   395         switch (role) {
       
   396         case Stretch:
       
   397             if (!center)
       
   398                 buttonLayout->addStretch();
       
   399             break;
       
   400         case AcceptRole: {
       
   401             if (acceptRoleList.isEmpty())
       
   402                 break;
       
   403             // Only the first one
       
   404             QAbstractButton *button = acceptRoleList.first();
       
   405             buttonLayout->addWidget(button);
       
   406             button->show();
       
   407         }
       
   408             break;
       
   409         case AlternateRole:
       
   410             {
       
   411                 if (acceptRoleList.size() < 2)
       
   412                     break;
       
   413                 QList<QAbstractButton *> list = acceptRoleList;
       
   414                 list.removeFirst();
       
   415                 addButtonsToLayout(list, reverse);
       
   416             }
       
   417             break;
       
   418         case DestructiveRole:
       
   419             {
       
   420                 const QList<QAbstractButton *> &list = buttonLists[role];
       
   421 
       
   422                 /*
       
   423                     Mac: Insert a gap on the left of the destructive
       
   424                     buttons to ensure that they don't get too close to
       
   425                     the help and action buttons (but only if there are
       
   426                     some buttons to the left of the destructive buttons
       
   427                     (and the stretch, whence buttonLayout->count() > 1
       
   428                     and not 0)).
       
   429                 */
       
   430                 if (tmpPolicy == QDialogButtonBox::MacLayout
       
   431                         && !list.isEmpty() && buttonLayout->count() > 1)
       
   432                     buttonLayout->addSpacing(MacGap);
       
   433 
       
   434                 addButtonsToLayout(list, reverse);
       
   435 
       
   436                 /*
       
   437                     Insert a gap between the destructive buttons and the
       
   438                     accept and reject buttons.
       
   439                 */
       
   440                 if (tmpPolicy == QDialogButtonBox::MacLayout && !list.isEmpty())
       
   441                     buttonLayout->addSpacing(MacGap);
       
   442             }
       
   443             break;
       
   444         case RejectRole:
       
   445         case ActionRole:
       
   446         case HelpRole:
       
   447         case YesRole:
       
   448         case NoRole:
       
   449         case ApplyRole:
       
   450         case ResetRole:
       
   451             addButtonsToLayout(buttonLists[role], reverse);
       
   452         }
       
   453         ++currentLayout;
       
   454     }
       
   455 
       
   456     QWidget *lastWidget = 0;
       
   457     q->setFocusProxy(0);
       
   458     for (int i = 0; i < buttonLayout->count(); ++i) {
       
   459         QLayoutItem *item = buttonLayout->itemAt(i);
       
   460         if (QWidget *widget = item->widget()) {
       
   461             if (lastWidget)
       
   462                 QWidget::setTabOrder(lastWidget, widget);
       
   463             else
       
   464                 q->setFocusProxy(widget);
       
   465             lastWidget = widget;
       
   466         }
       
   467     }
       
   468 
       
   469     if (center)
       
   470         buttonLayout->addStretch();
       
   471 }
       
   472 
       
   473 QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardButton sbutton,
       
   474                                                    bool doLayout)
       
   475 {
       
   476     Q_Q(QDialogButtonBox);
       
   477     const char *buttonText = 0;
       
   478     int icon = 0;
       
   479 
       
   480     switch (sbutton) {
       
   481     case QDialogButtonBox::Ok:
       
   482         icon = QStyle::SP_DialogOkButton;
       
   483         break;
       
   484     case QDialogButtonBox::Save:
       
   485         icon = QStyle::SP_DialogSaveButton;
       
   486         break;
       
   487     case QDialogButtonBox::Open:
       
   488         icon = QStyle::SP_DialogOpenButton;
       
   489         break;
       
   490     case QDialogButtonBox::Cancel:
       
   491         icon = QStyle::SP_DialogCancelButton;
       
   492         break;
       
   493     case QDialogButtonBox::Close:
       
   494         icon = QStyle::SP_DialogCloseButton;
       
   495         break;
       
   496     case QDialogButtonBox::Apply:
       
   497         icon = QStyle::SP_DialogApplyButton;
       
   498         break;
       
   499     case QDialogButtonBox::Reset:
       
   500         icon = QStyle::SP_DialogResetButton;
       
   501         break;
       
   502     case QDialogButtonBox::Help:
       
   503         icon = QStyle::SP_DialogHelpButton;
       
   504         break;
       
   505     case QDialogButtonBox::Discard:
       
   506         icon = QStyle::SP_DialogDiscardButton;
       
   507         break;
       
   508     case QDialogButtonBox::Yes:
       
   509         icon = QStyle::SP_DialogYesButton;
       
   510         break;
       
   511     case QDialogButtonBox::No:
       
   512         icon = QStyle::SP_DialogNoButton;
       
   513         break;
       
   514     case QDialogButtonBox::YesToAll:
       
   515     case QDialogButtonBox::NoToAll:
       
   516     case QDialogButtonBox::SaveAll:
       
   517     case QDialogButtonBox::Abort:
       
   518     case QDialogButtonBox::Retry:
       
   519     case QDialogButtonBox::Ignore:
       
   520     case QDialogButtonBox::RestoreDefaults:
       
   521         break;
       
   522     case QDialogButtonBox::NoButton:
       
   523         return 0;
       
   524         ;
       
   525     }
       
   526     buttonText = standardButtonText(sbutton);
       
   527 
       
   528     QPushButton *button = new QPushButton(QDialogButtonBox::tr(buttonText), q);
       
   529     QStyle *style = q->style();
       
   530     if (style->styleHint(QStyle::SH_DialogButtonBox_ButtonsHaveIcons, 0, q) && icon != 0)
       
   531         button->setIcon(style->standardIcon(QStyle::StandardPixmap(icon), 0, q));
       
   532     if (style != QApplication::style()) // Propagate style
       
   533         button->setStyle(style);
       
   534     standardButtonHash.insert(button, sbutton);
       
   535     if (roleFor(sbutton) != QDialogButtonBox::InvalidRole) {
       
   536         addButton(button, roleFor(sbutton), doLayout);
       
   537     } else {
       
   538         qWarning("QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
       
   539     }
       
   540     return button;
       
   541 }
       
   542 
       
   543 void QDialogButtonBoxPrivate::addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role,
       
   544                                         bool doLayout)
       
   545 {
       
   546     Q_Q(QDialogButtonBox);
       
   547     QObject::connect(button, SIGNAL(clicked()), q, SLOT(_q_handleButtonClicked()));
       
   548     QObject::connect(button, SIGNAL(destroyed()), q, SLOT(_q_handleButtonDestroyed()));
       
   549     buttonLists[role].append(button);
       
   550 #ifdef QT_SOFTKEYS_ENABLED
       
   551     softKeyActions.insert(button, createSoftKey(button, role));
       
   552 #endif
       
   553     if (doLayout)
       
   554         layoutButtons();
       
   555 }
       
   556 
       
   557 #ifdef QT_SOFTKEYS_ENABLED
       
   558 QAction* QDialogButtonBoxPrivate::createSoftKey(QAbstractButton *button, QDialogButtonBox::ButtonRole role)
       
   559 {
       
   560     Q_Q(QDialogButtonBox);
       
   561     QAction::SoftKeyRole softkeyRole;
       
   562 
       
   563     QAction *action = new QAction(button->text(), button);
       
   564 
       
   565     switch (role) {
       
   566     case ApplyRole:
       
   567     case AcceptRole:
       
   568     case YesRole:
       
   569     case ActionRole:
       
   570     case HelpRole:
       
   571         softkeyRole = QAction::PositiveSoftKey;
       
   572         break;
       
   573     case RejectRole:
       
   574     case DestructiveRole:
       
   575     case NoRole:
       
   576     case ResetRole:
       
   577         softkeyRole = QAction::NegativeSoftKey;
       
   578         break;
       
   579     default:
       
   580         break;
       
   581     }
       
   582     QObject::connect(action, SIGNAL(triggered()), button, SIGNAL(clicked()));
       
   583     action->setSoftKeyRole(softkeyRole);
       
   584     return action;
       
   585 }
       
   586 #endif
       
   587 
       
   588 void QDialogButtonBoxPrivate::createStandardButtons(QDialogButtonBox::StandardButtons buttons)
       
   589 {
       
   590     uint i = QDialogButtonBox::FirstButton;
       
   591     while (i <= QDialogButtonBox::LastButton) {
       
   592         if (i & buttons) {
       
   593             createButton(QDialogButtonBox::StandardButton(i), false);
       
   594         }
       
   595         i = i << 1;
       
   596     }
       
   597     layoutButtons();
       
   598 }
       
   599 
       
   600 const char *QDialogButtonBoxPrivate::standardButtonText(QDialogButtonBox::StandardButton sbutton) const
       
   601 {
       
   602     const char *buttonText = 0;
       
   603     bool gnomeLayout = (layoutPolicy == QDialogButtonBox::GnomeLayout);
       
   604     switch (sbutton) {
       
   605     case QDialogButtonBox::Ok:
       
   606         buttonText = gnomeLayout ? QT_TRANSLATE_NOOP("QDialogButtonBox", "&OK") : QT_TRANSLATE_NOOP("QDialogButtonBox", "OK");
       
   607         break;
       
   608     case QDialogButtonBox::Save:
       
   609         buttonText = gnomeLayout ? QT_TRANSLATE_NOOP("QDialogButtonBox", "&Save") : QT_TRANSLATE_NOOP("QDialogButtonBox", "Save");
       
   610         break;
       
   611     case QDialogButtonBox::Open:
       
   612         buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Open");
       
   613         break;
       
   614     case QDialogButtonBox::Cancel:
       
   615         buttonText = gnomeLayout ? QT_TRANSLATE_NOOP("QDialogButtonBox", "&Cancel") : QT_TRANSLATE_NOOP("QDialogButtonBox", "Cancel");
       
   616         break;
       
   617     case QDialogButtonBox::Close:
       
   618         buttonText = gnomeLayout ? QT_TRANSLATE_NOOP("QDialogButtonBox", "&Close") : QT_TRANSLATE_NOOP("QDialogButtonBox", "Close");
       
   619         break;
       
   620     case QDialogButtonBox::Apply:
       
   621         buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Apply");
       
   622         break;
       
   623     case QDialogButtonBox::Reset:
       
   624         buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Reset");
       
   625         break;
       
   626     case QDialogButtonBox::Help:
       
   627         buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Help");
       
   628         break;
       
   629     case QDialogButtonBox::Discard:
       
   630         if (layoutPolicy == QDialogButtonBox::MacLayout)
       
   631             buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Don't Save");
       
   632         else if (layoutPolicy == QDialogButtonBox::GnomeLayout)
       
   633             buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Close without Saving");
       
   634         else
       
   635             buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Discard");
       
   636         break;
       
   637     case QDialogButtonBox::Yes:
       
   638         buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "&Yes");
       
   639         break;
       
   640     case QDialogButtonBox::YesToAll:
       
   641         buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Yes to &All");
       
   642         break;
       
   643     case QDialogButtonBox::No:
       
   644         buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "&No");
       
   645         break;
       
   646     case QDialogButtonBox::NoToAll:
       
   647         buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "N&o to All");
       
   648         break;
       
   649     case QDialogButtonBox::SaveAll:
       
   650         buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Save All");
       
   651         break;
       
   652     case QDialogButtonBox::Abort:
       
   653         buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Abort");
       
   654         break;
       
   655     case QDialogButtonBox::Retry:
       
   656         buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Retry");
       
   657         break;
       
   658     case QDialogButtonBox::Ignore:
       
   659         buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Ignore");
       
   660         break;
       
   661     case QDialogButtonBox::RestoreDefaults:
       
   662         buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Restore Defaults");
       
   663         break;
       
   664     case QDialogButtonBox::NoButton:
       
   665         ;
       
   666     } // switch
       
   667     return buttonText;
       
   668 }
       
   669 
       
   670 void QDialogButtonBoxPrivate::retranslateStrings()
       
   671 {
       
   672     const char *buttonText = 0;
       
   673     QHash<QPushButton *, QDialogButtonBox::StandardButton>::iterator it =  standardButtonHash.begin();
       
   674     while (it != standardButtonHash.end()) {
       
   675         buttonText = standardButtonText(it.value());
       
   676         if (buttonText) {
       
   677             QPushButton *button = it.key();
       
   678             button->setText(QDialogButtonBox::tr(buttonText));
       
   679 #ifdef QT_SOFTKEYS_ENABLED
       
   680             QAction *action = softKeyActions.value(button, 0);
       
   681             if (action)
       
   682                 action->setText(button->text());
       
   683 #endif
       
   684         }
       
   685         ++it;
       
   686     }
       
   687 }
       
   688 
       
   689 /*!
       
   690     Constructs an empty, horizontal button box with the given \a parent.
       
   691 
       
   692     \sa orientation, addButton()
       
   693 */
       
   694 QDialogButtonBox::QDialogButtonBox(QWidget *parent)
       
   695     : QWidget(*new QDialogButtonBoxPrivate(Qt::Horizontal), parent, 0)
       
   696 {
       
   697     d_func()->initLayout();
       
   698 }
       
   699 
       
   700 /*!
       
   701     Constructs an empty button box with the given \a orientation and \a parent.
       
   702 
       
   703     \sa orientation, addButton()
       
   704 */
       
   705 QDialogButtonBox::QDialogButtonBox(Qt::Orientation orientation, QWidget *parent)
       
   706     : QWidget(*new QDialogButtonBoxPrivate(orientation), parent, 0)
       
   707 {
       
   708     d_func()->initLayout();
       
   709 }
       
   710 
       
   711 /*!
       
   712     Constructs a button box with the given \a orientation and \a parent, containing
       
   713     the standard buttons specified by \a buttons.
       
   714 
       
   715     \sa orientation, addButton()
       
   716 */
       
   717 QDialogButtonBox::QDialogButtonBox(StandardButtons buttons, Qt::Orientation orientation,
       
   718                                    QWidget *parent)
       
   719     : QWidget(*new QDialogButtonBoxPrivate(orientation), parent, 0)
       
   720 {
       
   721     d_func()->initLayout();
       
   722     d_func()->createStandardButtons(buttons);
       
   723 }
       
   724 
       
   725 /*!
       
   726     Destroys the button box.
       
   727 */
       
   728 QDialogButtonBox::~QDialogButtonBox()
       
   729 {
       
   730 }
       
   731 
       
   732 /*!
       
   733     \enum QDialogButtonBox::ButtonRole
       
   734     \enum QMessageBox::ButtonRole
       
   735 
       
   736     This enum describes the roles that can be used to describe buttons in
       
   737     the button box. Combinations of these roles are as flags used to
       
   738     describe different aspects of their behavior.
       
   739 
       
   740     \value InvalidRole The button is invalid.
       
   741     \value AcceptRole Clicking the button causes the dialog to be accepted
       
   742            (e.g. OK).
       
   743     \value RejectRole Clicking the button causes the dialog to be rejected
       
   744            (e.g. Cancel).
       
   745     \value DestructiveRole Clicking the button causes a destructive change
       
   746            (e.g. for Discarding Changes) and closes the dialog.
       
   747     \value ActionRole Clicking the button causes changes to the elements within
       
   748            the dialog.
       
   749     \value HelpRole The button can be clicked to request help.
       
   750     \value YesRole The button is a "Yes"-like button.
       
   751     \value NoRole The button is a "No"-like button.
       
   752     \value ApplyRole The button applies current changes.
       
   753     \value ResetRole The button resets the dialog's fields to default values.
       
   754 
       
   755     \omitvalue NRoles
       
   756 
       
   757     \sa StandardButton
       
   758 */
       
   759 
       
   760 /*!
       
   761     \enum QDialogButtonBox::StandardButton
       
   762 
       
   763     These enums describe flags for standard buttons. Each button has a
       
   764     defined \l ButtonRole.
       
   765 
       
   766     \value Ok An "OK" button defined with the \l AcceptRole.
       
   767     \value Open A "Open" button defined with the \l AcceptRole.
       
   768     \value Save A "Save" button defined with the \l AcceptRole.
       
   769     \value Cancel A "Cancel" button defined with the \l RejectRole.
       
   770     \value Close A "Close" button defined with the \l RejectRole.
       
   771     \value Discard A "Discard" or "Don't Save" button, depending on the platform,
       
   772                     defined with the \l DestructiveRole.
       
   773     \value Apply An "Apply" button defined with the \l ApplyRole.
       
   774     \value Reset A "Reset" button defined with the \l ResetRole.
       
   775     \value RestoreDefaults A "Restore Defaults" button defined with the \l ResetRole.
       
   776     \value Help A "Help" button defined with the \l HelpRole.
       
   777     \value SaveAll A "Save All" button defined with the \l AcceptRole.
       
   778     \value Yes A "Yes" button defined with the \l YesRole.
       
   779     \value YesToAll A "Yes to All" button defined with the \l YesRole.
       
   780     \value No A "No" button defined with the \l NoRole.
       
   781     \value NoToAll A "No to All" button defined with the \l NoRole.
       
   782     \value Abort An "Abort" button defined with the \l RejectRole.
       
   783     \value Retry A "Retry" button defined with the \l AcceptRole.
       
   784     \value Ignore An "Ignore" button defined with the \l AcceptRole.
       
   785 
       
   786     \value NoButton An invalid button.
       
   787 
       
   788     \omitvalue FirstButton
       
   789     \omitvalue LastButton
       
   790 
       
   791     \sa ButtonRole, standardButtons
       
   792 */
       
   793 
       
   794 /*!
       
   795     \enum QDialogButtonBox::ButtonLayout
       
   796 
       
   797     This enum describes the layout policy to be used when arranging the buttons
       
   798     contained in the button box.
       
   799 
       
   800     \value WinLayout Use a policy appropriate for applications on Windows.
       
   801     \value MacLayout Use a policy appropriate for applications on Mac OS X.
       
   802     \value KdeLayout Use a policy appropriate for applications on KDE.
       
   803     \value GnomeLayout Use a policy appropriate for applications on GNOME.
       
   804 
       
   805     The button layout is specified by the \l{style()}{current style}. However,
       
   806     on the X11 platform, it may be influenced by the desktop environment.
       
   807 */
       
   808 
       
   809 /*!
       
   810     \fn void QDialogButtonBox::clicked(QAbstractButton *button)
       
   811 
       
   812     This signal is emitted when a button inside the button box is clicked. The
       
   813     specific button that was pressed is specified by \a button.
       
   814 
       
   815     \sa accepted(), rejected(), helpRequested()
       
   816 */
       
   817 
       
   818 /*!
       
   819     \fn void QDialogButtonBox::accepted()
       
   820 
       
   821     This signal is emitted when a button inside the button box is clicked, as long
       
   822     as it was defined with the \l AcceptRole or \l YesRole.
       
   823 
       
   824     \sa rejected(), clicked() helpRequested()
       
   825 */
       
   826 
       
   827 /*!
       
   828     \fn void QDialogButtonBox::rejected()
       
   829 
       
   830     This signal is emitted when a button inside the button box is clicked, as long
       
   831     as it was defined with the \l RejectRole or \l NoRole.
       
   832 
       
   833     \sa accepted() helpRequested() clicked()
       
   834 */
       
   835 
       
   836 /*!
       
   837     \fn void QDialogButtonBox::helpRequested()
       
   838 
       
   839     This signal is emitted when a button inside the button box is clicked, as long
       
   840     as it was defined with the \l HelpRole.
       
   841 
       
   842     \sa accepted() rejected() clicked()
       
   843 */
       
   844 
       
   845 /*!
       
   846     \property QDialogButtonBox::orientation
       
   847     \brief the orientation of the button box
       
   848 
       
   849     By default, the orientation is horizontal (i.e. the buttons are laid out
       
   850     side by side). The possible orientations are Qt::Horizontal and
       
   851     Qt::Vertical.
       
   852 */
       
   853 Qt::Orientation QDialogButtonBox::orientation() const
       
   854 {
       
   855     return d_func()->orientation;
       
   856 }
       
   857 
       
   858 void QDialogButtonBox::setOrientation(Qt::Orientation orientation)
       
   859 {
       
   860     Q_D(QDialogButtonBox);
       
   861     if (orientation == d->orientation)
       
   862         return;
       
   863 
       
   864     d->orientation = orientation;
       
   865     d->resetLayout();
       
   866 }
       
   867 
       
   868 /*!
       
   869     Clears the button box, deleting all buttons within it.
       
   870 
       
   871     \sa removeButton(), addButton()
       
   872 */
       
   873 void QDialogButtonBox::clear()
       
   874 {
       
   875     Q_D(QDialogButtonBox);
       
   876 #ifdef QT_SOFTKEYS_ENABLED
       
   877     // Delete softkey actions as they have the buttons as parents
       
   878     qDeleteAll(d->softKeyActions.values());
       
   879     d->softKeyActions.clear();
       
   880 #endif
       
   881     // Remove the created standard buttons, they should be in the other lists, which will
       
   882     // do the deletion
       
   883     d->standardButtonHash.clear();
       
   884     for (int i = 0; i < NRoles; ++i) {
       
   885         QList<QAbstractButton *> &list = d->buttonLists[i];
       
   886         while (list.count()) {
       
   887             QAbstractButton *button = list.takeAt(0);
       
   888             QObject::disconnect(button, SIGNAL(destroyed()), this, SLOT(_q_handleButtonDestroyed()));
       
   889             delete button;
       
   890         }
       
   891     }
       
   892 }
       
   893 
       
   894 /*!
       
   895     Returns a list of all the buttons that have been added to the button box.
       
   896 
       
   897     \sa buttonRole(), addButton(), removeButton()
       
   898 */
       
   899 QList<QAbstractButton *> QDialogButtonBox::buttons() const
       
   900 {
       
   901     Q_D(const QDialogButtonBox);
       
   902     QList<QAbstractButton *> finalList;
       
   903     for (int i = 0; i < NRoles; ++i) {
       
   904         const QList<QAbstractButton *> &list = d->buttonLists[i];
       
   905         for (int j = 0; j < list.count(); ++j)
       
   906             finalList.append(list.at(j));
       
   907     }
       
   908     return finalList;
       
   909 }
       
   910 
       
   911 /*!
       
   912     Returns the button role for the specified \a button. This function returns
       
   913     \l InvalidRole if \a button is 0 or has not been added to the button box.
       
   914 
       
   915     \sa buttons(), addButton()
       
   916 */
       
   917 QDialogButtonBox::ButtonRole QDialogButtonBox::buttonRole(QAbstractButton *button) const
       
   918 {
       
   919     Q_D(const QDialogButtonBox);
       
   920     for (int i = 0; i < NRoles; ++i) {
       
   921         const QList<QAbstractButton *> &list = d->buttonLists[i];
       
   922         for (int j = 0; j < list.count(); ++j) {
       
   923             if (list.at(j) == button)
       
   924                 return ButtonRole(i);
       
   925         }
       
   926     }
       
   927     return InvalidRole;
       
   928 }
       
   929 
       
   930 /*!
       
   931     Removes \a button from the button box without deleting it and sets its parent to zero.
       
   932 
       
   933     \sa clear(), buttons(), addButton()
       
   934 */
       
   935 void QDialogButtonBox::removeButton(QAbstractButton *button)
       
   936 {
       
   937     Q_D(QDialogButtonBox);
       
   938 
       
   939     if (!button)
       
   940         return;
       
   941 
       
   942     // Remove it from the standard button hash first and then from the roles
       
   943     if (QPushButton *pushButton = qobject_cast<QPushButton *>(button))
       
   944         d->standardButtonHash.remove(pushButton);
       
   945     for (int i = 0; i < NRoles; ++i) {
       
   946         QList<QAbstractButton *> &list = d->buttonLists[i];
       
   947         for (int j = 0; j < list.count(); ++j) {
       
   948             if (list.at(j) == button) {
       
   949                 list.takeAt(j);
       
   950                 if (!d->internalRemove) {
       
   951                     disconnect(button, SIGNAL(clicked()), this, SLOT(_q_handleButtonClicked()));
       
   952                     disconnect(button, SIGNAL(destroyed()), this, SLOT(_q_handleButtonDestroyed()));
       
   953                 }
       
   954                 break;
       
   955             }
       
   956         }
       
   957     }
       
   958 #ifdef QT_SOFTKEYS_ENABLED
       
   959     QAction *action = d->softKeyActions.value(button, 0);
       
   960     if (action) {
       
   961         d->softKeyActions.remove(button);
       
   962         delete action;
       
   963     }
       
   964 #endif
       
   965     if (!d->internalRemove)
       
   966         button->setParent(0);
       
   967 }
       
   968 
       
   969 /*!
       
   970     Adds the given \a button to the button box with the specified \a role.
       
   971     If the role is invalid, the button is not added.
       
   972 
       
   973     If the button has already been added, it is removed and added again with the
       
   974     new role.
       
   975 
       
   976     \sa removeButton(), clear()
       
   977 */
       
   978 void QDialogButtonBox::addButton(QAbstractButton *button, ButtonRole role)
       
   979 {
       
   980     Q_D(QDialogButtonBox);
       
   981     if (role <= InvalidRole || role >= NRoles) {
       
   982         qWarning("QDialogButtonBox::addButton: Invalid ButtonRole, button not added");
       
   983         return;
       
   984     }
       
   985     removeButton(button);
       
   986     button->setParent(this);
       
   987     d->addButton(button, role);
       
   988 }
       
   989 
       
   990 /*!
       
   991     Creates a push button with the given \a text, adds it to the button box for the
       
   992     specified \a role, and returns the corresponding push button. If \a role is
       
   993     invalid, no button is created, and zero is returned.
       
   994 
       
   995     \sa removeButton(), clear()
       
   996 */
       
   997 QPushButton *QDialogButtonBox::addButton(const QString &text, ButtonRole role)
       
   998 {
       
   999     Q_D(QDialogButtonBox);
       
  1000     if (role <= InvalidRole || role >= NRoles) {
       
  1001         qWarning("QDialogButtonBox::addButton: Invalid ButtonRole, button not added");
       
  1002         return 0;
       
  1003     }
       
  1004     QPushButton *button = new QPushButton(text, this);
       
  1005     d->addButton(button, role);
       
  1006     return button;
       
  1007 }
       
  1008 
       
  1009 /*!
       
  1010     Adds a standard \a button to the button box if it is valid to do so, and returns
       
  1011     a push button. If \a button is invalid, it is not added to the button box, and
       
  1012     zero is returned.
       
  1013 
       
  1014     \sa removeButton(), clear()
       
  1015 */
       
  1016 QPushButton *QDialogButtonBox::addButton(StandardButton button)
       
  1017 {
       
  1018     Q_D(QDialogButtonBox);
       
  1019     return d->createButton(button);
       
  1020 }
       
  1021 
       
  1022 /*!
       
  1023     \property QDialogButtonBox::standardButtons
       
  1024     \brief collection of standard buttons in the button box
       
  1025 
       
  1026     This property controls which standard buttons are used by the button box.
       
  1027 
       
  1028     \sa addButton()
       
  1029 */
       
  1030 void QDialogButtonBox::setStandardButtons(StandardButtons buttons)
       
  1031 {
       
  1032     Q_D(QDialogButtonBox);
       
  1033 #ifdef QT_SOFTKEYS_ENABLED
       
  1034     // Delete softkey actions since they have the buttons as parents
       
  1035     qDeleteAll(d->softKeyActions.values());
       
  1036     d->softKeyActions.clear();
       
  1037 #endif
       
  1038     // Clear out all the old standard buttons, then recreate them.
       
  1039     qDeleteAll(d->standardButtonHash.keys());
       
  1040     d->standardButtonHash.clear();
       
  1041 
       
  1042     d->createStandardButtons(buttons);
       
  1043 }
       
  1044 
       
  1045 QDialogButtonBox::StandardButtons QDialogButtonBox::standardButtons() const
       
  1046 {
       
  1047     Q_D(const QDialogButtonBox);
       
  1048     StandardButtons standardButtons = NoButton;
       
  1049     QHash<QPushButton *, StandardButton>::const_iterator it = d->standardButtonHash.constBegin();
       
  1050     while (it != d->standardButtonHash.constEnd()) {
       
  1051         standardButtons |= it.value();
       
  1052         ++it;
       
  1053     }
       
  1054     return standardButtons;
       
  1055 }
       
  1056 
       
  1057 /*!
       
  1058     Returns the QPushButton corresponding to the standard button \a which,
       
  1059     or 0 if the standard button doesn't exist in this button box.
       
  1060 
       
  1061     \sa standardButton(), standardButtons(), buttons()
       
  1062 */
       
  1063 QPushButton *QDialogButtonBox::button(StandardButton which) const
       
  1064 {
       
  1065     Q_D(const QDialogButtonBox);
       
  1066     return d->standardButtonHash.key(which);
       
  1067 }
       
  1068 
       
  1069 /*!
       
  1070     Returns the standard button enum value corresponding to the given \a button,
       
  1071     or NoButton if the given \a button isn't a standard button.
       
  1072 
       
  1073     \sa button(), buttons(), standardButtons()
       
  1074 */
       
  1075 QDialogButtonBox::StandardButton QDialogButtonBox::standardButton(QAbstractButton *button) const
       
  1076 {
       
  1077     Q_D(const QDialogButtonBox);
       
  1078     return d->standardButtonHash.value(static_cast<QPushButton *>(button));
       
  1079 }
       
  1080 
       
  1081 void QDialogButtonBoxPrivate::_q_handleButtonClicked()
       
  1082 {
       
  1083     Q_Q(QDialogButtonBox);
       
  1084     if (QAbstractButton *button = qobject_cast<QAbstractButton *>(q->sender())) {
       
  1085         emit q->clicked(button);
       
  1086 
       
  1087         switch (q->buttonRole(button)) {
       
  1088         case AcceptRole:
       
  1089         case YesRole:
       
  1090             emit q->accepted();
       
  1091             break;
       
  1092         case RejectRole:
       
  1093         case NoRole:
       
  1094             emit q->rejected();
       
  1095             break;
       
  1096         case HelpRole:
       
  1097             emit q->helpRequested();
       
  1098             break;
       
  1099         default:
       
  1100             break;
       
  1101         }
       
  1102     }
       
  1103 }
       
  1104 
       
  1105 void QDialogButtonBoxPrivate::_q_handleButtonDestroyed()
       
  1106 {
       
  1107     Q_Q(QDialogButtonBox);
       
  1108     if (QObject *object = q->sender()) {
       
  1109         QBoolBlocker skippy(internalRemove);
       
  1110         q->removeButton(static_cast<QAbstractButton *>(object));
       
  1111     }
       
  1112 }
       
  1113 
       
  1114 /*!
       
  1115     \property QDialogButtonBox::centerButtons
       
  1116     \brief whether the buttons in the button box are centered
       
  1117 
       
  1118     By default, this property is false. This behavior is appopriate
       
  1119     for most types of dialogs. A notable exception is message boxes
       
  1120     on most platforms (e.g. Windows), where the button box is
       
  1121     centered horizontally.
       
  1122 
       
  1123     \sa QMessageBox
       
  1124 */
       
  1125 void QDialogButtonBox::setCenterButtons(bool center)
       
  1126 {
       
  1127     Q_D(QDialogButtonBox);
       
  1128     if (d->center != center) {
       
  1129         d->center = center;
       
  1130         d->resetLayout();
       
  1131     }
       
  1132 }
       
  1133 
       
  1134 bool QDialogButtonBox::centerButtons() const
       
  1135 {
       
  1136     Q_D(const QDialogButtonBox);
       
  1137     return d->center;
       
  1138 }
       
  1139 
       
  1140 /*!
       
  1141     \reimp
       
  1142 */
       
  1143 void QDialogButtonBox::changeEvent(QEvent *event)
       
  1144 {
       
  1145     typedef QHash<QPushButton *, QDialogButtonBox::StandardButton> StandardButtonHash;
       
  1146 
       
  1147     Q_D(QDialogButtonBox);
       
  1148     switch (event->type()) {
       
  1149     case QEvent::StyleChange:  // Propagate style
       
  1150         if (!d->standardButtonHash.empty()) {
       
  1151             QStyle *newStyle = style();
       
  1152             const StandardButtonHash::iterator end = d->standardButtonHash.end();
       
  1153             for (StandardButtonHash::iterator it = d->standardButtonHash.begin(); it != end; ++it)
       
  1154                 it.key()->setStyle(newStyle);
       
  1155         }
       
  1156         // fallthrough intended
       
  1157 #ifdef Q_WS_MAC
       
  1158     case QEvent::MacSizeChange:
       
  1159 #endif
       
  1160         d->resetLayout();
       
  1161         QWidget::changeEvent(event);
       
  1162         break;
       
  1163     default:
       
  1164         QWidget::changeEvent(event);
       
  1165         break;
       
  1166     }
       
  1167 }
       
  1168 
       
  1169 /*!
       
  1170     \reimp
       
  1171 */
       
  1172 bool QDialogButtonBox::event(QEvent *event)
       
  1173 {
       
  1174     Q_D(QDialogButtonBox);
       
  1175     if (event->type() == QEvent::Show) {
       
  1176         QList<QAbstractButton *> acceptRoleList = d->buttonLists[AcceptRole];
       
  1177         QPushButton *firstAcceptButton = acceptRoleList.isEmpty() ? 0 : qobject_cast<QPushButton *>(acceptRoleList.at(0));
       
  1178         bool hasDefault = false;
       
  1179         QWidget *dialog = 0;
       
  1180         QWidget *p = this;
       
  1181         while (p && !p->isWindow()) {
       
  1182             p = p->parentWidget();
       
  1183             if ((dialog = qobject_cast<QDialog *>(p)))
       
  1184                 break;
       
  1185         }
       
  1186 
       
  1187         foreach (QPushButton *pb, qFindChildren<QPushButton *>(dialog ? dialog : this)) {
       
  1188             if (pb->isDefault() && pb != firstAcceptButton) {
       
  1189                 hasDefault = true;
       
  1190                 break;
       
  1191             }
       
  1192         }
       
  1193         if (!hasDefault && firstAcceptButton)
       
  1194             firstAcceptButton->setDefault(true);
       
  1195 #ifdef QT_SOFTKEYS_ENABLED
       
  1196         if (dialog) {
       
  1197             setFixedSize(0,0);
       
  1198             dialog->addActions(d->softKeyActions.values());
       
  1199         } else {
       
  1200             addActions(d->softKeyActions.values());
       
  1201         }
       
  1202 #endif
       
  1203     }else if (event->type() == QEvent::LanguageChange) {
       
  1204         d->retranslateStrings();
       
  1205     }
       
  1206 
       
  1207     return QWidget::event(event);
       
  1208 }
       
  1209 
       
  1210 QT_END_NAMESPACE
       
  1211 
       
  1212 #include "moc_qdialogbuttonbox.cpp"