src/gui/widgets/qdialogbuttonbox.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
--- a/src/gui/widgets/qdialogbuttonbox.cpp	Tue Jan 26 12:42:25 2010 +0200
+++ b/src/gui/widgets/qdialogbuttonbox.cpp	Tue Feb 02 00:43:10 2010 +0200
@@ -46,6 +46,7 @@
 #include <QtGui/qdialog.h>
 #include <QtGui/qapplication.h>
 #include <QtGui/private/qwidget_p.h>
+#include <QtGui/qaction.h>
 
 #include "qdialogbuttonbox.h"
 
@@ -259,6 +260,31 @@
     }
 };
 
+class QDialogButtonEnabledProxy : public QObject
+{
+public:
+    QDialogButtonEnabledProxy(QObject *parent, QWidget *src, QAction *trg) : QObject(parent), source(src), target(trg)
+    {
+        source->installEventFilter(this);
+        target->setEnabled(source->isEnabled());
+    }
+    ~QDialogButtonEnabledProxy()
+    {
+        source->removeEventFilter(this);
+    }
+    bool eventFilter(QObject *object, QEvent *event)
+    {
+        if (object == source && event->type() == QEvent::EnabledChange) {
+            target->setEnabled(source->isEnabled());
+        }
+        return false;
+    };
+private:
+    QWidget *source;
+    QAction *target;
+};
+
+
 class QDialogButtonBoxPrivate : public QWidgetPrivate
 {
     Q_DECLARE_PUBLIC(QDialogButtonBox)
@@ -315,9 +341,9 @@
             buttonLayout = new QVBoxLayout(q);
     }
 
-	int left, top, right, bottom;
+    int left, top, right, bottom;
     setLayoutItemMargins(QStyle::SE_PushButtonLayoutItem);
-	getLayoutItemMargins(&left, &top, &right, &bottom);
+    getLayoutItemMargins(&left, &top, &right, &bottom);
     buttonLayout->setContentsMargins(-left, -top, -right, -bottom);
 
     if (!q->testAttribute(Qt::WA_WState_OwnSizePolicy)) {
@@ -356,7 +382,7 @@
 void QDialogButtonBoxPrivate::layoutButtons()
 {
     Q_Q(QDialogButtonBox);
-    const int MacGap = 36 - 8;	// 8 is the default gap between a widget and a spacer item
+    const int MacGap = 36 - 8;    // 8 is the default gap between a widget and a spacer item
 
     for (int i = buttonLayout->count() - 1; i >= 0; --i) {
         QLayoutItem *item = buttonLayout->takeAt(i);
@@ -548,7 +574,9 @@
     QObject::connect(button, SIGNAL(destroyed()), q, SLOT(_q_handleButtonDestroyed()));
     buttonLists[role].append(button);
 #ifdef QT_SOFTKEYS_ENABLED
-    softKeyActions.insert(button, createSoftKey(button, role));
+    QAction *action = createSoftKey(button, role);
+    softKeyActions.insert(button, action);
+    new QDialogButtonEnabledProxy(action, button, action);
 #endif
     if (doLayout)
         layoutButtons();
@@ -581,6 +609,22 @@
     }
     QObject::connect(action, SIGNAL(triggered()), button, SIGNAL(clicked()));
     action->setSoftKeyRole(softkeyRole);
+
+
+    QWidget *dialog = 0;
+    QWidget *p = q;
+    while (p && !p->isWindow()) {
+        p = p->parentWidget();
+        if ((dialog = qobject_cast<QDialog *>(p)))
+            break;
+    }
+
+    if (dialog) {
+        dialog->addAction(action);
+    } else {
+        q->addAction(action);
+    }
+
     return action;
 }
 #endif
@@ -1193,16 +1237,36 @@
         if (!hasDefault && firstAcceptButton)
             firstAcceptButton->setDefault(true);
 #ifdef QT_SOFTKEYS_ENABLED
-        if (dialog) {
+        if (dialog)
             setFixedSize(0,0);
-            dialog->addActions(d->softKeyActions.values());
-        } else {
-            addActions(d->softKeyActions.values());
-        }
 #endif
     }else if (event->type() == QEvent::LanguageChange) {
         d->retranslateStrings();
     }
+#ifdef QT_SOFTKEYS_ENABLED
+    else if (event->type() == QEvent::ParentChange) {
+        QWidget *dialog = 0;
+        QWidget *p = this;
+        while (p && !p->isWindow()) {
+            p = p->parentWidget();
+            if ((dialog = qobject_cast<QDialog *>(p)))
+                break;
+        }
+
+        // If the parent changes, then move the softkeys
+        for (QHash<QAbstractButton *, QAction *>::const_iterator it = d->softKeyActions.constBegin();
+            it != d->softKeyActions.constEnd(); ++it) {
+            QAction *current = it.value();
+            QList<QWidget *> widgets = current->associatedWidgets();
+            foreach (QWidget *w, widgets)
+                w->removeAction(current);
+            if (dialog)
+                dialog->addAction(current);
+            else
+                addAction(current);
+        }
+    }
+#endif
 
     return QWidget::event(event);
 }