From af914694d81317b4a7bf0804d9d34a1f3bf2cf48 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 10 Nov 2011 13:07:01 +0100 Subject: QPlatformDialogHelper: Split class hierarchy, decouple from Dialog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Introduce hierarchy of QPlatformDialogHelper-derived classes for font, color and file dialogs. - Start reducing dependencies on QDialog: * Remove QDialog-specifics from interface, introduce enumeration for DialogCode * Make the helpers Q_OBJECTS to be able to add the signals passed on to the QDialogs * Remove QDialogPrivate pointer - Split setVisible_sys() in show_sys() (factory method for native dialogs) and hide_sys(). Pass parent window to show_sys(), removing the necessity to query the QDialog for it - Introduce a styleHint() similar to QGuiApplication's for platform-specific - Fix compile in cocoa/windows, reduce depency on QDialog (-private) classes. Change-Id: Ic1cb715e1edf767f2cb18b9780341d189339ef1d Reviewed-by: Morten Johan Sørvig --- .../platforms/cocoa/qcocoafiledialoghelper.h | 8 +- .../platforms/cocoa/qcocoafiledialoghelper.mm | 94 +++++------ .../platforms/windows/qwindowsdialoghelpers.cpp | 185 +++++++++++---------- .../platforms/windows/qwindowsdialoghelpers.h | 19 ++- .../platforms/windows/qwindowsintegration.cpp | 4 +- src/widgets/dialogs/qcolordialog.cpp | 17 +- src/widgets/dialogs/qcolordialog_p.h | 5 + src/widgets/dialogs/qdialog.cpp | 44 +++-- src/widgets/dialogs/qdialog_p.h | 6 + src/widgets/dialogs/qfiledialog.cpp | 6 +- src/widgets/dialogs/qfiledialog_p.h | 49 +++--- src/widgets/dialogs/qfontdialog.cpp | 14 +- src/widgets/dialogs/qfontdialog_p.h | 7 + src/widgets/kernel/qplatformdialoghelper_qpa.cpp | 43 ++++- src/widgets/kernel/qplatformdialoghelper_qpa.h | 64 ++++++- 15 files changed, 366 insertions(+), 199 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h index 06309ab62b..c38ea90f19 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h @@ -44,10 +44,11 @@ #include #include + class QFileDialog; class QFileDialogPrivate; -class QCocoaFileDialogHelper : public QPlatformDialogHelper +class QCocoaFileDialogHelper : public QPlatformFileDialogHelper { public: QCocoaFileDialogHelper(QFileDialog *dialog); @@ -59,8 +60,9 @@ public: bool defaultNameFilterDisables() const; void deleteNativeDialog_sys(); - bool setVisible_sys(bool visible); - QDialog::DialogCode dialogResultCode_sys(); + bool show_sys(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); diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index bdccf5dfa5..820a5dcbd0 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -89,7 +89,7 @@ QT_USE_NAMESPACE NSView *mAccessoryView; NSPopUpButton *mPopUpButton; NSTextField *mTextField; - QFileDialogPrivate *mPriv; + QFileDialog *mFileDialog; QCocoaFileDialogHelper *mHelper; NSString *mCurrentDir; bool mConfirmOverwrite; @@ -133,11 +133,11 @@ QT_USE_NAMESPACE fileMode:(QT_PREPEND_NAMESPACE(QFileDialog::FileMode))fileMode selectFile:(const QString &)selectFile confirmOverwrite:(bool)confirm - priv:(QFileDialogPrivate *)priv + fileDialog:(QFileDialog *)fileDialog helper:(QCocoaFileDialogHelper *)helper { self = [super init]; - + mFileDialog = fileDialog; mAcceptMode = acceptMode; if (mAcceptMode == QT_PREPEND_NAMESPACE(QFileDialog::AcceptOpen)){ mOpenPanel = [NSOpenPanel openPanel]; @@ -154,12 +154,11 @@ QT_USE_NAMESPACE mFileMode = fileMode; mConfirmOverwrite = confirm; mReturnCode = -1; - mPriv = priv; mHelper = helper; mLastFilterCheckPath = new QString; mQDirFilterEntryList = new QStringList; - mNameFilterDropDownList = new QStringList(priv->nameFilters); - QString selectedVisualNameFilter = priv->qFileDialogUi->fileTypeCombo->currentText(); + mNameFilterDropDownList = new QStringList(mFileDialog->nameFilters()); + QString selectedVisualNameFilter = mFileDialog->selectedNameFilter(); mSelectedNameFilter = new QStringList([self findStrippedFilterWithVisualFilterName:selectedVisualNameFilter]); QFileInfo sel(selectFile); @@ -177,11 +176,10 @@ QT_USE_NAMESPACE [self createAccessory]; [mSavePanel setAccessoryView:mNameFilterDropDownList->size() > 1 ? mAccessoryView : nil]; - if (mPriv){ - [mSavePanel setPrompt:[self strip:mPriv->acceptLabel]]; - if (mPriv->fileNameLabelExplicitlySat) - [mSavePanel setNameFieldLabel:[self strip:mPriv->qFileDialogUi->fileNameLabel->text()]]; - } + + [mSavePanel setPrompt:[self strip:mFileDialog->labelText(QFileDialog::Accept)]]; + if (false) // ### fixme mPriv->fileNameLabelExplicitlySat) + [mSavePanel setNameFieldLabel:[self strip:mFileDialog->labelText(QFileDialog::FileName)]]; [self updateProperties]; [mSavePanel retain]; @@ -254,9 +252,9 @@ QT_USE_NAMESPACE return (mReturnCode == NSOKButton); } -- (QT_PREPEND_NAMESPACE(QDialog::DialogCode))dialogResultCode +- (QT_PREPEND_NAMESPACE(QPlatformDialogHelper::DialogCode))dialogResultCode { - return (mReturnCode == NSOKButton) ? QT_PREPEND_NAMESPACE(QDialog::Accepted) : QT_PREPEND_NAMESPACE(QDialog::Rejected); + return (mReturnCode == NSOKButton) ? QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Accepted) : QT_PREPEND_NAMESPACE(QPlatformDialogHelper::Rejected); } - (void)showWindowModalSheet:(QWidget *)docWidget @@ -391,8 +389,9 @@ QT_USE_NAMESPACE [mOpenPanel setResolvesAliases:!(*mFileOptions & QT_PREPEND_NAMESPACE(QFileDialog::DontResolveSymlinks))]; QStringList ext = [self acceptableExtensionsForSave]; - if (mPriv && !ext.isEmpty() && !mPriv->defaultSuffix.isEmpty()) - ext.prepend(mPriv->defaultSuffix); + const QString defaultSuffix = mFileDialog->defaultSuffix(); + if (!ext.isEmpty() && !defaultSuffix.isEmpty()) + ext.prepend(defaultSuffix); [mSavePanel setAllowedFileTypes:ext.isEmpty() ? nil : QT_PREPEND_NAMESPACE(qt_mac_QStringListToNSMutableArray(ext))]; if ([mSavePanel isVisible]) @@ -474,10 +473,7 @@ QT_USE_NAMESPACE [mTextField setSelectable:false]; [mTextField setBordered:false]; [mTextField setDrawsBackground:false]; - if (mPriv){ - [mTextField setStringValue:[self strip:mPriv->qFileDialogUi->fileTypeLabel->text()]]; - } else - [mTextField setStringValue:QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(QT_PREPEND_NAMESPACE(QFileDialog::tr)("Files of type:"))]; + [mTextField setStringValue:[self strip:mFileDialog->labelText(QFileDialog::FileType)]]; } - (void)createPopUpButton:(const QString &)selectedFilter hideDetails:(BOOL)hideDetails @@ -555,15 +551,14 @@ void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_panelClosed(bool accepted) void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_directoryEntered(const QString &newDir) { - QFileDialogPrivate *priv = static_cast(d_ptr); - priv->setLastVisitedDirectory(newDir); - qtFileDialog->metaObject()->invokeMethod(qtFileDialog, "directoryEntered", Q_ARG(QString, newDir)); + // ### fixme: priv->setLastVisitedDirectory(newDir); + emit directoryEntered(newDir); } void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_filterSelected(int menuIndex) { - QFileDialogPrivate *priv = static_cast(d_ptr); - qtFileDialog->metaObject()->invokeMethod(qtFileDialog, "filterSelected", Q_ARG(QString, priv->nameFilters.at(menuIndex))); + const QStringList filters = qtFileDialog->nameFilters(); + emit filterSelected(menuIndex >= 0 && menuIndex < filters.size() ? filters.at(menuIndex) : QString()); } extern OSErr qt_mac_create_fsref(const QString &, FSRef *); // qglobal.cpp @@ -607,22 +602,20 @@ void QCocoaFileDialogHelper::setNameFilters_sys(const QStringList &filters) void QCocoaFileDialogHelper::setFilter_sys() { - QFileDialogPrivate *priv = static_cast(d_ptr); QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); - *(delegate->mQDirFilter) = priv->model->filter(); - delegate->mFileMode = priv->fileMode; + *(delegate->mQDirFilter) = qtFileDialog->filter(); + delegate->mFileMode = qtFileDialog->fileMode(); [delegate->mSavePanel setTitle:qt_mac_QStringToNSString(qtFileDialog->windowTitle())]; - [delegate->mSavePanel setPrompt:[delegate strip:priv->acceptLabel]]; - if (priv->fileNameLabelExplicitlySat) - [delegate->mSavePanel setNameFieldLabel:[delegate strip:priv->qFileDialogUi->fileNameLabel->text()]]; + [delegate->mSavePanel setPrompt:[delegate strip:qtFileDialog->labelText(QFileDialog::Accept)]]; + if (false) // ### fixme priv->fileNameLabelExplicitlySat) + [delegate->mSavePanel setNameFieldLabel:[delegate strip:qtFileDialog->labelText(QFileDialog::FileName)]]; [delegate updateProperties]; } void QCocoaFileDialogHelper::selectNameFilter_sys(const QString &filter) { - QFileDialogPrivate *priv = static_cast(d_ptr); - int index = priv->nameFilters.indexOf(filter); + const int index = qtFileDialog->nameFilters().indexOf(filter); if (index != -1) { QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); [delegate->mPopUpButton selectItemAtIndex:index]; @@ -632,24 +625,27 @@ void QCocoaFileDialogHelper::selectNameFilter_sys(const QString &filter) QString QCocoaFileDialogHelper::selectedNameFilter_sys() const { - QFileDialogPrivate *priv = static_cast(d_ptr); QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); int index = [delegate->mPopUpButton indexOfSelectedItem]; - return index != -1 ? priv->nameFilters.at(index) : QString(); + return index != -1 ? qtFileDialog->nameFilters().at(index) : QString(); } void QCocoaFileDialogHelper::deleteNativeDialog_sys() { - QFileDialogPrivate *priv = static_cast(d_ptr); [reinterpret_cast(mDelegate) release]; mDelegate = 0; - priv->nativeDialogInUse = false; } -bool QCocoaFileDialogHelper::setVisible_sys(bool visible) +void QCocoaFileDialogHelper::hide_sys() +{ + if (!qtFileDialog->isHidden()) + hideCocoaFilePanel(); +} + +bool QCocoaFileDialogHelper::show_sys(QWindow * /* parent */) { // Q_Q(QFileDialog); - if (!visible == qtFileDialog->isHidden()) + if (!qtFileDialog->isHidden()) return false; if (qtFileDialog->windowFlags() & Qt::WindowStaysOnTopHint) { @@ -660,27 +656,26 @@ bool QCocoaFileDialogHelper::setVisible_sys(bool visible) return false; } - return visible ? showCocoaFilePanel() : hideCocoaFilePanel(); + return showCocoaFilePanel(); } void QCocoaFileDialogHelper::createNSOpenSavePanelDelegate() { - QFileDialogPrivate *priv = static_cast(d_ptr); if (mDelegate) return; bool selectDir = qtFileDialog->selectedFiles().isEmpty(); QString selection(selectDir ? qtFileDialog->directory().absolutePath() : qtFileDialog->selectedFiles().value(0)); QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) alloc] - initWithAcceptMode:priv->acceptMode + initWithAcceptMode:qtFileDialog->acceptMode() title:qtFileDialog->windowTitle() hideNameFilterDetails:qtFileDialog->testOption(QFileDialog::HideNameFilterDetails) - qDirFilter:priv->model->filter() - fileOptions:priv->opts - fileMode:priv->fileMode + qDirFilter:qtFileDialog->filter() + fileOptions:qtFileDialog->options() + fileMode:qtFileDialog->fileMode() selectFile:selection confirmOverwrite:!qtFileDialog->testOption(QFileDialog::DontConfirmOverwrite) - priv:priv + fileDialog:qtFileDialog helper:this]; mDelegate = delegate; @@ -722,10 +717,7 @@ void QCocoaFileDialogHelper::platformNativeDialogModalHelp() // 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. - QFileDialogPrivate *priv = static_cast(d_ptr); - if (priv->nativeDialogInUse){ - QTimer::singleShot(1, qtFileDialog, SLOT(_q_platformRunNativeAppModalPanel())); - } + QTimer::singleShot(1, qtFileDialog, SLOT(_q_platformRunNativeAppModalPanel())); } void QCocoaFileDialogHelper::_q_platformRunNativeAppModalPanel() @@ -736,13 +728,13 @@ void QCocoaFileDialogHelper::_q_platformRunNativeAppModalPanel() #endif QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); [delegate runApplicationModalPanel]; - if (dialogResultCode_sys() == QDialog::Accepted) + if (dialogResultCode_sys() == QPlatformDialogHelper::Accepted) qtFileDialog->metaObject()->invokeMethod(qtFileDialog, "accept"); else qtFileDialog->metaObject()->invokeMethod(qtFileDialog, "reject"); } -QDialog::DialogCode QCocoaFileDialogHelper::dialogResultCode_sys() +QPlatformDialogHelper::DialogCode QCocoaFileDialogHelper::dialogResultCode_sys() { QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast(mDelegate); return [delegate dialogResultCode]; 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 #include #include +#include #include #include #include @@ -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 +QWindowsDialogHelperBase::QWindowsDialogHelperBase(QDialog *dialog) : m_dialog(dialog), - m_nativeDialog(0) + m_nativeDialog(0), + m_ownerWindow(0) { } -QWindowsNativeDialogBase *QWindowsDialogHelperBase::nativeDialog() const +template +QWindowsNativeDialogBase *QWindowsDialogHelperBase::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 +QWindowsNativeDialogBase *QWindowsDialogHelperBase::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 +void QWindowsDialogHelperBase::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 +bool QWindowsDialogHelperBase::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 +void QWindowsDialogHelperBase::hide_sys() +{ + if (m_nativeDialog) + m_nativeDialog->close(); + m_ownerWindow = 0; +} + +template +void QWindowsDialogHelperBase::platformNativeDialogModalHelp() { if (QWindowsContext::verboseDialogs) qDebug("%s" , __FUNCTION__); @@ -522,17 +527,37 @@ void QWindowsDialogHelperBase::platformNativeDialogModalHelp() Qt::QueuedConnection); } -void QWindowsDialogHelperBase::_q_platformRunNativeAppModalPanel() +template +void QWindowsDialogHelperBase::_q_platformRunNativeAppModalPanel() { if (QWindowsNativeDialogBase *nd =nativeDialog()) - nd->exec(ownerWindow(m_dialog)); + nd->exec(m_ownerWindow); } -QDialog::DialogCode QWindowsDialogHelperBase::dialogResultCode_sys() +template +QPlatformDialogHelper::DialogCode QWindowsDialogHelperBase::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 +QVariant QWindowsDialogHelperBase::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(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 { public: explicit QWindowsFileDialogHelper(QDialog *dialog) : @@ -1061,9 +1086,6 @@ public: m_fileDialog(qobject_cast(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 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 { public: - explicit QWindowsColorDialogHelper(QDialog *dialog) : - QWindowsDialogHelperBase(dialog), - m_colorDialog(qobject_cast(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(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" diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.h b/src/plugins/platforms/windows/qwindowsdialoghelpers.h index 8566f00d55..99f3c0b2d2 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.h +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.h @@ -44,12 +44,14 @@ #ifdef QT_WIDGETS_LIB +#include "qtwindows_additional.h" #include #include QT_BEGIN_NAMESPACE class QFileDialog; +class QDialog; class QWindowsNativeDialogBase; namespace QWindowsDialogs @@ -58,21 +60,25 @@ namespace QWindowsDialogs Type dialogType(const QDialog *dialog); void eatMouseMove(); + + bool useHelper(const QDialog *dialog); + QPlatformDialogHelper *createHelper(QDialog *dialog); } // namespace QWindowsDialogs -class QWindowsDialogHelperBase : public QPlatformDialogHelper +template +class QWindowsDialogHelperBase : public BaseClass { public: - static bool useHelper(const QDialog *dialog); - static QPlatformDialogHelper *create(QDialog *dialog); virtual void platformNativeDialogModalHelp(); virtual void _q_platformRunNativeAppModalPanel(); virtual void deleteNativeDialog_sys(); - virtual bool setVisible_sys(bool visible); - virtual QDialog::DialogCode dialogResultCode_sys(); + virtual bool show_sys(QWindow *parent); + virtual void hide_sys(); + virtual QVariant styleHint(QPlatformDialogHelper::StyleHint) const; + + virtual QPlatformDialogHelper::DialogCode dialogResultCode_sys(); - virtual bool nonNativeDialog() const = 0; virtual bool supportsNonModalDialog() const { return true; } protected: @@ -85,6 +91,7 @@ private: QDialog *m_dialog; QWindowsNativeDialogBase *m_nativeDialog; + HWND m_ownerWindow; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 4975347748..4ffbdb7491 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -325,12 +325,12 @@ QAbstractEventDispatcher * QWindowsIntegration::guiThreadEventDispatcher() const #ifdef QT_WIDGETS_LIB bool QWindowsIntegration::usePlatformNativeDialog(QDialog *dialog) const { - return QWindowsDialogHelperBase::useHelper(dialog); + return QWindowsDialogs::useHelper(dialog); } QPlatformDialogHelper *QWindowsIntegration::createPlatformDialogHelper(QDialog *dialog) const { - return QWindowsDialogHelperBase::create(dialog); + return QWindowsDialogs::createHelper(dialog); } #endif // QT_WIDGETS_LIB diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 6b956b1277..1eaaf79bf5 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -1282,6 +1282,8 @@ inline bool QColorDialogPrivate::isAlphaVisible() const { return cs->isAlphaVisi QColor QColorDialogPrivate::currentQColor() const { + if (nativeDialogInUse) + return platformColorDialogHelper()->currentColor_sys(); return cs->currentQColor(); } @@ -1650,6 +1652,13 @@ void QColorDialogPrivate::init(const QColor &initial) q->setCurrentColor(initial); } +void QColorDialogPrivate::initHelper(QPlatformDialogHelper *h) +{ + QColorDialog *d = q_func(); + QObject::connect(h, SIGNAL(currentColorChanged(QColor)), d, SIGNAL(currentColorChanged(QColor))); + QObject::connect(h, SIGNAL(colorSelected(QColor)), d, SIGNAL(colorSelected(QColor))); +} + void QColorDialogPrivate::_q_addCustom() { cusrgb[nextCust] = cs->currentColor(); @@ -1758,8 +1767,8 @@ void QColorDialog::setCurrentColor(const QColor &color) d->setCocoaPanelColor(color); #endif // ### fixme: Call helper - // if (d->nativeDialogInUse) - // qt_guiPlatformPlugin()->colorDialogSetCurrentColor(this, color); + if (d->nativeDialogInUse) + d->platformColorDialogHelper()->setCurrentColor_sys(color); } QColor QColorDialog::currentColor() const @@ -1768,7 +1777,6 @@ QColor QColorDialog::currentColor() const return d->currentQColor(); } - /*! Returns the color that the user selected by clicking the \gui{OK} or equivalent button. @@ -1915,8 +1923,7 @@ void QColorDialog::setVisible(bool visible) #else if (!(d->opts & DontUseNativeDialog)) - if (QPlatformDialogHelper *helper = d->platformHelper()) - d->nativeDialogInUse = helper->setVisible_sys(visible); + d->setNativeDialogVisible(visible); if (d->nativeDialogInUse) { // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below diff --git a/src/widgets/dialogs/qcolordialog_p.h b/src/widgets/dialogs/qcolordialog_p.h index b2413f1418..39d7192b1d 100644 --- a/src/widgets/dialogs/qcolordialog_p.h +++ b/src/widgets/dialogs/qcolordialog_p.h @@ -75,6 +75,9 @@ class QColorDialogPrivate : public QDialogPrivate Q_DECLARE_PUBLIC(QColorDialog) public: + QPlatformColorDialogHelper *platformColorDialogHelper() const + { return static_cast(platformHelper()); } + void init(const QColor &initial); QRgb currentColor() const; QColor currentQColor() const; @@ -133,6 +136,8 @@ public: void _q_macRunNativeAppModalPanel(); void mac_nativeDialogModalHelp(); #endif +private: + virtual void initHelper(QPlatformDialogHelper *h); }; #endif // QT_NO_COLORDIALOG diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index 09c0127852..a0b0cdc564 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -64,16 +64,42 @@ QPlatformDialogHelper *QDialogPrivate::platformHelper() const // Delayed creation of the platform, ensuring that // that qobject_cast<> on the dialog works in the plugin. if (!m_platformHelperCreated) { + QDialogPrivate *ncThis = const_cast(this); m_platformHelperCreated = true; - QDialog *dialog = const_cast(q_func()); m_platformHelper = QGuiApplicationPrivate::platformIntegration() - ->createPlatformDialogHelper(dialog); + ->createPlatformDialogHelper(ncThis->q_func()); if (m_platformHelper) - m_platformHelper->d_ptr = const_cast(this); + ncThis->initHelper(m_platformHelper); } return m_platformHelper; } +QWindow *QDialogPrivate::parentWindow() const +{ + if (const QWidget *parent = q_func()->nativeParentWidget()) + return parent->windowHandle(); + return 0; +} + +bool QDialogPrivate::setNativeDialogVisible(bool visible) +{ + if (QPlatformDialogHelper *helper = platformHelper()) { + if (visible) { + nativeDialogInUse = helper->show_sys(parentWindow()); + } else { + helper->hide_sys(); + } + } + return nativeDialogInUse; +} + +QVariant QDialogPrivate::styleHint(QPlatformDialogHelper::StyleHint hint) const +{ + if (const QPlatformDialogHelper *helper = platformHelper()) + return helper->styleHint(hint); + return QPlatformDialogHelper::defaultStyleHint(hint); +} + /*! \class QDialog \brief The QDialog class is the base class of dialog windows. @@ -705,15 +731,9 @@ void QDialog::setVisible(bool visible) if (d->eventLoop) d->eventLoop->exit(); } -#ifdef Q_WS_WIN - if (d->mainDef && isActiveWindow()) { - BOOL snapToDefault = false; - if (SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, &snapToDefault, 0)) { - if (snapToDefault) - QCursor::setPos(d->mainDef->mapToGlobal(d->mainDef->rect().center())); - } - } -#endif + if (d->mainDef && isActiveWindow() + && d->styleHint(QPlatformDialogHelper::SnapToDefaultButton).toBool()) + QCursor::setPos(d->mainDef->mapToGlobal(d->mainDef->rect().center())); } /*!\reimp */ diff --git a/src/widgets/dialogs/qdialog_p.h b/src/widgets/dialogs/qdialog_p.h index c88bda7b95..3d90686b6d 100644 --- a/src/widgets/dialogs/qdialog_p.h +++ b/src/widgets/dialogs/qdialog_p.h @@ -80,6 +80,10 @@ public: {} ~QDialogPrivate() { delete m_platformHelper; } + QWindow *parentWindow() const; + bool setNativeDialogVisible(bool visible); + QVariant styleHint(QPlatformDialogHelper::StyleHint hint) const; + QPointer mainDef; Qt::Orientation orientation; QWidget *extension; @@ -110,6 +114,8 @@ public: QPlatformDialogHelper *platformHelper() const; private: + virtual void initHelper(QPlatformDialogHelper *) {} + mutable QPlatformDialogHelper *m_platformHelper; mutable bool m_platformHelperCreated; }; diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 9b7c525c8b..75ba15af87 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -713,8 +713,7 @@ void QFileDialog::setVisible(bool visible) return; if (d->canBeNativeDialog()){ - if (d->setVisible_sys(visible)){ - d->nativeDialogInUse = true; + if (d->setNativeDialogVisible(visible)){ // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below // updates the state correctly, but skips showing the non-native version: setAttribute(Qt::WA_DontShowOnScreen); @@ -723,7 +722,6 @@ void QFileDialog::setVisible(bool visible) d->completer->setModel(0); #endif } else { - d->nativeDialogInUse = false; setAttribute(Qt::WA_DontShowOnScreen, false); #ifndef QT_NO_FSCOMPLETER if (d->proxyModel != 0) @@ -2268,7 +2266,7 @@ void QFileDialogPrivate::createWidgets() Q_Q(QFileDialog); model = new QFileSystemModel(q); model->setObjectName(QLatin1String("qt_filesystem_model")); - if (QPlatformDialogHelper *helper = platformHelper()) + if (QPlatformFileDialogHelper *helper = platformFileDialogHelper()) model->setNameFilterDisables(helper->defaultNameFilterDisables()); else model->setNameFilterDisables(false); diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h index 6d4a00e681..383734950c 100644 --- a/src/widgets/dialogs/qfiledialog_p.h +++ b/src/widgets/dialogs/qfiledialog_p.h @@ -114,6 +114,9 @@ class Q_WIDGETS_EXPORT QFileDialogPrivate : public QDialogPrivate public: QFileDialogPrivate(); + QPlatformFileDialogHelper *platformFileDialogHelper() const + { return static_cast(platformHelper()); } + void createToolButtons(); void createMenuActions(); void createWidgets(); @@ -262,7 +265,6 @@ public: // dialog. Returning false means that a non-native dialog must be // used instead. bool canBeNativeDialog(); - bool setVisible_sys(bool visible); void deleteNativeDialog_sys(); QDialog::DialogCode dialogResultCode_sys(); @@ -289,6 +291,8 @@ public: ~QFileDialogPrivate(); private: + virtual void initHelper(QPlatformDialogHelper *); + Q_DISABLE_COPY(QFileDialogPrivate) }; @@ -344,6 +348,16 @@ private: QFileDialogPrivate *d_ptr; }; +void QFileDialogPrivate::initHelper(QPlatformDialogHelper *h) +{ + QFileDialog *d = q_func(); + QObject::connect(h, SIGNAL(fileSelected(QString)), d, SIGNAL(fileSelected(QString))); + QObject::connect(h, SIGNAL(filesSelected(QStringList)), d, SIGNAL(filesSelected(QStringList))); + QObject::connect(h, SIGNAL(currentChanged(QString)), d, SIGNAL(currentChanged(QString))); + QObject::connect(h, SIGNAL(directoryEntered(QString)), d, SIGNAL(directoryEntered(QString))); + QObject::connect(h, SIGNAL(filterSelected(QString)), d, SIGNAL(filterSelected(QString))); +} + inline QModelIndex QFileDialogPrivate::mapToSource(const QModelIndex &index) const { #ifdef QT_NO_PROXYMODEL return index; @@ -366,71 +380,68 @@ inline QString QFileDialogPrivate::rootPath() const { // Dummies for platforms that don't use native dialogs: inline void QFileDialogPrivate::deleteNativeDialog_sys() { - if (QPlatformDialogHelper *helper = platformHelper()) + if (QPlatformFileDialogHelper *helper = platformFileDialogHelper()) { helper->deleteNativeDialog_sys(); -} - -inline bool QFileDialogPrivate::setVisible_sys(bool visible) -{ - if (QPlatformDialogHelper *helper = platformHelper()) - return helper->setVisible_sys(visible); - return false; + nativeDialogInUse = false; + } } inline QDialog::DialogCode QFileDialogPrivate::dialogResultCode_sys() { + QDialog::DialogCode result = QDialog::Rejected; if (QPlatformDialogHelper *helper = platformHelper()) - return helper->dialogResultCode_sys(); - return QDialog::Rejected; + if (helper->dialogResultCode_sys() == QPlatformDialogHelper::Accepted) + result = QDialog::Accepted; + return result; } inline void QFileDialogPrivate::setDirectory_sys(const QString &directory) { - if (QPlatformDialogHelper *helper = platformHelper()) + if (QPlatformFileDialogHelper *helper = platformFileDialogHelper()) helper->setDirectory_sys(directory); } inline QString QFileDialogPrivate::directory_sys() const { - if (QPlatformDialogHelper *helper = platformHelper()) + if (QPlatformFileDialogHelper *helper = platformFileDialogHelper()) return helper->directory_sys(); return QString(); } inline void QFileDialogPrivate::selectFile_sys(const QString &filename) { - if (QPlatformDialogHelper *helper = platformHelper()) + if (QPlatformFileDialogHelper *helper = platformFileDialogHelper()) helper->selectFile_sys(filename); } inline QStringList QFileDialogPrivate::selectedFiles_sys() const { - if (QPlatformDialogHelper *helper = platformHelper()) + if (QPlatformFileDialogHelper *helper = platformFileDialogHelper()) return helper->selectedFiles_sys(); return QStringList(); } inline void QFileDialogPrivate::setFilter_sys() { - if (QPlatformDialogHelper *helper = platformHelper()) + if (QPlatformFileDialogHelper *helper = platformFileDialogHelper()) helper->setFilter_sys(); } inline void QFileDialogPrivate::setNameFilters_sys(const QStringList &filters) { - if (QPlatformDialogHelper *helper = platformHelper()) + if (QPlatformFileDialogHelper *helper = platformFileDialogHelper()) helper->setNameFilters_sys(filters); } inline void QFileDialogPrivate::selectNameFilter_sys(const QString &filter) { - if (QPlatformDialogHelper *helper = platformHelper()) + if (QPlatformFileDialogHelper *helper = platformFileDialogHelper()) helper->selectNameFilter_sys(filter); } inline QString QFileDialogPrivate::selectedNameFilter_sys() const { - if (QPlatformDialogHelper *helper = platformHelper()) + if (QPlatformFileDialogHelper *helper = platformFileDialogHelper()) return helper->selectedNameFilter_sys(); return QString(); } diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp index 1b8a9137ac..1935a5aa73 100644 --- a/src/widgets/dialogs/qfontdialog.cpp +++ b/src/widgets/dialogs/qfontdialog.cpp @@ -490,6 +490,13 @@ bool QFontDialog::eventFilter(QObject *o , QEvent *e) return QDialog::eventFilter(o, e); } +void QFontDialogPrivate::initHelper(QPlatformDialogHelper *h) +{ + QFontDialog *d = q_func(); + QObject::connect(h, SIGNAL(currentFontChanged(QFont)), d, SIGNAL(currentFontChanged(QFont))); + QObject::connect(h, SIGNAL(fontSelected(QFont)), d, SIGNAL(fontSelected(QFont))); +} + /* Updates the contents of the "font family" list box. This function can be reimplemented if you have special requirements. @@ -819,6 +826,8 @@ void QFontDialog::setCurrentFont(const QFont &font) d->strikeout->setChecked(font.strikeOut()); d->underline->setChecked(font.underline()); d->updateFamilies(); + if (QPlatformFontDialogHelper *helper = d->platformFontDialogHelper()) + helper->setCurrentFont_sys(font); #ifdef Q_WS_MAC if (d->delegate) @@ -836,6 +845,8 @@ void QFontDialog::setCurrentFont(const QFont &font) QFont QFontDialog::currentFont() const { Q_D(const QFontDialog); + if (const QPlatformFontDialogHelper *helper = d->platformFontDialogHelper()) + return helper->currentFont_sys(); return d->sampleEdit->font(); } @@ -985,8 +996,7 @@ void QFontDialog::setVisible(bool visible) return; Q_D(QFontDialog); if (d->canBeNativeDialog()) - if (QPlatformDialogHelper *helper = d->platformHelper()) - d->nativeDialogInUse = helper->setVisible_sys(visible); + d->setNativeDialogVisible(visible); if (d->nativeDialogInUse) { // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below // updates the state correctly, but skips showing the non-native version: diff --git a/src/widgets/dialogs/qfontdialog_p.h b/src/widgets/dialogs/qfontdialog_p.h index 8b423f92d8..ef4e933624 100644 --- a/src/widgets/dialogs/qfontdialog_p.h +++ b/src/widgets/dialogs/qfontdialog_p.h @@ -57,6 +57,7 @@ #include "private/qdialog_p.h" #include "qfontdatabase.h" #include "qfontdialog.h" +#include "qplatformdialoghelper_qpa.h" #ifndef QT_NO_FONTDIALOG @@ -80,6 +81,9 @@ public: : writingSystem(QFontDatabase::Any) { } + QPlatformFontDialogHelper *platformFontDialogHelper() const + { return static_cast(platformHelper()); } + void updateFamilies(); void updateStyles(); void updateSizes(); @@ -156,6 +160,9 @@ public: static bool sharedFontPanelAvailable; #endif + +private: + virtual void initHelper(QPlatformDialogHelper *); }; #endif // QT_NO_FONTDIALOG diff --git a/src/widgets/kernel/qplatformdialoghelper_qpa.cpp b/src/widgets/kernel/qplatformdialoghelper_qpa.cpp index 4ad3118053..daf864ff30 100644 --- a/src/widgets/kernel/qplatformdialoghelper_qpa.cpp +++ b/src/widgets/kernel/qplatformdialoghelper_qpa.cpp @@ -41,11 +41,50 @@ #include "qplatformdialoghelper_qpa.h" -QPlatformDialogHelper::QPlatformDialogHelper() : - d_ptr(0) +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QPlatformDialogHelper + \since 5.0 + \internal + \brief The QPlatformDialogHelper class allows for platform-specific customization of dialogs. + +*/ + +/*! + \enum QPlatformDialogHelper::StyleHint + + This enum type specifies platform-specific style hints. + + \value SnapToDefaultButton Snap the mouse to the center of the default + button. There is corresponding system + setting on Windows. + + \sa styleHint() +*/ + +QPlatformDialogHelper::QPlatformDialogHelper() { } QPlatformDialogHelper::~QPlatformDialogHelper() { } + +QVariant QPlatformDialogHelper::styleHint(StyleHint hint) const +{ + return QPlatformDialogHelper::defaultStyleHint(hint); +} + +QVariant QPlatformDialogHelper::defaultStyleHint(QPlatformDialogHelper::StyleHint hint) +{ + switch (hint) { + case QPlatformDialogHelper::SnapToDefaultButton: + return QVariant(false); + } + return QVariant(); +} + +QT_END_NAMESPACE diff --git a/src/widgets/kernel/qplatformdialoghelper_qpa.h b/src/widgets/kernel/qplatformdialoghelper_qpa.h index 2a3fbaa87e..970de611bc 100644 --- a/src/widgets/kernel/qplatformdialoghelper_qpa.h +++ b/src/widgets/kernel/qplatformdialoghelper_qpa.h @@ -43,7 +43,7 @@ #define QPLATFORMDIALOGHELPER_H #include -#include +#include QT_BEGIN_HEADER @@ -52,23 +52,66 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) class QString; -class QObjectPrivate; +class QColor; +class QFont; +class QWindow; +class QVariant; -class Q_WIDGETS_EXPORT QPlatformDialogHelper +class Q_WIDGETS_EXPORT QPlatformDialogHelper : public QObject { + Q_OBJECT public: + enum StyleHint { + SnapToDefaultButton + }; + enum DialogCode { Rejected, Accepted }; + QPlatformDialogHelper(); virtual ~QPlatformDialogHelper(); + virtual QVariant styleHint(StyleHint hint) const; + virtual void platformNativeDialogModalHelp() = 0; virtual void _q_platformRunNativeAppModalPanel() = 0; - virtual bool defaultNameFilterDisables() const = 0; - virtual void deleteNativeDialog_sys() = 0; - virtual bool setVisible_sys(bool visible) = 0; - virtual QDialog::DialogCode dialogResultCode_sys() = 0; + virtual bool show_sys(QWindow *parent) = 0; + virtual void hide_sys() = 0; + + virtual DialogCode dialogResultCode_sys() = 0; + + static QVariant defaultStyleHint(QPlatformDialogHelper::StyleHint hint); +}; + +class Q_WIDGETS_EXPORT QPlatformColorDialogHelper : public QPlatformDialogHelper +{ + Q_OBJECT +public: + virtual void setCurrentColor_sys(const QColor &) = 0; + virtual QColor currentColor_sys() const = 0; +Q_SIGNALS: + void currentColorChanged(const QColor &color); + void colorSelected(const QColor &color); +}; + +class Q_WIDGETS_EXPORT QPlatformFontDialogHelper : public QPlatformDialogHelper +{ + Q_OBJECT +public: + virtual void setCurrentFont_sys(const QFont &) = 0; + virtual QFont currentFont_sys() const = 0; + +Q_SIGNALS: + void currentFontChanged(const QFont &font); + void fontSelected(const QFont &font); +}; + +class Q_WIDGETS_EXPORT QPlatformFileDialogHelper : public QPlatformDialogHelper +{ + Q_OBJECT +public: + virtual bool defaultNameFilterDisables() const = 0; virtual void setDirectory_sys(const QString &directory) = 0; virtual QString directory_sys() const = 0; virtual void selectFile_sys(const QString &filename) = 0; @@ -78,7 +121,12 @@ public: virtual void selectNameFilter_sys(const QString &filter) = 0; virtual QString selectedNameFilter_sys() const = 0; - QObjectPrivate *d_ptr; +Q_SIGNALS: + void fileSelected(const QString &file); + void filesSelected(const QStringList &files); + void currentChanged(const QString &path); + void directoryEntered(const QString &directory); + void filterSelected(const QString &filter); }; QT_END_NAMESPACE -- cgit v1.2.3