diff options
Diffstat (limited to 'src/plugins/platforms/windows/qwindowsdialoghelpers.cpp')
-rw-r--r-- | src/plugins/platforms/windows/qwindowsdialoghelpers.cpp | 185 |
1 files changed, 100 insertions, 85 deletions
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index ce8fa08cb3..82fbd8c712 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -58,6 +58,7 @@ #include <QtCore/QTimer> #include <QtCore/QDir> #include <QtCore/QScopedArrayPointer> +#include <QtCore/QSharedPointer> #include <QtCore/QObject> #include <QtCore/QThread> #include <QtCore/private/qsystemlibrary_p.h> @@ -353,17 +354,6 @@ Type dialogType(const QDialog *dialog) } // namespace QWindowsDialogs -// Find the owner which to use as a parent of a native dialog. -static inline HWND ownerWindow(const QDialog *dialog) -{ - if (QWidget *parent = dialog->nativeParentWidget()) - if (QWindow *windowHandle = parent->windowHandle()) - return QWindowsWindow::handleOf(windowHandle); - if (QWindow *fw = QGuiApplication::focusWindow()) - return QWindowsWindow::handleOf(fw); - return 0; -} - /*! \class QWindowsNativeDialogBase \brief Base class for Windows native dialogs. @@ -395,7 +385,7 @@ class QWindowsNativeDialogBase : public QObject public: virtual void setWindowTitle(const QString &title) = 0; virtual void exec(HWND owner = 0) = 0; - virtual QDialog::DialogCode result() const = 0; + virtual QPlatformDialogHelper::DialogCode result() const = 0; signals: void accepted(); @@ -425,13 +415,16 @@ protected: \ingroup qt-lighthouse-win */ -QWindowsDialogHelperBase::QWindowsDialogHelperBase(QDialog *dialog) : +template <class BaseClass> +QWindowsDialogHelperBase<BaseClass>::QWindowsDialogHelperBase(QDialog *dialog) : m_dialog(dialog), - m_nativeDialog(0) + m_nativeDialog(0), + m_ownerWindow(0) { } -QWindowsNativeDialogBase *QWindowsDialogHelperBase::nativeDialog() const +template <class BaseClass> +QWindowsNativeDialogBase *QWindowsDialogHelperBase<BaseClass>::nativeDialog() const { if (!m_nativeDialog) { qWarning("%s invoked with no native dialog present.", __FUNCTION__); @@ -440,7 +433,8 @@ QWindowsNativeDialogBase *QWindowsDialogHelperBase::nativeDialog() const return m_nativeDialog; } -QWindowsNativeDialogBase *QWindowsDialogHelperBase::ensureNativeDialog() +template <class BaseClass> +QWindowsNativeDialogBase *QWindowsDialogHelperBase<BaseClass>::ensureNativeDialog() { // Create dialog and apply common settings. if (!m_nativeDialog) { @@ -451,7 +445,8 @@ QWindowsNativeDialogBase *QWindowsDialogHelperBase::ensureNativeDialog() return m_nativeDialog; } -void QWindowsDialogHelperBase::deleteNativeDialog_sys() +template <class BaseClass> +void QWindowsDialogHelperBase<BaseClass>::deleteNativeDialog_sys() { if (QWindowsContext::verboseDialogs) qDebug("%s" , __FUNCTION__); @@ -491,29 +486,39 @@ void QWindowsDialogThread::run() qDebug("<%s" , __FUNCTION__); } -bool QWindowsDialogHelperBase::setVisible_sys(bool visible) +template <class BaseClass> +bool QWindowsDialogHelperBase<BaseClass>::show_sys(QWindow *parent) { - const bool nonNative = nonNativeDialog(); const bool modal = m_dialog->isModal(); + if (parent) { + m_ownerWindow = QWindowsWindow::handleOf(parent); + } else { + m_ownerWindow = 0; + } if (QWindowsContext::verboseDialogs) - qDebug("%s visible=%d, native=%d, modal=%d native=%p" , - __FUNCTION__, visible, !nonNative, modal, m_nativeDialog); - if (nonNative || (!visible && !m_nativeDialog) || (!modal && !supportsNonModalDialog())) + qDebug("%s modal=%d native=%p parent=%p" , + __FUNCTION__, modal, m_nativeDialog, m_ownerWindow); + if (!modal && !supportsNonModalDialog()) return false; // Was it changed in-between? if (!ensureNativeDialog()) return false; - if (visible) { - if (!modal) { // Modal dialogs are shown in separate slot. - QWindowsDialogThread *thread = new QWindowsDialogThread(m_nativeDialog, ownerWindow(m_dialog)); - thread->start(); - } - } else { - m_nativeDialog->close(); + if (!modal) { // Modal dialogs are shown in separate slot. + QWindowsDialogThread *thread = new QWindowsDialogThread(m_nativeDialog, m_ownerWindow); + thread->start(); } return true; } -void QWindowsDialogHelperBase::platformNativeDialogModalHelp() +template <class BaseClass> +void QWindowsDialogHelperBase<BaseClass>::hide_sys() +{ + if (m_nativeDialog) + m_nativeDialog->close(); + m_ownerWindow = 0; +} + +template <class BaseClass> +void QWindowsDialogHelperBase<BaseClass>::platformNativeDialogModalHelp() { if (QWindowsContext::verboseDialogs) qDebug("%s" , __FUNCTION__); @@ -522,17 +527,37 @@ void QWindowsDialogHelperBase::platformNativeDialogModalHelp() Qt::QueuedConnection); } -void QWindowsDialogHelperBase::_q_platformRunNativeAppModalPanel() +template <class BaseClass> +void QWindowsDialogHelperBase<BaseClass>::_q_platformRunNativeAppModalPanel() { if (QWindowsNativeDialogBase *nd =nativeDialog()) - nd->exec(ownerWindow(m_dialog)); + nd->exec(m_ownerWindow); } -QDialog::DialogCode QWindowsDialogHelperBase::dialogResultCode_sys() +template <class BaseClass> +QPlatformDialogHelper::DialogCode QWindowsDialogHelperBase<BaseClass>::dialogResultCode_sys() { if (QWindowsNativeDialogBase *nd =nativeDialog()) return nd->result(); - return QDialog::Rejected; + return QPlatformDialogHelper::Rejected; +} + +static inline bool snapToDefaultButtonHint() +{ + BOOL snapToDefault = false; + if (SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, &snapToDefault, 0)) + return snapToDefault; + return false; +} + +template <class BaseClass> +QVariant QWindowsDialogHelperBase<BaseClass>::styleHint(QPlatformDialogHelper::StyleHint hint) const +{ + switch (hint) { + case QPlatformDialogHelper::SnapToDefaultButton: + return QVariant(snapToDefaultButtonHint()); + } + return BaseClass::styleHint(hint); } /*! @@ -638,9 +663,9 @@ public: bool hideFiltersDetails() const { return m_hideFiltersDetails; } void setHideFiltersDetails(bool h) { m_hideFiltersDetails = h; } - virtual QDialog::DialogCode result() const + virtual QPlatformDialogHelper::DialogCode result() const { return fileResult(); } - virtual QDialog::DialogCode fileResult(QStringList *fileResult = 0) const = 0; + virtual QPlatformDialogHelper::DialogCode fileResult(QStringList *fileResult = 0) const = 0; virtual QStringList selectedFiles() const = 0; inline void onFolderChange(IShellItem *); @@ -953,21 +978,21 @@ HRESULT QWindowsNativeFileDialogEventHandler::OnTypeChange(IFileDialog *) class QWindowsNativeSaveFileDialog : public QWindowsNativeFileDialogBase { public: - virtual QDialog::DialogCode fileResult(QStringList *fileResult = 0) const; + virtual QPlatformDialogHelper::DialogCode fileResult(QStringList *fileResult = 0) const; virtual QStringList selectedFiles() const; }; -QDialog::DialogCode QWindowsNativeSaveFileDialog::fileResult(QStringList *result /* = 0 */) const +QPlatformDialogHelper::DialogCode QWindowsNativeSaveFileDialog::fileResult(QStringList *result /* = 0 */) const { if (result) result->clear(); IShellItem *item = 0; const HRESULT hr = fileDialog()->GetResult(&item); if (FAILED(hr) || !item) - return QDialog::Rejected; + return QPlatformDialogHelper::Rejected; if (result) result->push_back(QWindowsNativeFileDialogBase::itemPath(item)); - return QDialog::Accepted; + return QPlatformDialogHelper::Accepted; } QStringList QWindowsNativeSaveFileDialog::selectedFiles() const @@ -992,7 +1017,7 @@ QStringList QWindowsNativeSaveFileDialog::selectedFiles() const class QWindowsNativeOpenFileDialog : public QWindowsNativeFileDialogBase { public: - virtual QDialog::DialogCode fileResult(QStringList *fileResult = 0) const; + virtual QPlatformDialogHelper::DialogCode fileResult(QStringList *fileResult = 0) const; virtual QStringList selectedFiles() const; private: @@ -1000,15 +1025,15 @@ private: { return static_cast<IFileOpenDialog *>(fileDialog()); } }; -QDialog::DialogCode QWindowsNativeOpenFileDialog::fileResult(QStringList *result /* = 0 */) const +QPlatformDialogHelper::DialogCode QWindowsNativeOpenFileDialog::fileResult(QStringList *result /* = 0 */) const { if (result) result->clear(); IShellItemArray *items = 0; const HRESULT hr = openFileDialog()->GetResults(&items); if (SUCCEEDED(hr) && items && QWindowsNativeFileDialogBase::itemPaths(items, result) > 0) - return QDialog::Accepted; - return QDialog::Rejected; + return QPlatformDialogHelper::Accepted; + return QPlatformDialogHelper::Rejected; } QStringList QWindowsNativeOpenFileDialog::selectedFiles() const @@ -1053,7 +1078,7 @@ QWindowsNativeFileDialogBase *QWindowsNativeFileDialogBase::create(QFileDialog:: \ingroup qt-lighthouse-win */ -class QWindowsFileDialogHelper : public QWindowsDialogHelperBase +class QWindowsFileDialogHelper : public QWindowsDialogHelperBase<QPlatformFileDialogHelper> { public: explicit QWindowsFileDialogHelper(QDialog *dialog) : @@ -1061,9 +1086,6 @@ public: m_fileDialog(qobject_cast<QFileDialog *>(dialog)) { Q_ASSERT(m_fileDialog); } - virtual bool nonNativeDialog() const - { return m_fileDialog->testOption(QFileDialog::DontUseNativeDialog); } - virtual bool defaultNameFilterDisables() const { return true; } virtual void setDirectory_sys(const QString &directory); @@ -1093,13 +1115,13 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog() QObject::connect(result, SIGNAL(rejected()), m_fileDialog, SLOT(reject()), Qt::QueuedConnection); QObject::connect(result, SIGNAL(directoryEntered(QString)), - m_fileDialog, SIGNAL(directoryEntered(QString)), + this, SIGNAL(directoryEntered(QString)), Qt::QueuedConnection); QObject::connect(result, SIGNAL(currentChanged(QString)), - m_fileDialog, SIGNAL(currentChanged(QString)), + this, SIGNAL(currentChanged(QString)), Qt::QueuedConnection); QObject::connect(result, SIGNAL(filterSelected(QString)), - m_fileDialog, SIGNAL(filterSelected(QString)), + this, SIGNAL(filterSelected(QString)), Qt::QueuedConnection); // Apply settings. @@ -1190,27 +1212,29 @@ QString QWindowsFileDialogHelper::selectedNameFilter_sys() const \ingroup qt-lighthouse-win */ +typedef QSharedPointer<QColor> SharedPointerColor; + class QWindowsNativeColorDialog : public QWindowsNativeDialogBase { Q_OBJECT public: - explicit QWindowsNativeColorDialog(QColorDialog *dialog); + explicit QWindowsNativeColorDialog(const SharedPointerColor &color); virtual void setWindowTitle(const QString &) {} virtual void exec(HWND owner = 0); - virtual QDialog::DialogCode result() const { return m_code; } + virtual QPlatformDialogHelper::DialogCode result() const { return m_code; } public slots: virtual void close() {} private: COLORREF m_customColors[16]; - QDialog::DialogCode m_code; - QColorDialog *m_dialog; + QPlatformDialogHelper::DialogCode m_code; + SharedPointerColor m_color; }; -QWindowsNativeColorDialog::QWindowsNativeColorDialog(QColorDialog *dialog) : - m_code(QDialog::Rejected), m_dialog(dialog) +QWindowsNativeColorDialog::QWindowsNativeColorDialog(const SharedPointerColor &color) : + m_code(QPlatformDialogHelper::Rejected), m_color(color) { qFill(m_customColors, m_customColors + 16, COLORREF(0)); } @@ -1232,7 +1256,7 @@ void QWindowsNativeColorDialog::exec(HWND owner) chooseColor.lStructSize = sizeof(chooseColor); chooseColor.hwndOwner = owner; chooseColor.lpCustColors = m_customColors; - chooseColor.rgbResult = qColorToCOLORREF(m_dialog->currentColor()); + chooseColor.rgbResult = qColorToCOLORREF(*m_color); chooseColor.Flags = CC_FULLOPEN | CC_RGBINIT; static ChooseColorWType chooseColorW = 0; if (!chooseColorW) { @@ -1240,16 +1264,17 @@ void QWindowsNativeColorDialog::exec(HWND owner) chooseColorW = (ChooseColorWType)library.resolve("ChooseColorW"); } if (chooseColorW) { - m_code = chooseColorW(&chooseColor) ? QDialog::Accepted :QDialog::Rejected; + m_code = chooseColorW(&chooseColor) ? + QPlatformDialogHelper::Accepted : QPlatformDialogHelper::Rejected; QWindowsDialogs::eatMouseMove(); } else { - m_code = QDialog::Rejected; + m_code = QPlatformDialogHelper::Rejected; } - if (m_code == QDialog::Accepted) { - m_dialog->setCurrentColor(COLORREFToQColor(chooseColor.rgbResult)); + if (m_code == QPlatformDialogHelper::Accepted) { + *m_color = COLORREFToQColor(chooseColor.rgbResult); emit accepted(); if (QWindowsContext::verboseDialogs) - qDebug() << '<' << __FUNCTION__ << m_dialog->currentColor(); + qDebug() << '<' << __FUNCTION__ << m_color; } else { emit rejected(); } @@ -1267,41 +1292,30 @@ void QWindowsNativeColorDialog::exec(HWND owner) \ingroup qt-lighthouse-win */ -class QWindowsColorDialogHelper : public QWindowsDialogHelperBase +class QWindowsColorDialogHelper : public QWindowsDialogHelperBase<QPlatformColorDialogHelper> { public: - explicit QWindowsColorDialogHelper(QDialog *dialog) : - QWindowsDialogHelperBase(dialog), - m_colorDialog(qobject_cast<QColorDialog *>(dialog)) - { Q_ASSERT(m_colorDialog); } + QWindowsColorDialogHelper(QDialog *dialog) : + QWindowsDialogHelperBase(dialog), m_currentColor(new QColor) { } - virtual bool nonNativeDialog() const - { return m_colorDialog->testOption(QColorDialog::DontUseNativeDialog); } virtual bool supportsNonModalDialog() { return false; } - // ### fixme: Remove once a dialog helper hierarchy is in place - virtual bool defaultNameFilterDisables() const { return true; } - virtual void setDirectory_sys(const QString &) {} - virtual QString directory_sys() const { return QString(); } - virtual void selectFile_sys(const QString &) {} - virtual QStringList selectedFiles_sys() const { return QStringList(); } - virtual void setFilter_sys() {} - virtual void setNameFilters_sys(const QStringList &) {} - virtual void selectNameFilter_sys(const QString &) {} - virtual QString selectedNameFilter_sys() const { return QString(); } + virtual QColor currentColor_sys() const { return *m_currentColor; } + virtual void setCurrentColor_sys(const QColor &c) { *m_currentColor = c; } private: inline QWindowsNativeColorDialog *nativeFileDialog() const { return static_cast<QWindowsNativeColorDialog *>(nativeDialog()); } virtual QWindowsNativeDialogBase *createNativeDialog() - { return new QWindowsNativeColorDialog(m_colorDialog); } - QColorDialog *m_colorDialog; + { return new QWindowsNativeColorDialog(m_currentColor); } + SharedPointerColor m_currentColor; }; -// QWindowsDialogHelperBase creation functions +namespace QWindowsDialogs { -bool QWindowsDialogHelperBase::useHelper(const QDialog *dialog) +// QWindowsDialogHelperBase creation functions +bool useHelper(const QDialog *dialog) { switch (QWindowsDialogs::dialogType(dialog)) { case QWindowsDialogs::FileDialog: @@ -1317,7 +1331,7 @@ bool QWindowsDialogHelperBase::useHelper(const QDialog *dialog) return false; } -QPlatformDialogHelper *QWindowsDialogHelperBase::create(QDialog *dialog) +QPlatformDialogHelper *createHelper(QDialog *dialog) { if (QWindowsContext::verboseDialogs) qDebug("%s %p %s" , __FUNCTION__, dialog, dialog->metaObject()->className()); @@ -1336,6 +1350,7 @@ QPlatformDialogHelper *QWindowsDialogHelperBase::create(QDialog *dialog) return 0; } +} // namespace QWindowsDialogs QT_END_NAMESPACE #include "qwindowsdialoghelpers.moc" |