QPA: Cleanup native dialog modal execution

Remove the _q_platformRunNativeAppModalPanel() function, together with
the launchNativeAppModalPanel() signal and
emitLaunchNativeAppModalPanel() slot, which were previously used to run
the modal loop inside the QDialog::exec() loop. This trick isn't
necessary anymore, so remove the mechanism and code related to it.

Rename QPlatformDialogHelper::platformNativeDialogModalHelp() to
exec_sys(). This function is now responsible for both showing the native
dialog and running the modal loop. QDialog:exec() now calls this
function if a native dialog is in use (it does not call
QEventLoop::exec() anymore).

The dialogResultCode_sys() function was unused, so it has also been
removed.

This commit also removes some unused private slots that were left over
from the port to QPA.

Note that the comments in the Cocoa plugin are still valid and relevant,
but this commit does not fix the scenarios mentioned. This will be done
in a future commit.

The Windows plugin needs minor changes. The QueuedConnections to
accept() and reject() cause the deliver to come too late, resulting in
crashes, hence the change to AutoConnection (which ends up being a
DirectConnection).

Change-Id: Ifc90325c945ca78737e60bf331929f03ecc52e0a
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>
This commit is contained in:
Bradley T. Hughes 2012-04-30 14:26:47 +02:00 committed by Qt by Nokia
parent 9f2f7a8f72
commit ab947649eb
17 changed files with 40 additions and 167 deletions

View File

@ -90,26 +90,20 @@ public:
virtual QVariant styleHint(StyleHint hint) const;
virtual void platformNativeDialogModalHelp() = 0;
virtual void _q_platformRunNativeAppModalPanel() = 0;
virtual void exec_sys() = 0;
virtual void deleteNativeDialog_sys() = 0;
virtual bool show_sys(Qt::WindowFlags windowFlags,
Qt::WindowModality windowModality,
QWindow *parent) = 0;
virtual void hide_sys() = 0;
virtual DialogCode dialogResultCode_sys() = 0;
static QVariant defaultStyleHint(QPlatformDialogHelper::StyleHint hint);
Q_SIGNALS:
void launchNativeAppModalPanel();
void accept();
void reject();
protected Q_SLOTS:
void emitLaunchNativeAppModalPanel();
};
class Q_GUI_EXPORT QColorDialogOptions

View File

@ -94,11 +94,6 @@ QVariant QPlatformDialogHelper::defaultStyleHint(QPlatformDialogHelper::StyleHi
return QVariant();
}
void QPlatformDialogHelper::emitLaunchNativeAppModalPanel()
{
emit launchNativeAppModalPanel();
}
// Font dialog
class QFontDialogOptionsPrivate : public QSharedData

View File

@ -53,13 +53,11 @@ public:
QCocoaColorDialogHelper();
virtual ~QCocoaColorDialogHelper();
void platformNativeDialogModalHelp();
void _q_platformRunNativeAppModalPanel();
void exec_sys();
void deleteNativeDialog_sys();
bool show_sys(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
void hide_sys();
DialogCode dialogResultCode_sys();
void setCurrentColor_sys(const QColor&);
QColor currentColor_sys() const;

View File

@ -345,27 +345,14 @@ QCocoaColorDialogHelper::QCocoaColorDialogHelper() :
QCocoaColorDialogHelper::~QCocoaColorDialogHelper()
{ }
void QCocoaColorDialogHelper::platformNativeDialogModalHelp()
void QCocoaColorDialogHelper::exec_sys()
{
// Do a queued meta-call to open the native modal dialog so it opens after the new
// event loop has started to execute (in QDialog::exec). Using a timer rather than
// a queued meta call is intentional to ensure that the call is only delivered when
// [NSApp run] runs (timers are handeled special in cocoa). If NSApp is not
// running (which is the case if e.g a top-most QEventLoop has been
// interrupted, and the second-most event loop has not yet been reactivated (regardless
// if [NSApp run] is still on the stack)), showing a native modal dialog will fail.
QTimer::singleShot(1, this, SIGNAL(launchNativeAppModalPanel()));
}
void QCocoaColorDialogHelper::_q_platformRunNativeAppModalPanel()
{
// TODO:
#if 0
QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active);
#endif
// Note: If NSApp is not running (which is the case if e.g a top-most
// QEventLoop has been interrupted, and the second-most event loop has not
// yet been reactivated (regardless if [NSApp run] is still on the stack)),
// showing a native modal dialog will fail.
QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *>(mDelegate);
[delegate runApplicationModalPanel];
if (dialogResultCode_sys() == QPlatformDialogHelper::Accepted)
if ([delegate runApplicationModalPanel])
emit accept();
else
emit reject();
@ -395,14 +382,6 @@ void QCocoaColorDialogHelper::hide_sys()
[reinterpret_cast<QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *>(mDelegate)->mColorPanel close];
}
QCocoaColorDialogHelper::DialogCode QCocoaColorDialogHelper::dialogResultCode_sys()
{
if (!mDelegate)
return QPlatformDialogHelper::Rejected;
QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSColorPanelDelegate) *>(mDelegate);
return [delegate dialogResultCode];
}
void QCocoaColorDialogHelper::setCurrentColor_sys(const QColor &color)
{
if (!mDelegate)

View File

@ -56,15 +56,13 @@ public:
QCocoaFileDialogHelper();
virtual ~QCocoaFileDialogHelper();
void platformNativeDialogModalHelp();
void _q_platformRunNativeAppModalPanel();
void exec_sys();
bool defaultNameFilterDisables() const;
void deleteNativeDialog_sys();
bool show_sys(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
void hide_sys();
QPlatformFileDialogHelper::DialogCode dialogResultCode_sys();
void setDirectory_sys(const QString &directory);
QString directory_sys() const;
void selectFile_sys(const QString &filename);

View File

@ -672,36 +672,18 @@ bool QCocoaFileDialogHelper::hideCocoaFilePanel()
}
}
void QCocoaFileDialogHelper::platformNativeDialogModalHelp()
void QCocoaFileDialogHelper::exec_sys()
{
// Do a queued meta-call to open the native modal dialog so it opens after the new
// event loop has started to execute (in QDialog::exec). Using a timer rather than
// a queued meta call is intentional to ensure that the call is only delivered when
// [NSApp run] runs (timers are handeled special in cocoa). If NSApp is not
// running (which is the case if e.g a top-most QEventLoop has been
// interrupted, and the second-most event loop has not yet been reactivated (regardless
// if [NSApp run] is still on the stack)), showing a native modal dialog will fail.
QTimer::singleShot(1, this, SIGNAL(launchNativeAppModalPanel()));
}
void QCocoaFileDialogHelper::_q_platformRunNativeAppModalPanel()
{
// TODO:
#if 0
QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active);
#endif
// Note: If NSApp is not running (which is the case if e.g a top-most
// QEventLoop has been interrupted, and the second-most event loop has not
// yet been reactivated (regardless if [NSApp run] is still on the stack)),
// showing a native modal dialog will fail.
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
[delegate runApplicationModalPanel];
if (dialogResultCode_sys() == QPlatformDialogHelper::Accepted)
if ([delegate runApplicationModalPanel])
emit accept();
else
emit reject();
}
QPlatformDialogHelper::DialogCode QCocoaFileDialogHelper::dialogResultCode_sys()
{
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
return [delegate dialogResultCode];
}
bool QCocoaFileDialogHelper::defaultNameFilterDisables() const

View File

@ -56,15 +56,13 @@ public:
QCocoaFontDialogHelper();
virtual ~QCocoaFontDialogHelper();
void platformNativeDialogModalHelp();
void _q_platformRunNativeAppModalPanel();
void exec_sys();
void deleteNativeDialog_sys();
bool show_sys(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent);
void hide_sys();
QPlatformDialogHelper::DialogCode dialogResultCode_sys();
void setCurrentFont_sys(const QFont &);
QFont currentFont_sys() const;

View File

@ -364,27 +364,14 @@ QCocoaFontDialogHelper::QCocoaFontDialogHelper() :
QCocoaFontDialogHelper::~QCocoaFontDialogHelper()
{ }
void QCocoaFontDialogHelper::platformNativeDialogModalHelp()
void QCocoaFontDialogHelper::exec_sys()
{
// Do a queued meta-call to open the native modal dialog so it opens after the new
// event loop has started to execute (in QDialog::exec). Using a timer rather than
// a queued meta call is intentional to ensure that the call is only delivered when
// [NSApp run] runs (timers are handeled special in cocoa). If NSApp is not
// running (which is the case if e.g a top-most QEventLoop has been
// interrupted, and the second-most event loop has not yet been reactivated (regardless
// if [NSApp run] is still on the stack)), showing a native modal dialog will fail.
QTimer::singleShot(1, this, SIGNAL(launchNativeAppModalPanel()));
}
void QCocoaFontDialogHelper::_q_platformRunNativeAppModalPanel()
{
// TODO:
#if 0
QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active);
#endif
// Note: If NSApp is not running (which is the case if e.g a top-most
// QEventLoop has been interrupted, and the second-most event loop has not
// yet been reactivated (regardless if [NSApp run] is still on the stack)),
// showing a native modal dialog will fail.
QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate);
[delegate runApplicationModalPanel];
if (dialogResultCode_sys() == QPlatformDialogHelper::Accepted)
if ([delegate runApplicationModalPanel])
emit accept();
else
emit reject();
@ -414,14 +401,6 @@ void QCocoaFontDialogHelper::hide_sys()
[reinterpret_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate)->mFontPanel close];
}
QCocoaFontDialogHelper::DialogCode QCocoaFontDialogHelper::dialogResultCode_sys()
{
if (!mDelegate)
return QPlatformDialogHelper::Rejected;
QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSFontPanelDelegate) *>(mDelegate);
return [delegate dialogResultCode];
}
void QCocoaFontDialogHelper::setCurrentFont_sys(const QFont &font)
{
NSFontManager *mgr = [NSFontManager sharedFontManager];

View File

@ -519,29 +519,12 @@ void QWindowsDialogHelperBase<BaseClass>::hide_sys()
}
template <class BaseClass>
void QWindowsDialogHelperBase<BaseClass>::platformNativeDialogModalHelp()
void QWindowsDialogHelperBase<BaseClass>::exec_sys()
{
if (QWindowsContext::verboseDialogs)
qDebug("%s" , __FUNCTION__);
if (QWindowsNativeDialogBase *nd =nativeDialog())
nd->metaObject()->invokeMethod(this,
"emitLaunchNativeAppModalPanel",
Qt::QueuedConnection);
}
template <class BaseClass>
void QWindowsDialogHelperBase<BaseClass>::_q_platformRunNativeAppModalPanel()
{
if (QWindowsNativeDialogBase *nd =nativeDialog())
nd->exec(m_ownerWindow);
}
template <class BaseClass>
QPlatformDialogHelper::DialogCode QWindowsDialogHelperBase<BaseClass>::dialogResultCode_sys()
{
if (QWindowsNativeDialogBase *nd =nativeDialog())
return nd->result();
return QPlatformDialogHelper::Rejected;
if (QWindowsNativeDialogBase *nd = nativeDialog())
nd->exec(m_ownerWindow);
}
static inline bool snapToDefaultButtonHint()
@ -1135,19 +1118,14 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog()
QWindowsNativeFileDialogBase *result = QWindowsNativeFileDialogBase::create(options()->acceptMode());
if (!result)
return 0;
QObject::connect(result, SIGNAL(accepted()), this, SIGNAL(accept()),
Qt::QueuedConnection);
QObject::connect(result, SIGNAL(rejected()), this, SIGNAL(reject()),
Qt::QueuedConnection);
QObject::connect(result, SIGNAL(accepted()), this, SIGNAL(accept()));
QObject::connect(result, SIGNAL(rejected()), this, SIGNAL(reject()));
QObject::connect(result, SIGNAL(directoryEntered(QString)),
this, SIGNAL(directoryEntered(QString)),
Qt::QueuedConnection);
this, SIGNAL(directoryEntered(QString)));
QObject::connect(result, SIGNAL(currentChanged(QString)),
this, SIGNAL(currentChanged(QString)),
Qt::QueuedConnection);
this, SIGNAL(currentChanged(QString)));
QObject::connect(result, SIGNAL(filterSelected(QString)),
this, SIGNAL(filterSelected(QString)),
Qt::QueuedConnection);
this, SIGNAL(filterSelected(QString)));
// Apply settings.
const QSharedPointer<QFileDialogOptions> &opts = options();

View File

@ -66,8 +66,7 @@ class QWindowsDialogHelperBase : public BaseClass
{
public:
virtual void platformNativeDialogModalHelp();
virtual void _q_platformRunNativeAppModalPanel();
virtual void exec_sys();
virtual void deleteNativeDialog_sys();
virtual bool show_sys(Qt::WindowFlags windowFlags,
Qt::WindowModality windowModality,
@ -75,8 +74,6 @@ public:
virtual void hide_sys();
virtual QVariant styleHint(QPlatformDialogHelper::StyleHint) const;
virtual QPlatformDialogHelper::DialogCode dialogResultCode_sys();
virtual bool supportsNonModalDialog() const { return true; }
protected:

View File

@ -124,7 +124,6 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_newColorTypedIn(QRgb rgb))
Q_PRIVATE_SLOT(d_func(), void _q_newCustom(int, int))
Q_PRIVATE_SLOT(d_func(), void _q_newStandard(int, int))
Q_PRIVATE_SLOT(d_func(), void _q_platformRunNativeAppModalPanel())
friend class QColorShower;
};

View File

@ -88,8 +88,6 @@ QPlatformDialogHelper *QDialogPrivate::platformHelper() const
if (m_platformHelper) {
QObject::connect(m_platformHelper, SIGNAL(accept()), dialog, SLOT(accept()));
QObject::connect(m_platformHelper, SIGNAL(reject()), dialog, SLOT(reject()));
QObject::connect(m_platformHelper, SIGNAL(launchNativeAppModalPanel()),
dialog, SLOT(_q_platformRunNativeAppModalPanel()));
ncThis->initHelper(m_platformHelper);
}
}
@ -118,13 +116,6 @@ bool QDialogPrivate::setNativeDialogVisible(bool visible)
return nativeDialogInUse;
}
void QDialogPrivate::_q_platformRunNativeAppModalPanel()
{
if (nativeDialogInUse)
platformHelper()->_q_platformRunNativeAppModalPanel();
}
QVariant QDialogPrivate::styleHint(QPlatformDialogHelper::StyleHint hint) const
{
if (const QPlatformDialogHelper *helper = platformHelper())
@ -535,13 +526,14 @@ int QDialog::exec()
}
show();
if (d->nativeDialogInUse)
d->platformHelper()->platformNativeDialogModalHelp();
QEventLoop eventLoop;
d->eventLoop = &eventLoop;
QPointer<QDialog> guard = this;
(void) eventLoop.exec(QEventLoop::DialogExec);
if (d->nativeDialogInUse) {
d->platformHelper()->exec_sys();
} else {
QEventLoop eventLoop;
d->eventLoop = &eventLoop;
(void) eventLoop.exec(QEventLoop::DialogExec);
}
if (guard.isNull())
return QDialog::Rejected;
d->eventLoop = 0;

View File

@ -117,7 +117,6 @@ protected:
private:
Q_DECLARE_PRIVATE(QDialog)
Q_DISABLE_COPY(QDialog)
Q_PRIVATE_SLOT(d_func(), void _q_platformRunNativeAppModalPanel())
#ifdef Q_OS_WINCE_WM
Q_PRIVATE_SLOT(d_func(), void _q_doneAction())

View File

@ -79,7 +79,6 @@ public:
nativeDialogInUse(false), m_platformHelper(0), m_platformHelperCreated(false)
{}
~QDialogPrivate() { delete m_platformHelper; }
void _q_platformRunNativeAppModalPanel();
QWindow *parentWindow() const;
bool setNativeDialogVisible(bool visible);

View File

@ -252,7 +252,6 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex & parent))
Q_PRIVATE_SLOT(d_func(), void _q_fileRenamed(const QString &path,
const QString oldName, const QString newName))
Q_PRIVATE_SLOT(d_func(), void _q_platformRunNativeAppModalPanel())
friend class QPlatformDialogHelper;
};

View File

@ -244,7 +244,6 @@ public:
// dialog. Returning false means that a non-native dialog must be
// used instead.
bool canBeNativeDialog();
QDialog::DialogCode dialogResultCode_sys();
void setDirectory_sys(const QString &directory);
QString directory_sys() const;
@ -346,15 +345,6 @@ inline QString QFileDialogPrivate::rootPath() const {
return model->rootPath();
}
inline QDialog::DialogCode QFileDialogPrivate::dialogResultCode_sys()
{
QDialog::DialogCode result = QDialog::Rejected;
if (QPlatformDialogHelper *helper = platformHelper())
if (helper->dialogResultCode_sys() == QPlatformDialogHelper::Accepted)
result = QDialog::Accepted;
return result;
}
inline void QFileDialogPrivate::setDirectory_sys(const QString &directory)
{
if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())

View File

@ -118,9 +118,6 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_styleHighlighted(int))
Q_PRIVATE_SLOT(d_func(), void _q_sizeHighlighted(int))
Q_PRIVATE_SLOT(d_func(), void _q_updateSample())
#if defined(Q_WS_MAC)
Q_PRIVATE_SLOT(d_func(), void _q_macRunNativeAppModalPanel())
#endif
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QFontDialog::FontDialogOptions)