QPlatformDialogHelper: Split class hierarchy, decouple from Dialog

- 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 <morten.sorvig@nokia.com>
This commit is contained in:
Friedemann Kleint 2011-11-10 13:07:01 +01:00 committed by Qt by Nokia
parent 9a8a70d8e4
commit af914694d8
15 changed files with 366 additions and 199 deletions

View File

@ -44,10 +44,11 @@
#include <QObject> #include <QObject>
#include <qplatformdialoghelper_qpa.h> #include <qplatformdialoghelper_qpa.h>
class QFileDialog; class QFileDialog;
class QFileDialogPrivate; class QFileDialogPrivate;
class QCocoaFileDialogHelper : public QPlatformDialogHelper class QCocoaFileDialogHelper : public QPlatformFileDialogHelper
{ {
public: public:
QCocoaFileDialogHelper(QFileDialog *dialog); QCocoaFileDialogHelper(QFileDialog *dialog);
@ -59,8 +60,9 @@ public:
bool defaultNameFilterDisables() const; bool defaultNameFilterDisables() const;
void deleteNativeDialog_sys(); void deleteNativeDialog_sys();
bool setVisible_sys(bool visible); bool show_sys(QWindow *parent);
QDialog::DialogCode dialogResultCode_sys(); void hide_sys();
QPlatformFileDialogHelper::DialogCode dialogResultCode_sys();
void setDirectory_sys(const QString &directory); void setDirectory_sys(const QString &directory);
QString directory_sys() const; QString directory_sys() const;
void selectFile_sys(const QString &filename); void selectFile_sys(const QString &filename);

View File

@ -89,7 +89,7 @@ QT_USE_NAMESPACE
NSView *mAccessoryView; NSView *mAccessoryView;
NSPopUpButton *mPopUpButton; NSPopUpButton *mPopUpButton;
NSTextField *mTextField; NSTextField *mTextField;
QFileDialogPrivate *mPriv; QFileDialog *mFileDialog;
QCocoaFileDialogHelper *mHelper; QCocoaFileDialogHelper *mHelper;
NSString *mCurrentDir; NSString *mCurrentDir;
bool mConfirmOverwrite; bool mConfirmOverwrite;
@ -133,11 +133,11 @@ QT_USE_NAMESPACE
fileMode:(QT_PREPEND_NAMESPACE(QFileDialog::FileMode))fileMode fileMode:(QT_PREPEND_NAMESPACE(QFileDialog::FileMode))fileMode
selectFile:(const QString &)selectFile selectFile:(const QString &)selectFile
confirmOverwrite:(bool)confirm confirmOverwrite:(bool)confirm
priv:(QFileDialogPrivate *)priv fileDialog:(QFileDialog *)fileDialog
helper:(QCocoaFileDialogHelper *)helper helper:(QCocoaFileDialogHelper *)helper
{ {
self = [super init]; self = [super init];
mFileDialog = fileDialog;
mAcceptMode = acceptMode; mAcceptMode = acceptMode;
if (mAcceptMode == QT_PREPEND_NAMESPACE(QFileDialog::AcceptOpen)){ if (mAcceptMode == QT_PREPEND_NAMESPACE(QFileDialog::AcceptOpen)){
mOpenPanel = [NSOpenPanel openPanel]; mOpenPanel = [NSOpenPanel openPanel];
@ -154,12 +154,11 @@ QT_USE_NAMESPACE
mFileMode = fileMode; mFileMode = fileMode;
mConfirmOverwrite = confirm; mConfirmOverwrite = confirm;
mReturnCode = -1; mReturnCode = -1;
mPriv = priv;
mHelper = helper; mHelper = helper;
mLastFilterCheckPath = new QString; mLastFilterCheckPath = new QString;
mQDirFilterEntryList = new QStringList; mQDirFilterEntryList = new QStringList;
mNameFilterDropDownList = new QStringList(priv->nameFilters); mNameFilterDropDownList = new QStringList(mFileDialog->nameFilters());
QString selectedVisualNameFilter = priv->qFileDialogUi->fileTypeCombo->currentText(); QString selectedVisualNameFilter = mFileDialog->selectedNameFilter();
mSelectedNameFilter = new QStringList([self findStrippedFilterWithVisualFilterName:selectedVisualNameFilter]); mSelectedNameFilter = new QStringList([self findStrippedFilterWithVisualFilterName:selectedVisualNameFilter]);
QFileInfo sel(selectFile); QFileInfo sel(selectFile);
@ -177,11 +176,10 @@ QT_USE_NAMESPACE
[self createAccessory]; [self createAccessory];
[mSavePanel setAccessoryView:mNameFilterDropDownList->size() > 1 ? mAccessoryView : nil]; [mSavePanel setAccessoryView:mNameFilterDropDownList->size() > 1 ? mAccessoryView : nil];
if (mPriv){
[mSavePanel setPrompt:[self strip:mPriv->acceptLabel]]; [mSavePanel setPrompt:[self strip:mFileDialog->labelText(QFileDialog::Accept)]];
if (mPriv->fileNameLabelExplicitlySat) if (false) // ### fixme mPriv->fileNameLabelExplicitlySat)
[mSavePanel setNameFieldLabel:[self strip:mPriv->qFileDialogUi->fileNameLabel->text()]]; [mSavePanel setNameFieldLabel:[self strip:mFileDialog->labelText(QFileDialog::FileName)]];
}
[self updateProperties]; [self updateProperties];
[mSavePanel retain]; [mSavePanel retain];
@ -254,9 +252,9 @@ QT_USE_NAMESPACE
return (mReturnCode == NSOKButton); 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 - (void)showWindowModalSheet:(QWidget *)docWidget
@ -391,8 +389,9 @@ QT_USE_NAMESPACE
[mOpenPanel setResolvesAliases:!(*mFileOptions & QT_PREPEND_NAMESPACE(QFileDialog::DontResolveSymlinks))]; [mOpenPanel setResolvesAliases:!(*mFileOptions & QT_PREPEND_NAMESPACE(QFileDialog::DontResolveSymlinks))];
QStringList ext = [self acceptableExtensionsForSave]; QStringList ext = [self acceptableExtensionsForSave];
if (mPriv && !ext.isEmpty() && !mPriv->defaultSuffix.isEmpty()) const QString defaultSuffix = mFileDialog->defaultSuffix();
ext.prepend(mPriv->defaultSuffix); if (!ext.isEmpty() && !defaultSuffix.isEmpty())
ext.prepend(defaultSuffix);
[mSavePanel setAllowedFileTypes:ext.isEmpty() ? nil : QT_PREPEND_NAMESPACE(qt_mac_QStringListToNSMutableArray(ext))]; [mSavePanel setAllowedFileTypes:ext.isEmpty() ? nil : QT_PREPEND_NAMESPACE(qt_mac_QStringListToNSMutableArray(ext))];
if ([mSavePanel isVisible]) if ([mSavePanel isVisible])
@ -474,10 +473,7 @@ QT_USE_NAMESPACE
[mTextField setSelectable:false]; [mTextField setSelectable:false];
[mTextField setBordered:false]; [mTextField setBordered:false];
[mTextField setDrawsBackground:false]; [mTextField setDrawsBackground:false];
if (mPriv){ [mTextField setStringValue:[self strip:mFileDialog->labelText(QFileDialog::FileType)]];
[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:"))];
} }
- (void)createPopUpButton:(const QString &)selectedFilter hideDetails:(BOOL)hideDetails - (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) void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_directoryEntered(const QString &newDir)
{ {
QFileDialogPrivate *priv = static_cast<QFileDialogPrivate*>(d_ptr); // ### fixme: priv->setLastVisitedDirectory(newDir);
priv->setLastVisitedDirectory(newDir); emit directoryEntered(newDir);
qtFileDialog->metaObject()->invokeMethod(qtFileDialog, "directoryEntered", Q_ARG(QString, newDir));
} }
void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_filterSelected(int menuIndex) void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_filterSelected(int menuIndex)
{ {
QFileDialogPrivate *priv = static_cast<QFileDialogPrivate*>(d_ptr); const QStringList filters = qtFileDialog->nameFilters();
qtFileDialog->metaObject()->invokeMethod(qtFileDialog, "filterSelected", Q_ARG(QString, priv->nameFilters.at(menuIndex))); emit filterSelected(menuIndex >= 0 && menuIndex < filters.size() ? filters.at(menuIndex) : QString());
} }
extern OSErr qt_mac_create_fsref(const QString &, FSRef *); // qglobal.cpp 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() void QCocoaFileDialogHelper::setFilter_sys()
{ {
QFileDialogPrivate *priv = static_cast<QFileDialogPrivate*>(d_ptr);
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate); QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
*(delegate->mQDirFilter) = priv->model->filter(); *(delegate->mQDirFilter) = qtFileDialog->filter();
delegate->mFileMode = priv->fileMode; delegate->mFileMode = qtFileDialog->fileMode();
[delegate->mSavePanel setTitle:qt_mac_QStringToNSString(qtFileDialog->windowTitle())]; [delegate->mSavePanel setTitle:qt_mac_QStringToNSString(qtFileDialog->windowTitle())];
[delegate->mSavePanel setPrompt:[delegate strip:priv->acceptLabel]]; [delegate->mSavePanel setPrompt:[delegate strip:qtFileDialog->labelText(QFileDialog::Accept)]];
if (priv->fileNameLabelExplicitlySat) if (false) // ### fixme priv->fileNameLabelExplicitlySat)
[delegate->mSavePanel setNameFieldLabel:[delegate strip:priv->qFileDialogUi->fileNameLabel->text()]]; [delegate->mSavePanel setNameFieldLabel:[delegate strip:qtFileDialog->labelText(QFileDialog::FileName)]];
[delegate updateProperties]; [delegate updateProperties];
} }
void QCocoaFileDialogHelper::selectNameFilter_sys(const QString &filter) void QCocoaFileDialogHelper::selectNameFilter_sys(const QString &filter)
{ {
QFileDialogPrivate *priv = static_cast<QFileDialogPrivate*>(d_ptr); const int index = qtFileDialog->nameFilters().indexOf(filter);
int index = priv->nameFilters.indexOf(filter);
if (index != -1) { if (index != -1) {
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate); QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
[delegate->mPopUpButton selectItemAtIndex:index]; [delegate->mPopUpButton selectItemAtIndex:index];
@ -632,24 +625,27 @@ void QCocoaFileDialogHelper::selectNameFilter_sys(const QString &filter)
QString QCocoaFileDialogHelper::selectedNameFilter_sys() const QString QCocoaFileDialogHelper::selectedNameFilter_sys() const
{ {
QFileDialogPrivate *priv = static_cast<QFileDialogPrivate*>(d_ptr);
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate); QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
int index = [delegate->mPopUpButton indexOfSelectedItem]; 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() void QCocoaFileDialogHelper::deleteNativeDialog_sys()
{ {
QFileDialogPrivate *priv = static_cast<QFileDialogPrivate*>(d_ptr);
[reinterpret_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate) release]; [reinterpret_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate) release];
mDelegate = 0; 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); // Q_Q(QFileDialog);
if (!visible == qtFileDialog->isHidden()) if (!qtFileDialog->isHidden())
return false; return false;
if (qtFileDialog->windowFlags() & Qt::WindowStaysOnTopHint) { if (qtFileDialog->windowFlags() & Qt::WindowStaysOnTopHint) {
@ -660,27 +656,26 @@ bool QCocoaFileDialogHelper::setVisible_sys(bool visible)
return false; return false;
} }
return visible ? showCocoaFilePanel() : hideCocoaFilePanel(); return showCocoaFilePanel();
} }
void QCocoaFileDialogHelper::createNSOpenSavePanelDelegate() void QCocoaFileDialogHelper::createNSOpenSavePanelDelegate()
{ {
QFileDialogPrivate *priv = static_cast<QFileDialogPrivate*>(d_ptr);
if (mDelegate) if (mDelegate)
return; return;
bool selectDir = qtFileDialog->selectedFiles().isEmpty(); bool selectDir = qtFileDialog->selectedFiles().isEmpty();
QString selection(selectDir ? qtFileDialog->directory().absolutePath() : qtFileDialog->selectedFiles().value(0)); QString selection(selectDir ? qtFileDialog->directory().absolutePath() : qtFileDialog->selectedFiles().value(0));
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) alloc] QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) alloc]
initWithAcceptMode:priv->acceptMode initWithAcceptMode:qtFileDialog->acceptMode()
title:qtFileDialog->windowTitle() title:qtFileDialog->windowTitle()
hideNameFilterDetails:qtFileDialog->testOption(QFileDialog::HideNameFilterDetails) hideNameFilterDetails:qtFileDialog->testOption(QFileDialog::HideNameFilterDetails)
qDirFilter:priv->model->filter() qDirFilter:qtFileDialog->filter()
fileOptions:priv->opts fileOptions:qtFileDialog->options()
fileMode:priv->fileMode fileMode:qtFileDialog->fileMode()
selectFile:selection selectFile:selection
confirmOverwrite:!qtFileDialog->testOption(QFileDialog::DontConfirmOverwrite) confirmOverwrite:!qtFileDialog->testOption(QFileDialog::DontConfirmOverwrite)
priv:priv fileDialog:qtFileDialog
helper:this]; helper:this];
mDelegate = delegate; mDelegate = delegate;
@ -722,10 +717,7 @@ void QCocoaFileDialogHelper::platformNativeDialogModalHelp()
// running (which is the case if e.g a top-most QEventLoop has been // 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 // 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. // if [NSApp run] is still on the stack)), showing a native modal dialog will fail.
QFileDialogPrivate *priv = static_cast<QFileDialogPrivate*>(d_ptr); QTimer::singleShot(1, qtFileDialog, SLOT(_q_platformRunNativeAppModalPanel()));
if (priv->nativeDialogInUse){
QTimer::singleShot(1, qtFileDialog, SLOT(_q_platformRunNativeAppModalPanel()));
}
} }
void QCocoaFileDialogHelper::_q_platformRunNativeAppModalPanel() void QCocoaFileDialogHelper::_q_platformRunNativeAppModalPanel()
@ -736,13 +728,13 @@ void QCocoaFileDialogHelper::_q_platformRunNativeAppModalPanel()
#endif #endif
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate); QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
[delegate runApplicationModalPanel]; [delegate runApplicationModalPanel];
if (dialogResultCode_sys() == QDialog::Accepted) if (dialogResultCode_sys() == QPlatformDialogHelper::Accepted)
qtFileDialog->metaObject()->invokeMethod(qtFileDialog, "accept"); qtFileDialog->metaObject()->invokeMethod(qtFileDialog, "accept");
else else
qtFileDialog->metaObject()->invokeMethod(qtFileDialog, "reject"); qtFileDialog->metaObject()->invokeMethod(qtFileDialog, "reject");
} }
QDialog::DialogCode QCocoaFileDialogHelper::dialogResultCode_sys() QPlatformDialogHelper::DialogCode QCocoaFileDialogHelper::dialogResultCode_sys()
{ {
QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate); QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *delegate = static_cast<QT_MANGLE_NAMESPACE(QNSOpenSavePanelDelegate) *>(mDelegate);
return [delegate dialogResultCode]; return [delegate dialogResultCode];

View File

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

View File

@ -44,12 +44,14 @@
#ifdef QT_WIDGETS_LIB #ifdef QT_WIDGETS_LIB
#include "qtwindows_additional.h"
#include <QtWidgets/qplatformdialoghelper_qpa.h> #include <QtWidgets/qplatformdialoghelper_qpa.h>
#include <QtCore/QStringList> #include <QtCore/QStringList>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QFileDialog; class QFileDialog;
class QDialog;
class QWindowsNativeDialogBase; class QWindowsNativeDialogBase;
namespace QWindowsDialogs namespace QWindowsDialogs
@ -58,21 +60,25 @@ namespace QWindowsDialogs
Type dialogType(const QDialog *dialog); Type dialogType(const QDialog *dialog);
void eatMouseMove(); void eatMouseMove();
bool useHelper(const QDialog *dialog);
QPlatformDialogHelper *createHelper(QDialog *dialog);
} // namespace QWindowsDialogs } // namespace QWindowsDialogs
class QWindowsDialogHelperBase : public QPlatformDialogHelper template <class BaseClass>
class QWindowsDialogHelperBase : public BaseClass
{ {
public: public:
static bool useHelper(const QDialog *dialog);
static QPlatformDialogHelper *create(QDialog *dialog);
virtual void platformNativeDialogModalHelp(); virtual void platformNativeDialogModalHelp();
virtual void _q_platformRunNativeAppModalPanel(); virtual void _q_platformRunNativeAppModalPanel();
virtual void deleteNativeDialog_sys(); virtual void deleteNativeDialog_sys();
virtual bool setVisible_sys(bool visible); virtual bool show_sys(QWindow *parent);
virtual QDialog::DialogCode dialogResultCode_sys(); 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; } virtual bool supportsNonModalDialog() const { return true; }
protected: protected:
@ -85,6 +91,7 @@ private:
QDialog *m_dialog; QDialog *m_dialog;
QWindowsNativeDialogBase *m_nativeDialog; QWindowsNativeDialogBase *m_nativeDialog;
HWND m_ownerWindow;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -325,12 +325,12 @@ QAbstractEventDispatcher * QWindowsIntegration::guiThreadEventDispatcher() const
#ifdef QT_WIDGETS_LIB #ifdef QT_WIDGETS_LIB
bool QWindowsIntegration::usePlatformNativeDialog(QDialog *dialog) const bool QWindowsIntegration::usePlatformNativeDialog(QDialog *dialog) const
{ {
return QWindowsDialogHelperBase::useHelper(dialog); return QWindowsDialogs::useHelper(dialog);
} }
QPlatformDialogHelper *QWindowsIntegration::createPlatformDialogHelper(QDialog *dialog) const QPlatformDialogHelper *QWindowsIntegration::createPlatformDialogHelper(QDialog *dialog) const
{ {
return QWindowsDialogHelperBase::create(dialog); return QWindowsDialogs::createHelper(dialog);
} }
#endif // QT_WIDGETS_LIB #endif // QT_WIDGETS_LIB

View File

@ -1282,6 +1282,8 @@ inline bool QColorDialogPrivate::isAlphaVisible() const { return cs->isAlphaVisi
QColor QColorDialogPrivate::currentQColor() const QColor QColorDialogPrivate::currentQColor() const
{ {
if (nativeDialogInUse)
return platformColorDialogHelper()->currentColor_sys();
return cs->currentQColor(); return cs->currentQColor();
} }
@ -1650,6 +1652,13 @@ void QColorDialogPrivate::init(const QColor &initial)
q->setCurrentColor(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() void QColorDialogPrivate::_q_addCustom()
{ {
cusrgb[nextCust] = cs->currentColor(); cusrgb[nextCust] = cs->currentColor();
@ -1758,8 +1767,8 @@ void QColorDialog::setCurrentColor(const QColor &color)
d->setCocoaPanelColor(color); d->setCocoaPanelColor(color);
#endif #endif
// ### fixme: Call helper // ### fixme: Call helper
// if (d->nativeDialogInUse) if (d->nativeDialogInUse)
// qt_guiPlatformPlugin()->colorDialogSetCurrentColor(this, color); d->platformColorDialogHelper()->setCurrentColor_sys(color);
} }
QColor QColorDialog::currentColor() const QColor QColorDialog::currentColor() const
@ -1768,7 +1777,6 @@ QColor QColorDialog::currentColor() const
return d->currentQColor(); return d->currentQColor();
} }
/*! /*!
Returns the color that the user selected by clicking the \gui{OK} Returns the color that the user selected by clicking the \gui{OK}
or equivalent button. or equivalent button.
@ -1915,8 +1923,7 @@ void QColorDialog::setVisible(bool visible)
#else #else
if (!(d->opts & DontUseNativeDialog)) if (!(d->opts & DontUseNativeDialog))
if (QPlatformDialogHelper *helper = d->platformHelper()) d->setNativeDialogVisible(visible);
d->nativeDialogInUse = helper->setVisible_sys(visible);
if (d->nativeDialogInUse) { if (d->nativeDialogInUse) {
// Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below

View File

@ -75,6 +75,9 @@ class QColorDialogPrivate : public QDialogPrivate
Q_DECLARE_PUBLIC(QColorDialog) Q_DECLARE_PUBLIC(QColorDialog)
public: public:
QPlatformColorDialogHelper *platformColorDialogHelper() const
{ return static_cast<QPlatformColorDialogHelper *>(platformHelper()); }
void init(const QColor &initial); void init(const QColor &initial);
QRgb currentColor() const; QRgb currentColor() const;
QColor currentQColor() const; QColor currentQColor() const;
@ -133,6 +136,8 @@ public:
void _q_macRunNativeAppModalPanel(); void _q_macRunNativeAppModalPanel();
void mac_nativeDialogModalHelp(); void mac_nativeDialogModalHelp();
#endif #endif
private:
virtual void initHelper(QPlatformDialogHelper *h);
}; };
#endif // QT_NO_COLORDIALOG #endif // QT_NO_COLORDIALOG

View File

@ -64,16 +64,42 @@ QPlatformDialogHelper *QDialogPrivate::platformHelper() const
// Delayed creation of the platform, ensuring that // Delayed creation of the platform, ensuring that
// that qobject_cast<> on the dialog works in the plugin. // that qobject_cast<> on the dialog works in the plugin.
if (!m_platformHelperCreated) { if (!m_platformHelperCreated) {
QDialogPrivate *ncThis = const_cast<QDialogPrivate *>(this);
m_platformHelperCreated = true; m_platformHelperCreated = true;
QDialog *dialog = const_cast<QDialog *>(q_func());
m_platformHelper = QGuiApplicationPrivate::platformIntegration() m_platformHelper = QGuiApplicationPrivate::platformIntegration()
->createPlatformDialogHelper(dialog); ->createPlatformDialogHelper(ncThis->q_func());
if (m_platformHelper) if (m_platformHelper)
m_platformHelper->d_ptr = const_cast<QDialogPrivate *>(this); ncThis->initHelper(m_platformHelper);
} }
return 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 \class QDialog
\brief The QDialog class is the base class of dialog windows. \brief The QDialog class is the base class of dialog windows.
@ -705,15 +731,9 @@ void QDialog::setVisible(bool visible)
if (d->eventLoop) if (d->eventLoop)
d->eventLoop->exit(); d->eventLoop->exit();
} }
#ifdef Q_WS_WIN if (d->mainDef && isActiveWindow()
if (d->mainDef && isActiveWindow()) { && d->styleHint(QPlatformDialogHelper::SnapToDefaultButton).toBool())
BOOL snapToDefault = false; QCursor::setPos(d->mainDef->mapToGlobal(d->mainDef->rect().center()));
if (SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, &snapToDefault, 0)) {
if (snapToDefault)
QCursor::setPos(d->mainDef->mapToGlobal(d->mainDef->rect().center()));
}
}
#endif
} }
/*!\reimp */ /*!\reimp */

View File

@ -80,6 +80,10 @@ public:
{} {}
~QDialogPrivate() { delete m_platformHelper; } ~QDialogPrivate() { delete m_platformHelper; }
QWindow *parentWindow() const;
bool setNativeDialogVisible(bool visible);
QVariant styleHint(QPlatformDialogHelper::StyleHint hint) const;
QPointer<QPushButton> mainDef; QPointer<QPushButton> mainDef;
Qt::Orientation orientation; Qt::Orientation orientation;
QWidget *extension; QWidget *extension;
@ -110,6 +114,8 @@ public:
QPlatformDialogHelper *platformHelper() const; QPlatformDialogHelper *platformHelper() const;
private: private:
virtual void initHelper(QPlatformDialogHelper *) {}
mutable QPlatformDialogHelper *m_platformHelper; mutable QPlatformDialogHelper *m_platformHelper;
mutable bool m_platformHelperCreated; mutable bool m_platformHelperCreated;
}; };

View File

@ -713,8 +713,7 @@ void QFileDialog::setVisible(bool visible)
return; return;
if (d->canBeNativeDialog()){ if (d->canBeNativeDialog()){
if (d->setVisible_sys(visible)){ if (d->setNativeDialogVisible(visible)){
d->nativeDialogInUse = true;
// Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
// updates the state correctly, but skips showing the non-native version: // updates the state correctly, but skips showing the non-native version:
setAttribute(Qt::WA_DontShowOnScreen); setAttribute(Qt::WA_DontShowOnScreen);
@ -723,7 +722,6 @@ void QFileDialog::setVisible(bool visible)
d->completer->setModel(0); d->completer->setModel(0);
#endif #endif
} else { } else {
d->nativeDialogInUse = false;
setAttribute(Qt::WA_DontShowOnScreen, false); setAttribute(Qt::WA_DontShowOnScreen, false);
#ifndef QT_NO_FSCOMPLETER #ifndef QT_NO_FSCOMPLETER
if (d->proxyModel != 0) if (d->proxyModel != 0)
@ -2268,7 +2266,7 @@ void QFileDialogPrivate::createWidgets()
Q_Q(QFileDialog); Q_Q(QFileDialog);
model = new QFileSystemModel(q); model = new QFileSystemModel(q);
model->setObjectName(QLatin1String("qt_filesystem_model")); model->setObjectName(QLatin1String("qt_filesystem_model"));
if (QPlatformDialogHelper *helper = platformHelper()) if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
model->setNameFilterDisables(helper->defaultNameFilterDisables()); model->setNameFilterDisables(helper->defaultNameFilterDisables());
else else
model->setNameFilterDisables(false); model->setNameFilterDisables(false);

View File

@ -114,6 +114,9 @@ class Q_WIDGETS_EXPORT QFileDialogPrivate : public QDialogPrivate
public: public:
QFileDialogPrivate(); QFileDialogPrivate();
QPlatformFileDialogHelper *platformFileDialogHelper() const
{ return static_cast<QPlatformFileDialogHelper *>(platformHelper()); }
void createToolButtons(); void createToolButtons();
void createMenuActions(); void createMenuActions();
void createWidgets(); void createWidgets();
@ -262,7 +265,6 @@ public:
// dialog. Returning false means that a non-native dialog must be // dialog. Returning false means that a non-native dialog must be
// used instead. // used instead.
bool canBeNativeDialog(); bool canBeNativeDialog();
bool setVisible_sys(bool visible);
void deleteNativeDialog_sys(); void deleteNativeDialog_sys();
QDialog::DialogCode dialogResultCode_sys(); QDialog::DialogCode dialogResultCode_sys();
@ -289,6 +291,8 @@ public:
~QFileDialogPrivate(); ~QFileDialogPrivate();
private: private:
virtual void initHelper(QPlatformDialogHelper *);
Q_DISABLE_COPY(QFileDialogPrivate) Q_DISABLE_COPY(QFileDialogPrivate)
}; };
@ -344,6 +348,16 @@ private:
QFileDialogPrivate *d_ptr; 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 { inline QModelIndex QFileDialogPrivate::mapToSource(const QModelIndex &index) const {
#ifdef QT_NO_PROXYMODEL #ifdef QT_NO_PROXYMODEL
return index; return index;
@ -366,71 +380,68 @@ inline QString QFileDialogPrivate::rootPath() const {
// Dummies for platforms that don't use native dialogs: // Dummies for platforms that don't use native dialogs:
inline void QFileDialogPrivate::deleteNativeDialog_sys() inline void QFileDialogPrivate::deleteNativeDialog_sys()
{ {
if (QPlatformDialogHelper *helper = platformHelper()) if (QPlatformFileDialogHelper *helper = platformFileDialogHelper()) {
helper->deleteNativeDialog_sys(); helper->deleteNativeDialog_sys();
} nativeDialogInUse = false;
}
inline bool QFileDialogPrivate::setVisible_sys(bool visible)
{
if (QPlatformDialogHelper *helper = platformHelper())
return helper->setVisible_sys(visible);
return false;
} }
inline QDialog::DialogCode QFileDialogPrivate::dialogResultCode_sys() inline QDialog::DialogCode QFileDialogPrivate::dialogResultCode_sys()
{ {
QDialog::DialogCode result = QDialog::Rejected;
if (QPlatformDialogHelper *helper = platformHelper()) if (QPlatformDialogHelper *helper = platformHelper())
return helper->dialogResultCode_sys(); if (helper->dialogResultCode_sys() == QPlatformDialogHelper::Accepted)
return QDialog::Rejected; result = QDialog::Accepted;
return result;
} }
inline void QFileDialogPrivate::setDirectory_sys(const QString &directory) inline void QFileDialogPrivate::setDirectory_sys(const QString &directory)
{ {
if (QPlatformDialogHelper *helper = platformHelper()) if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
helper->setDirectory_sys(directory); helper->setDirectory_sys(directory);
} }
inline QString QFileDialogPrivate::directory_sys() const inline QString QFileDialogPrivate::directory_sys() const
{ {
if (QPlatformDialogHelper *helper = platformHelper()) if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
return helper->directory_sys(); return helper->directory_sys();
return QString(); return QString();
} }
inline void QFileDialogPrivate::selectFile_sys(const QString &filename) inline void QFileDialogPrivate::selectFile_sys(const QString &filename)
{ {
if (QPlatformDialogHelper *helper = platformHelper()) if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
helper->selectFile_sys(filename); helper->selectFile_sys(filename);
} }
inline QStringList QFileDialogPrivate::selectedFiles_sys() const inline QStringList QFileDialogPrivate::selectedFiles_sys() const
{ {
if (QPlatformDialogHelper *helper = platformHelper()) if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
return helper->selectedFiles_sys(); return helper->selectedFiles_sys();
return QStringList(); return QStringList();
} }
inline void QFileDialogPrivate::setFilter_sys() inline void QFileDialogPrivate::setFilter_sys()
{ {
if (QPlatformDialogHelper *helper = platformHelper()) if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
helper->setFilter_sys(); helper->setFilter_sys();
} }
inline void QFileDialogPrivate::setNameFilters_sys(const QStringList &filters) inline void QFileDialogPrivate::setNameFilters_sys(const QStringList &filters)
{ {
if (QPlatformDialogHelper *helper = platformHelper()) if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
helper->setNameFilters_sys(filters); helper->setNameFilters_sys(filters);
} }
inline void QFileDialogPrivate::selectNameFilter_sys(const QString &filter) inline void QFileDialogPrivate::selectNameFilter_sys(const QString &filter)
{ {
if (QPlatformDialogHelper *helper = platformHelper()) if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
helper->selectNameFilter_sys(filter); helper->selectNameFilter_sys(filter);
} }
inline QString QFileDialogPrivate::selectedNameFilter_sys() const inline QString QFileDialogPrivate::selectedNameFilter_sys() const
{ {
if (QPlatformDialogHelper *helper = platformHelper()) if (QPlatformFileDialogHelper *helper = platformFileDialogHelper())
return helper->selectedNameFilter_sys(); return helper->selectedNameFilter_sys();
return QString(); return QString();
} }

View File

@ -490,6 +490,13 @@ bool QFontDialog::eventFilter(QObject *o , QEvent *e)
return QDialog::eventFilter(o, 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 Updates the contents of the "font family" list box. This
function can be reimplemented if you have special requirements. 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->strikeout->setChecked(font.strikeOut());
d->underline->setChecked(font.underline()); d->underline->setChecked(font.underline());
d->updateFamilies(); d->updateFamilies();
if (QPlatformFontDialogHelper *helper = d->platformFontDialogHelper())
helper->setCurrentFont_sys(font);
#ifdef Q_WS_MAC #ifdef Q_WS_MAC
if (d->delegate) if (d->delegate)
@ -836,6 +845,8 @@ void QFontDialog::setCurrentFont(const QFont &font)
QFont QFontDialog::currentFont() const QFont QFontDialog::currentFont() const
{ {
Q_D(const QFontDialog); Q_D(const QFontDialog);
if (const QPlatformFontDialogHelper *helper = d->platformFontDialogHelper())
return helper->currentFont_sys();
return d->sampleEdit->font(); return d->sampleEdit->font();
} }
@ -985,8 +996,7 @@ void QFontDialog::setVisible(bool visible)
return; return;
Q_D(QFontDialog); Q_D(QFontDialog);
if (d->canBeNativeDialog()) if (d->canBeNativeDialog())
if (QPlatformDialogHelper *helper = d->platformHelper()) d->setNativeDialogVisible(visible);
d->nativeDialogInUse = helper->setVisible_sys(visible);
if (d->nativeDialogInUse) { if (d->nativeDialogInUse) {
// Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
// updates the state correctly, but skips showing the non-native version: // updates the state correctly, but skips showing the non-native version:

View File

@ -57,6 +57,7 @@
#include "private/qdialog_p.h" #include "private/qdialog_p.h"
#include "qfontdatabase.h" #include "qfontdatabase.h"
#include "qfontdialog.h" #include "qfontdialog.h"
#include "qplatformdialoghelper_qpa.h"
#ifndef QT_NO_FONTDIALOG #ifndef QT_NO_FONTDIALOG
@ -80,6 +81,9 @@ public:
: writingSystem(QFontDatabase::Any) : writingSystem(QFontDatabase::Any)
{ } { }
QPlatformFontDialogHelper *platformFontDialogHelper() const
{ return static_cast<QPlatformFontDialogHelper *>(platformHelper()); }
void updateFamilies(); void updateFamilies();
void updateStyles(); void updateStyles();
void updateSizes(); void updateSizes();
@ -156,6 +160,9 @@ public:
static bool sharedFontPanelAvailable; static bool sharedFontPanelAvailable;
#endif #endif
private:
virtual void initHelper(QPlatformDialogHelper *);
}; };
#endif // QT_NO_FONTDIALOG #endif // QT_NO_FONTDIALOG

View File

@ -41,11 +41,50 @@
#include "qplatformdialoghelper_qpa.h" #include "qplatformdialoghelper_qpa.h"
QPlatformDialogHelper::QPlatformDialogHelper() : #include <QtCore/QVariant>
d_ptr(0)
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() 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

View File

@ -43,7 +43,7 @@
#define QPLATFORMDIALOGHELPER_H #define QPLATFORMDIALOGHELPER_H
#include <qglobal.h> #include <qglobal.h>
#include <qdialog.h> #include <qobject.h>
QT_BEGIN_HEADER QT_BEGIN_HEADER
@ -52,23 +52,66 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui) QT_MODULE(Gui)
class QString; 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: public:
enum StyleHint {
SnapToDefaultButton
};
enum DialogCode { Rejected, Accepted };
QPlatformDialogHelper(); QPlatformDialogHelper();
virtual ~QPlatformDialogHelper(); virtual ~QPlatformDialogHelper();
virtual QVariant styleHint(StyleHint hint) const;
virtual void platformNativeDialogModalHelp() = 0; virtual void platformNativeDialogModalHelp() = 0;
virtual void _q_platformRunNativeAppModalPanel() = 0; virtual void _q_platformRunNativeAppModalPanel() = 0;
virtual bool defaultNameFilterDisables() const = 0;
virtual void deleteNativeDialog_sys() = 0; virtual void deleteNativeDialog_sys() = 0;
virtual bool setVisible_sys(bool visible) = 0; virtual bool show_sys(QWindow *parent) = 0;
virtual QDialog::DialogCode dialogResultCode_sys() = 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 void setDirectory_sys(const QString &directory) = 0;
virtual QString directory_sys() const = 0; virtual QString directory_sys() const = 0;
virtual void selectFile_sys(const QString &filename) = 0; virtual void selectFile_sys(const QString &filename) = 0;
@ -78,7 +121,12 @@ public:
virtual void selectNameFilter_sys(const QString &filter) = 0; virtual void selectNameFilter_sys(const QString &filter) = 0;
virtual QString selectedNameFilter_sys() const = 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 QT_END_NAMESPACE