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