QWidgets: Delayed creation of the QPlatformDialogHelper.
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Wed, 2 Nov 2011 14:35:18 +0000 (15:35 +0100)
committerQt by Nokia <qt-info@nokia.com>
Fri, 4 Nov 2011 00:54:02 +0000 (01:54 +0100)
- Create helper only once and ensure deletion
- Move nativeDialogInUse into QDialogPrivate, ensuring the native
  modal helper is called from QDialog::exec() only if it is true

Change-Id: Id92b278bb051ce254458f276fbf7075689a7d491
Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>
src/widgets/dialogs/qdialog.cpp
src/widgets/dialogs/qdialog_p.h
src/widgets/dialogs/qfiledialog.cpp
src/widgets/dialogs/qfiledialog_p.h

index 38609a9..28feb6b 100644 (file)
@@ -73,6 +73,21 @@ extern bool qt_wince_is_smartphone(); //is defined in qguifunctions_wce.cpp
 
 QT_BEGIN_NAMESPACE
 
+QPlatformDialogHelper *QDialogPrivate::platformHelper() const
+{
+    // Delayed creation of the platform, ensuring that
+    // that qobject_cast<> on the dialog works in the plugin.
+    if (!m_platformHelperCreated) {
+        m_platformHelperCreated = true;
+        QDialog *dialog = const_cast<QDialog *>(q_func());
+        m_platformHelper = QGuiApplicationPrivate::platformIntegration()
+                               ->createPlatformDialogHelper(dialog);
+        if (m_platformHelper)
+            m_platformHelper->d_ptr = const_cast<QDialogPrivate *>(this);
+    }
+    return m_platformHelper;
+}
+
 /*!
     \class QDialog
     \brief The QDialog class is the base class of dialog windows.
@@ -252,10 +267,6 @@ QDialog::QDialog(QWidget *parent, Qt::WindowFlags f)
     : QWidget(*new QDialogPrivate, parent,
               f | ((f & Qt::WindowType_Mask) == 0 ? Qt::Dialog : Qt::WindowType(0)))
 {
-    Q_D(QDialog);
-    d->platformHelper = QGuiApplicationPrivate::platformIntegration()->createPlatformDialogHelper(this);
-    if (d->platformHelper)
-        d->platformHelper->d_ptr = d_func();
 #ifdef Q_WS_WINCE
     if (!qt_wince_is_smartphone())
         setWindowFlags(windowFlags() | Qt::WindowOkButtonHint | QFlag(qt_wince_is_mobile() ? 0 : Qt::WindowCancelButtonHint));
@@ -515,8 +526,8 @@ int QDialog::exec()
     }
     show();
 
-    if (d->platformHelper)
-        d->platformHelper->platformNativeDialogModalHelp();
+    if (d->nativeDialogInUse)
+        d->platformHelper()->platformNativeDialogModalHelp();
 
     QEventLoop eventLoop;
     d->eventLoop = &eventLoop;
index 04e0d74..c88bda7 100644 (file)
@@ -75,8 +75,10 @@ public:
           resizer(0),
           sizeGripEnabled(false),
 #endif
-          rescode(0), resetModalityTo(-1), wasModalitySet(true), eventLoop(0), platformHelper(0)
+          rescode(0), resetModalityTo(-1), wasModalitySet(true), eventLoop(0),
+          nativeDialogInUse(false), m_platformHelper(0), m_platformHelperCreated(false)
         {}
+    ~QDialogPrivate() { delete m_platformHelper; }
 
     QPointer<QPushButton> mainDef;
     Qt::Orientation orientation;
@@ -104,7 +106,12 @@ public:
 
     QPointer<QEventLoop> eventLoop;
 
-    QPlatformDialogHelper *platformHelper;
+    bool nativeDialogInUse; // Assigned in setVisible_sys() in derived classes.
+    QPlatformDialogHelper *platformHelper() const;
+
+private:
+    mutable QPlatformDialogHelper *m_platformHelper;
+    mutable bool m_platformHelperCreated;
 };
 
 QT_END_NAMESPACE
index 4c0d50f..9b7c525 100644 (file)
@@ -516,7 +516,6 @@ QFileDialogPrivate::QFileDialogPrivate()
         useDefaultCaption(true),
         defaultFileTypes(true),
         fileNameLabelExplicitlySat(false),
-        nativeDialogInUse(false),
         qFileDialogUi(0)
 {
 }
@@ -2223,10 +2222,6 @@ void QFileDialogPrivate::init(const QString &directory, const QString &nameFilte
                               const QString &caption)
 {
     Q_Q(QFileDialog);
-    platformHelper = QGuiApplicationPrivate::platformIntegration()->createPlatformDialogHelper(q);
-    if (platformHelper)
-        platformHelper->d_ptr = this;
-
     if (!caption.isEmpty()) {
         useDefaultCaption = false;
         setWindowTitle = caption;
@@ -2273,8 +2268,8 @@ void QFileDialogPrivate::createWidgets()
     Q_Q(QFileDialog);
     model = new QFileSystemModel(q);
     model->setObjectName(QLatin1String("qt_filesystem_model"));
-    if (platformHelper)
-        model->setNameFilterDisables(platformHelper->defaultNameFilterDisables());
+    if (QPlatformDialogHelper *helper = platformHelper())
+        model->setNameFilterDisables(helper->defaultNameFilterDisables());
     else
         model->setNameFilterDisables(false);
     model->d_func()->disableRecursiveSort = true;
@@ -3130,8 +3125,8 @@ void QFileDialogPrivate::_q_fileRenamed(const QString &path, const QString oldNa
 
 void QFileDialogPrivate::_q_platformRunNativeAppModalPanel()
 {
-    if (platformHelper)
-        platformHelper->_q_platformRunNativeAppModalPanel();
+    if (nativeDialogInUse)
+        platformHelper()->_q_platformRunNativeAppModalPanel();
 }
 
 /*!
index 4de970d..fe14836 100644 (file)
@@ -260,8 +260,6 @@ public:
     bool fileNameLabelExplicitlySat;
     QStringList nameFilters;
 
-    // Members for using native dialogs:
-    bool nativeDialogInUse;
     // setVisible_sys returns true if it ends up showing a native
     // dialog. Returning false means that a non-native dialog must be
     // used instead.
@@ -370,84 +368,84 @@ inline QString QFileDialogPrivate::rootPath() const {
 // Dummies for platforms that don't use native dialogs:
 inline void QFileDialogPrivate::deleteNativeDialog_sys()
 {
-    if (platformHelper)
-        platformHelper->deleteNativeDialog_sys();
+    if (QPlatformDialogHelper *helper = platformHelper())
+        helper->deleteNativeDialog_sys();
     else
         qt_guiPlatformPlugin()->fileDialogDelete(q_func());
 }
 
 inline bool QFileDialogPrivate::setVisible_sys(bool visible)
 {
-    if (platformHelper)
-        return platformHelper->setVisible_sys(visible);
+    if (QPlatformDialogHelper *helper = platformHelper())
+        return helper->setVisible_sys(visible);
     return qt_guiPlatformPlugin()->fileDialogSetVisible(q_func(), visible);
 }
 
 inline QDialog::DialogCode QFileDialogPrivate::dialogResultCode_sys()
 {
-    if (platformHelper)
-        return platformHelper->dialogResultCode_sys();
+    if (QPlatformDialogHelper *helper = platformHelper())
+        return helper->dialogResultCode_sys();
     return qt_guiPlatformPlugin()->fileDialogResultCode(q_func());
 }
 
 inline void QFileDialogPrivate::setDirectory_sys(const QString &directory)
 {
-    if (platformHelper)
-        platformHelper->setDirectory_sys(directory);
+    if (QPlatformDialogHelper *helper = platformHelper())
+        helper->setDirectory_sys(directory);
     else
         qt_guiPlatformPlugin()->fileDialogSetDirectory(q_func(), directory);
 }
 
 inline QString QFileDialogPrivate::directory_sys() const
 {
-    if (platformHelper)
-        return platformHelper->directory_sys();
+    if (QPlatformDialogHelper *helper = platformHelper())
+        return helper->directory_sys();
     return qt_guiPlatformPlugin()->fileDialogDirectory(q_func());
 }
 
 inline void QFileDialogPrivate::selectFile_sys(const QString &filename)
 {
-    if (platformHelper)
-        platformHelper->selectFile_sys(filename);
+    if (QPlatformDialogHelper *helper = platformHelper())
+        helper->selectFile_sys(filename);
     else
         qt_guiPlatformPlugin()->fileDialogSelectFile(q_func(), filename);
 }
 
 inline QStringList QFileDialogPrivate::selectedFiles_sys() const
 {
-    if (platformHelper)
-        return platformHelper->selectedFiles_sys();
+    if (QPlatformDialogHelper *helper = platformHelper())
+        return helper->selectedFiles_sys();
     return qt_guiPlatformPlugin()->fileDialogSelectedFiles(q_func());
 }
 
 inline void QFileDialogPrivate::setFilter_sys()
 {
-    if (platformHelper)
-        platformHelper->setFilter_sys();
+    if (QPlatformDialogHelper *helper = platformHelper())
+        helper->setFilter_sys();
     else
         qt_guiPlatformPlugin()->fileDialogSetFilter(q_func());
 }
 
 inline void QFileDialogPrivate::setNameFilters_sys(const QStringList &filters)
 {
-    if (platformHelper)
-        platformHelper->setNameFilters_sys(filters);
+    if (QPlatformDialogHelper *helper = platformHelper())
+        helper->setNameFilters_sys(filters);
     else
         qt_guiPlatformPlugin()->fileDialogSetNameFilters(q_func(), filters);
 }
 
 inline void QFileDialogPrivate::selectNameFilter_sys(const QString &filter)
 {
-    if (platformHelper)
-        platformHelper->selectNameFilter_sys(filter);
+    if (QPlatformDialogHelper *helper = platformHelper())
+        helper->selectNameFilter_sys(filter);
     else
         qt_guiPlatformPlugin()->fileDialogSelectNameFilter(q_func(), filter);
 }
 
 inline QString QFileDialogPrivate::selectedNameFilter_sys() const
 {
-    if (platformHelper)
-        return platformHelper->selectedNameFilter_sys();
+    if (QPlatformDialogHelper *helper = platformHelper())
+        return helper->selectedNameFilter_sys();
     return qt_guiPlatformPlugin()->fileDialogSelectedNameFilter(q_func());
 }