diff options
Diffstat (limited to 'src/widgets')
29 files changed, 899 insertions, 335 deletions
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index e8b6218299..d45f623b8d 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -379,7 +379,6 @@ QFileDialog::QFileDialog(QWidget *parent, Qt::WindowFlags f) { Q_D(QFileDialog); d->init(); - d->lineEdit()->selectAll(); } /*! @@ -397,7 +396,6 @@ QFileDialog::QFileDialog(QWidget *parent, { Q_D(QFileDialog); d->init(directory, filter, caption); - d->lineEdit()->selectAll(); } /*! @@ -411,7 +409,6 @@ QFileDialog::QFileDialog(const QFileDialogArgs &args) setFileMode(args.mode); setOptions(args.options); selectFile(args.selection); - d->lineEdit()->selectAll(); } /*! @@ -443,7 +440,8 @@ QFileDialog::~QFileDialog() void QFileDialog::setSidebarUrls(const QList<QUrl> &urls) { Q_D(QFileDialog); - d->qFileDialogUi->sidebar->setUrls(urls); + if (!d->nativeDialogInUse) + d->qFileDialogUi->sidebar->setUrls(urls); } /*! @@ -453,7 +451,7 @@ void QFileDialog::setSidebarUrls(const QList<QUrl> &urls) QList<QUrl> QFileDialog::sidebarUrls() const { Q_D(const QFileDialog); - return d->qFileDialogUi->sidebar->urls(); + return (d->nativeDialogInUse ? QList<QUrl>() : d->qFileDialogUi->sidebar->urls()); } static const qint32 QFileDialogMagic = 0xbe; @@ -474,11 +472,19 @@ QByteArray QFileDialog::saveState() const stream << qint32(QFileDialogMagic); stream << qint32(version); - stream << d->qFileDialogUi->splitter->saveState(); - stream << d->qFileDialogUi->sidebar->urls(); + if (d->usingWidgets()) { + stream << d->qFileDialogUi->splitter->saveState(); + stream << d->qFileDialogUi->sidebar->urls(); + } else { + stream << QByteArray(); + stream << QList<QUrl>(); + } stream << history(); stream << *lastVisitedDir(); - stream << d->qFileDialogUi->treeView->header()->saveState(); + if (d->usingWidgets()) + stream << d->qFileDialogUi->treeView->header()->saveState(); + else + stream << QByteArray(); stream << qint32(viewMode()); return data; } @@ -520,6 +526,12 @@ bool QFileDialog::restoreState(const QByteArray &state) >> headerData >> viewMode; + setDirectory(lastVisitedDir()->isEmpty() ? currentDirectory : *lastVisitedDir()); + setViewMode(static_cast<QFileDialog::ViewMode>(viewMode)); + + if (!d->usingWidgets()) + return true; + if (!d->qFileDialogUi->splitter->restoreState(splitterState)) return false; QList<int> list = d->qFileDialogUi->splitter->sizes(); @@ -533,7 +545,6 @@ bool QFileDialog::restoreState(const QByteArray &state) while (history.count() > 5) history.pop_front(); setHistory(history); - setDirectory(lastVisitedDir()->isEmpty() ? currentDirectory : *lastVisitedDir()); QHeaderView *headerView = d->qFileDialogUi->treeView->header(); if (!headerView->restoreState(headerData)) return false; @@ -548,7 +559,6 @@ bool QFileDialog::restoreState(const QByteArray &state) for (int i = 1; i < total; ++i) actions.at(i - 1)->setChecked(!headerView->isSectionHidden(i)); - setViewMode(ViewMode(viewMode)); return true; } @@ -595,15 +605,16 @@ void QFileDialogPrivate::initHelper(QPlatformDialogHelper *h) QObject::connect(h, SIGNAL(directoryEntered(QUrl)), d, SLOT(_q_nativeEnterDirectory(QUrl))); QObject::connect(h, SIGNAL(filterSelected(QString)), d, SIGNAL(filterSelected(QString))); static_cast<QPlatformFileDialogHelper *>(h)->setOptions(options); + nativeDialogInUse = true; } void QFileDialogPrivate::helperPrepareShow(QPlatformDialogHelper *) { Q_Q(QFileDialog); options->setWindowTitle(q->windowTitle()); - options->setViewMode(static_cast<QFileDialogOptions::ViewMode>(q->viewMode())); options->setHistory(q->history()); - options->setSidebarUrls(qFileDialogUi->sidebar->urls()); + if (usingWidgets()) + options->setSidebarUrls(qFileDialogUi->sidebar->urls()); const QDir directory = q->directory(); options->setInitialDirectory(directory.exists() ? QUrl::fromLocalFile(directory.absolutePath()) : @@ -644,9 +655,17 @@ void QFileDialogPrivate::setLastVisitedDirectory(const QString &dir) *lastVisitedDir() = dir; } +void QFileDialogPrivate::updateLookInLabel() +{ + if (options->isLabelExplicitlySet(QFileDialogOptions::LookIn)) + setLabelTextControl(QFileDialog::LookIn, options->labelText(QFileDialogOptions::LookIn)); +} + void QFileDialogPrivate::updateFileNameLabel() { - if (!options->isLabelExplicitlySet(QFileDialogOptions::FileName)) { + if (options->isLabelExplicitlySet(QFileDialogOptions::FileName)) { + setLabelTextControl(QFileDialog::FileName, options->labelText(QFileDialogOptions::FileName)); + } else { switch (q_func()->fileMode()) { case QFileDialog::DirectoryOnly: case QFileDialog::Directory: @@ -659,6 +678,12 @@ void QFileDialogPrivate::updateFileNameLabel() } } +void QFileDialogPrivate::updateFileTypeLabel() +{ + if (options->isLabelExplicitlySet(QFileDialogOptions::FileType)) + setLabelTextControl(QFileDialog::FileType, options->labelText(QFileDialogOptions::FileType)); +} + void QFileDialogPrivate::updateOkButtonText(bool saveAsOnFolder) { Q_Q(QFileDialog); @@ -684,12 +709,20 @@ void QFileDialogPrivate::updateOkButtonText(bool saveAsOnFolder) } } +void QFileDialogPrivate::updateCancelButtonText() +{ + if (options->isLabelExplicitlySet(QFileDialogOptions::Reject)) + setLabelTextControl(QFileDialog::Reject, options->labelText(QFileDialogOptions::Reject)); +} + void QFileDialogPrivate::retranslateStrings() { Q_Q(QFileDialog); /* WIDGETS */ if (defaultFileTypes) q->setNameFilter(QFileDialog::tr("All Files (*)")); + if (nativeDialogInUse) + return; QList<QAction*> actions = qFileDialogUi->treeView->header()->actions(); QAbstractItemModel *abstractModel = model; @@ -708,7 +741,10 @@ void QFileDialogPrivate::retranslateStrings() showHiddenAction->setText(QFileDialog::tr("Show &hidden files")); newFolderAction->setText(QFileDialog::tr("&New Folder")); qFileDialogUi->retranslateUi(q); + updateLookInLabel(); updateFileNameLabel(); + updateFileTypeLabel(); + updateCancelButtonText(); } void QFileDialogPrivate::emitFilesSelected(const QStringList &files) @@ -734,6 +770,11 @@ bool QFileDialogPrivate::canBeNativeDialog() return (staticName == dynamicName); } +bool QFileDialogPrivate::usingWidgets() const +{ + return !nativeDialogInUse && qFileDialogUi; +} + /*! \since 4.5 Sets the given \a option to be enabled if \a on is true; otherwise, @@ -784,29 +825,36 @@ void QFileDialog::setOptions(Options options) return; d->options->setOptions(QFileDialogOptions::FileDialogOptions(int(options))); - if (changed & DontResolveSymlinks) - d->model->setResolveSymlinks(!(options & DontResolveSymlinks)); - if (changed & ReadOnly) { - bool ro = (options & ReadOnly); - d->model->setReadOnly(ro); - d->qFileDialogUi->newFolderButton->setEnabled(!ro); - d->renameAction->setEnabled(!ro); - d->deleteAction->setEnabled(!ro); + + if ((options & DontUseNativeDialog) && !d->usingWidgets()) + d->createWidgets(); + + if (d->usingWidgets()) { + if (changed & DontResolveSymlinks) + d->model->setResolveSymlinks(!(options & DontResolveSymlinks)); + if (changed & ReadOnly) { + bool ro = (options & ReadOnly); + d->model->setReadOnly(ro); + d->qFileDialogUi->newFolderButton->setEnabled(!ro); + d->renameAction->setEnabled(!ro); + d->deleteAction->setEnabled(!ro); + } + + if (changed & DontUseCustomDirectoryIcons) { + QFileIconProvider::Options providerOptions = iconProvider()->options(); + if (options & DontUseCustomDirectoryIcons) + providerOptions |= QFileIconProvider::DontUseCustomDirectoryIcons; + else + providerOptions &= ~QFileIconProvider::DontUseCustomDirectoryIcons; + iconProvider()->setOptions(providerOptions); + } } + if (changed & HideNameFilterDetails) setNameFilters(d->options->nameFilters()); if (changed & ShowDirsOnly) setFilter((options & ShowDirsOnly) ? filter() & ~QDir::Files : filter() | QDir::Files); - - if (changed & DontUseCustomDirectoryIcons) { - QFileIconProvider::Options providerOptions = iconProvider()->options(); - if (options & DontUseCustomDirectoryIcons) - providerOptions |= QFileIconProvider::DontUseCustomDirectoryIcons; - else - providerOptions &= ~QFileIconProvider::DontUseCustomDirectoryIcons; - iconProvider()->setOptions(providerOptions); - } } QFileDialog::Options QFileDialog::options() const @@ -858,21 +906,25 @@ void QFileDialog::setVisible(bool visible) // updates the state correctly, but skips showing the non-native version: setAttribute(Qt::WA_DontShowOnScreen); #ifndef QT_NO_FSCOMPLETER - //So the completer don't try to complete and therefore to show a popup - d->completer->setModel(0); + // So the completer doesn't try to complete and therefore show a popup + if (!d->nativeDialogInUse) + d->completer->setModel(0); #endif } else { + d->createWidgets(); setAttribute(Qt::WA_DontShowOnScreen, false); #ifndef QT_NO_FSCOMPLETER - if (d->proxyModel != 0) - d->completer->setModel(d->proxyModel); - else - d->completer->setModel(d->model); + if (!d->nativeDialogInUse) { + if (d->proxyModel != 0) + d->completer->setModel(d->proxyModel); + else + d->completer->setModel(d->model); + } #endif } } - if (!d->nativeDialogInUse) + if (d->usingWidgets()) d->qFileDialogUi->fileNameEdit->setFocus(); QDialog::setVisible(visible); @@ -914,24 +966,27 @@ void QFileDialog::setDirectory(const QString &directory) d->setLastVisitedDirectory(newDirectory); - if (d->nativeDialogInUse){ + d->options->setInitialDirectory(QUrl::fromLocalFile(directory)); + if (!d->usingWidgets()) { d->setDirectory_sys(QUrl::fromLocalFile(newDirectory)); return; } if (d->rootPath() == newDirectory) return; QModelIndex root = d->model->setRootPath(newDirectory); - d->qFileDialogUi->newFolderButton->setEnabled(d->model->flags(root) & Qt::ItemIsDropEnabled); - if (root != d->rootIndex()) { + if (!d->nativeDialogInUse) { + d->qFileDialogUi->newFolderButton->setEnabled(d->model->flags(root) & Qt::ItemIsDropEnabled); + if (root != d->rootIndex()) { #ifndef QT_NO_FSCOMPLETER - if (directory.endsWith(QLatin1Char('/'))) - d->completer->setCompletionPrefix(newDirectory); - else - d->completer->setCompletionPrefix(newDirectory + QLatin1Char('/')); + if (directory.endsWith(QLatin1Char('/'))) + d->completer->setCompletionPrefix(newDirectory); + else + d->completer->setCompletionPrefix(newDirectory + QLatin1Char('/')); #endif - d->setRootIndex(root); + d->setRootIndex(root); + } + d->qFileDialogUi->listView->selectionModel()->clear(); } - d->qFileDialogUi->listView->selectionModel()->clear(); } /*! @@ -989,8 +1044,11 @@ void QFileDialog::selectFile(const QString &filename) if (filename.isEmpty()) return; - if (d->nativeDialogInUse){ + if (!d->usingWidgets()) { d->selectFile_sys(QUrl::fromLocalFile(filename)); + QList<QUrl> i; + i << QUrl(filename); + d->options->setInitiallySelectedFiles(i); return; } @@ -1141,7 +1199,7 @@ QList<QUrl> QFileDialogPrivate::userSelectedFiles() const { QList<QUrl> files; - if (nativeDialogInUse) + if (!usingWidgets()) return addDefaultSuffixToUrls(selectedFiles_sys()); foreach (const QModelIndex &index, qFileDialogUi->listView->selectionModel()->selectedRows()) @@ -1339,6 +1397,9 @@ void QFileDialog::setNameFilters(const QStringList &filters) } d->options->setNameFilters(cleanedFilters); + if (!d->usingWidgets()) + return; + d->qFileDialogUi->fileTypeCombo->clear(); if (cleanedFilters.isEmpty()) return; @@ -1373,7 +1434,7 @@ QStringList QFileDialog::nameFilters() const void QFileDialog::selectNameFilter(const QString &filter) { Q_D(QFileDialog); - if (d->nativeDialogInUse) { + if (!d->usingWidgets()) { d->selectNameFilter_sys(filter); return; } @@ -1401,7 +1462,7 @@ void QFileDialog::selectNameFilter(const QString &filter) QString QFileDialog::selectedNameFilter() const { Q_D(const QFileDialog); - if (d->nativeDialogInUse) + if (!d->usingWidgets()) return d->selectedNameFilter_sys(); return d->qFileDialogUi->fileTypeCombo->currentText(); @@ -1417,7 +1478,9 @@ QString QFileDialog::selectedNameFilter() const QDir::Filters QFileDialog::filter() const { Q_D(const QFileDialog); - return d->model->filter(); + if (d->usingWidgets()) + return d->model->filter(); + return d->options->filter(); } /*! @@ -1432,13 +1495,13 @@ QDir::Filters QFileDialog::filter() const void QFileDialog::setFilter(QDir::Filters filters) { Q_D(QFileDialog); - d->model->setFilter(filters); d->options->setFilter(filters); - if (d->nativeDialogInUse){ + if (!d->usingWidgets()) { d->setFilter_sys(); return; } + d->model->setFilter(filters); d->showHiddenAction->setChecked((filters & QDir::Hidden)); } @@ -1523,6 +1586,9 @@ void QFileDialog::selectMimeTypeFilter(const QString &filter) void QFileDialog::setViewMode(QFileDialog::ViewMode mode) { Q_D(QFileDialog); + d->options->setViewMode(static_cast<QFileDialogOptions::ViewMode>(mode)); + if (!d->usingWidgets()) + return; if (mode == Detail) d->_q_showDetailsView(); else @@ -1532,6 +1598,8 @@ void QFileDialog::setViewMode(QFileDialog::ViewMode mode) QFileDialog::ViewMode QFileDialog::viewMode() const { Q_D(const QFileDialog); + if (!d->usingWidgets()) + return QFileDialog::List; return (d->qFileDialogUi->stackedWidget->currentWidget() == d->qFileDialogUi->listView->parent() ? QFileDialog::List : QFileDialog::Detail); } @@ -1554,11 +1622,15 @@ void QFileDialog::setFileMode(QFileDialog::FileMode mode) { Q_D(QFileDialog); d->options->setFileMode(static_cast<QFileDialogOptions::FileMode>(mode)); - d->retranslateWindowTitle(); // keep ShowDirsOnly option in sync with fileMode (BTW, DirectoryOnly is obsolete) setOption(ShowDirsOnly, mode == DirectoryOnly); + if (!d->usingWidgets()) + return; + + d->retranslateWindowTitle(); + // set selection mode and behavior QAbstractItemView::SelectionMode selectionMode; if (mode == QFileDialog::ExistingFiles) @@ -1577,11 +1649,6 @@ void QFileDialog::setFileMode(QFileDialog::FileMode mode) } d->updateFileNameLabel(); d->updateOkButtonText(); - if (d->nativeDialogInUse){ - d->setFilter_sys(); - return; - } - d->qFileDialogUi->fileTypeCombo->setEnabled(!testOption(ShowDirsOnly)); d->_q_updateOkButton(); } @@ -1606,6 +1673,13 @@ void QFileDialog::setAcceptMode(QFileDialog::AcceptMode mode) { Q_D(QFileDialog); d->options->setAcceptMode(static_cast<QFileDialogOptions::AcceptMode>(mode)); + // clear WA_DontShowOnScreen so that d->canBeNativeDialog() doesn't return false incorrectly + setAttribute(Qt::WA_DontShowOnScreen, false); + if (!d->usingWidgets()) { + // we need to recreate the native dialog when changing the AcceptMode + d->deletePlatformHelper(); + return; + } QDialogButtonBox::StandardButton button = (mode == AcceptOpen ? QDialogButtonBox::Open : QDialogButtonBox::Save); d->qFileDialogUi->buttonBox->setStandardButtons(button | QDialogButtonBox::Cancel); d->qFileDialogUi->buttonBox->button(button)->setEnabled(false); @@ -1614,10 +1688,6 @@ void QFileDialog::setAcceptMode(QFileDialog::AcceptMode mode) d->qFileDialogUi->lookInCombo->setEditable(false); } d->retranslateWindowTitle(); - // we need to recreate the native dialog when changing the AcceptMode - d->deletePlatformHelper(); - // clear WA_DontShowOnScreen so that d->canBeNativeDialog() doesn't return false incorrectly - setAttribute(Qt::WA_DontShowOnScreen, false); } /* @@ -1778,7 +1848,8 @@ QString QFileDialog::defaultSuffix() const void QFileDialog::setHistory(const QStringList &paths) { Q_D(QFileDialog); - d->qFileDialogUi->lookInCombo->setHistory(paths); + if (d->usingWidgets()) + d->qFileDialogUi->lookInCombo->setHistory(paths); } void QFileDialogComboBox::setHistory(const QStringList &paths) @@ -1800,6 +1871,8 @@ void QFileDialogComboBox::setHistory(const QStringList &paths) QStringList QFileDialog::history() const { Q_D(const QFileDialog); + if (!d->usingWidgets()) + return QStringList(); QStringList currentHistory = d->qFileDialogUi->lookInCombo->history(); //On windows the popup display the "C:\", convert to nativeSeparators QString newHistory = QDir::toNativeSeparators(d->rootIndex().data(QFileSystemModel::FilePathRole).toString()); @@ -1826,6 +1899,8 @@ QStringList QFileDialog::history() const void QFileDialog::setItemDelegate(QAbstractItemDelegate *delegate) { Q_D(QFileDialog); + if (!d->usingWidgets()) + return; d->qFileDialogUi->listView->setItemDelegate(delegate); d->qFileDialogUi->treeView->setItemDelegate(delegate); } @@ -1836,6 +1911,8 @@ void QFileDialog::setItemDelegate(QAbstractItemDelegate *delegate) QAbstractItemDelegate *QFileDialog::itemDelegate() const { Q_D(const QFileDialog); + if (!d->usingWidgets()) + return 0; return d->qFileDialogUi->listView->itemDelegate(); } @@ -1845,6 +1922,8 @@ QAbstractItemDelegate *QFileDialog::itemDelegate() const void QFileDialog::setIconProvider(QFileIconProvider *provider) { Q_D(QFileDialog); + if (!d->usingWidgets()) + return; d->model->setIconProvider(provider); //It forces the refresh of all entries in the side bar, then we can get new icons d->qFileDialogUi->sidebar->setUrls(d->qFileDialogUi->sidebar->urls()); @@ -1861,6 +1940,8 @@ QFileIconProvider *QFileDialog::iconProvider() const void QFileDialogPrivate::setLabelTextControl(QFileDialog::DialogLabel label, const QString &text) { + if (!qFileDialogUi) + return; switch (label) { case QFileDialog::LookIn: qFileDialogUi->lookInLabel->setText(text); @@ -1903,8 +1984,10 @@ void QFileDialog::setLabelText(DialogLabel label, const QString &text) */ QString QFileDialog::labelText(DialogLabel label) const { - QPushButton *button; Q_D(const QFileDialog); + if (!d->usingWidgets()) + return d->options->labelText(static_cast<QFileDialogOptions::DialogLabel>(label)); + QPushButton *button; switch (label) { case LookIn: return d->qFileDialogUi->lookInLabel->text(); @@ -2518,7 +2601,7 @@ void QFileDialog::accept() QStringList files = selectedFiles(); if (files.isEmpty()) return; - if (d->nativeDialogInUse){ + if (!d->usingWidgets()) { d->emitFilesSelected(files); QDialog::accept(); return; @@ -2631,16 +2714,19 @@ void QFileDialogPrivate::init(const QString &directory, const QString &nameFilte q->setWindowTitle(caption); } - createWidgets(); - createMenuActions(); - retranslateStrings(); + q->setAcceptMode(QFileDialog::AcceptOpen); + nativeDialogInUse = (canBeNativeDialog() && platformFileDialogHelper() != 0); + if (!nativeDialogInUse) + createWidgets(); q->setFileMode(QFileDialog::AnyFile); + if (!nameFilter.isEmpty()) + q->setNameFilter(nameFilter); + q->setDirectory(workingDirectory(directory)); + q->selectFile(initialSelection(directory)); #ifndef QT_NO_SETTINGS QSettings settings(QSettings::UserScope, QLatin1String("QtProject")); settings.beginGroup(QLatin1String("Qt")); - if (!directory.isEmpty()) - setLastVisitedDirectory(workingDirectory(directory)); q->restoreState(settings.value(QLatin1String("filedialog")).toByteArray()); #endif @@ -2650,14 +2736,7 @@ void QFileDialogPrivate::init(const QString &directory, const QString &nameFilte qFileDialogUi->fileTypeLabel->setVisible(false); qFileDialogUi->sidebar->hide(); #endif - // Default case - if (!nameFilter.isEmpty()) - q->setNameFilter(nameFilter); - q->setAcceptMode(QFileDialog::AcceptOpen); - q->setDirectory(workingDirectory(directory)); - q->selectFile(initialSelection(directory)); - _q_updateOkButton(); q->resize(q->sizeHint()); } @@ -2668,6 +2747,8 @@ void QFileDialogPrivate::init(const QString &directory, const QString &nameFilte */ void QFileDialogPrivate::createWidgets() { + if (qFileDialogUi) + return; Q_Q(QFileDialog); model = new QFileSystemModel(q); options->setFilter(model->filter()); @@ -2676,6 +2757,8 @@ void QFileDialogPrivate::createWidgets() model->setNameFilterDisables(helper->defaultNameFilterDisables()); else model->setNameFilterDisables(false); + if (nativeDialogInUse) + deletePlatformHelper(); model->d_func()->disableRecursiveSort = true; QFileDialog::connect(model, SIGNAL(fileRenamed(QString,QString,QString)), q, SLOT(_q_fileRenamed(QString,QString,QString))); QFileDialog::connect(model, SIGNAL(rootPathChanged(QString)), @@ -2789,6 +2872,31 @@ void QFileDialogPrivate::createWidgets() qFileDialogUi->splitter->setStretchFactor(qFileDialogUi->splitter->indexOf(qFileDialogUi->splitter->widget(1)), QSizePolicy::Expanding); createToolButtons(); + createMenuActions(); + + // Initial widget states from options + q->setFileMode(static_cast<QFileDialog::FileMode>(options->fileMode())); + q->setAcceptMode(static_cast<QFileDialog::AcceptMode>(options->acceptMode())); + q->setViewMode(static_cast<QFileDialog::ViewMode>(options->viewMode())); + q->setOptions(static_cast<QFileDialog::Options>(static_cast<int>(options->options()))); + if (!options->sidebarUrls().isEmpty()) + q->setSidebarUrls(options->sidebarUrls()); + q->setDirectoryUrl(options->initialDirectory()); + if (!options->mimeTypeFilters().isEmpty()) + q->setMimeTypeFilters(options->mimeTypeFilters()); + else if (!options->nameFilters().isEmpty()) + q->setNameFilters(options->nameFilters()); + q->selectNameFilter(options->initiallySelectedNameFilter()); + q->setDefaultSuffix(options->defaultSuffix()); + q->setHistory(options->history()); + if (options->initiallySelectedFiles().count() == 1) + q->selectFile(options->initiallySelectedFiles().first().fileName()); + foreach (QUrl url, options->initiallySelectedFiles()) + q->selectUrl(url); + lineEdit()->selectAll(); + _q_updateOkButton(); + retranslateStrings(); + q->resize(q->sizeHint()); } void QFileDialogPrivate::_q_showHeader(QAction *action) @@ -2814,6 +2922,8 @@ void QFileDialogPrivate::_q_showHeader(QAction *action) void QFileDialog::setProxyModel(QAbstractProxyModel *proxyModel) { Q_D(QFileDialog); + if (!d->usingWidgets()) + return; if ((!proxyModel && !d->proxyModel) || (proxyModel == d->proxyModel)) return; diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h index e5a558bb91..36336bdbf6 100644 --- a/src/widgets/dialogs/qfiledialog_p.h +++ b/src/widgets/dialogs/qfiledialog_p.h @@ -135,8 +135,11 @@ public: QList<QUrl> addDefaultSuffixToUrls(const QList<QUrl> &urlsToFix) const; bool removeDirectory(const QString &path); void setLabelTextControl(QFileDialog::DialogLabel label, const QString &text); + inline void updateLookInLabel(); inline void updateFileNameLabel(); + inline void updateFileTypeLabel(); void updateOkButtonText(bool saveAsOnFolder = false); + void updateCancelButtonText(); inline QModelIndex mapToSource(const QModelIndex &index) const; inline QModelIndex mapFromSource(const QModelIndex &index) const; @@ -249,6 +252,7 @@ public: // dialog. Returning false means that a non-native dialog must be // used instead. bool canBeNativeDialog(); + inline bool usingWidgets() const; void setDirectory_sys(const QUrl &directory); QUrl directory_sys() const; @@ -347,7 +351,7 @@ inline QModelIndex QFileDialogPrivate::mapFromSource(const QModelIndex &index) c } inline QString QFileDialogPrivate::rootPath() const { - return model->rootPath(); + return (model ? model->rootPath() : QStringLiteral("/")); } inline void QFileDialogPrivate::setDirectory_sys(const QUrl &directory) diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index 6dcc354f94..bda448bde3 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -204,6 +204,8 @@ bool QFileSystemModel::remove(const QModelIndex &aindex) #ifndef QT_NO_FILESYSTEMWATCHER d->fileInfoGatherer.removePath(path); #endif + if (QFileInfo(path).isFile()) + return QFile::remove(path); return QDir(path).removeRecursively(); } diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.cpp b/src/widgets/graphicsview/qgraphicsitemanimation.cpp index 5dc3e1159e..ff98c147fe 100644 --- a/src/widgets/graphicsview/qgraphicsitemanimation.cpp +++ b/src/widgets/graphicsview/qgraphicsitemanimation.cpp @@ -97,6 +97,15 @@ QT_BEGIN_NAMESPACE +static inline bool check_step_valid(qreal step, const char *method) +{ + if (!(step >= 0 && step <= 1)) { + qWarning("QGraphicsItemAnimation::%s: invalid step = %f", method, step); + return false; + } + return true; +} + class QGraphicsItemAnimationPrivate { public: @@ -169,10 +178,8 @@ qreal QGraphicsItemAnimationPrivate::linearValueForStep(qreal step, QList<Pair> void QGraphicsItemAnimationPrivate::insertUniquePair(qreal step, qreal value, QList<Pair> *binList, const char* method) { - if (step < 0.0 || step > 1.0) { - qWarning("QGraphicsItemAnimation::%s: invalid step = %f", method, step); + if (!check_step_valid(step, method)) return; - } Pair pair(step, value); @@ -259,9 +266,7 @@ void QGraphicsItemAnimation::setTimeLine(QTimeLine *timeLine) */ QPointF QGraphicsItemAnimation::posAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::posAt: invalid step = %f", step); - + check_step_valid(step, "posAt"); return QPointF(d->linearValueForStep(step, &d->xPosition, d->startPos.x()), d->linearValueForStep(step, &d->yPosition, d->startPos.y())); } @@ -298,8 +303,7 @@ QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::posList() const */ QMatrix QGraphicsItemAnimation::matrixAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::matrixAt: invalid step = %f", step); + check_step_valid(step, "matrixAt"); QMatrix matrix; if (!d->rotation.isEmpty()) @@ -320,9 +324,7 @@ QMatrix QGraphicsItemAnimation::matrixAt(qreal step) const */ qreal QGraphicsItemAnimation::rotationAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::rotationAt: invalid step = %f", step); - + check_step_valid(step, "rotationAt"); return d->linearValueForStep(step, &d->rotation); } @@ -357,9 +359,7 @@ QList<QPair<qreal, qreal> > QGraphicsItemAnimation::rotationList() const */ qreal QGraphicsItemAnimation::xTranslationAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::xTranslationAt: invalid step = %f", step); - + check_step_valid(step, "xTranslationAt"); return d->linearValueForStep(step, &d->xTranslation); } @@ -370,9 +370,7 @@ qreal QGraphicsItemAnimation::xTranslationAt(qreal step) const */ qreal QGraphicsItemAnimation::yTranslationAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::yTranslationAt: invalid step = %f", step); - + check_step_valid(step, "yTranslationAt"); return d->linearValueForStep(step, &d->yTranslation); } @@ -409,8 +407,7 @@ QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::translationList() const */ qreal QGraphicsItemAnimation::verticalScaleAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::verticalScaleAt: invalid step = %f", step); + check_step_valid(step, "verticalScaleAt"); return d->linearValueForStep(step, &d->verticalScale, 1); } @@ -422,9 +419,7 @@ qreal QGraphicsItemAnimation::verticalScaleAt(qreal step) const */ qreal QGraphicsItemAnimation::horizontalScaleAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::horizontalScaleAt: invalid step = %f", step); - + check_step_valid(step, "horizontalScaleAt"); return d->linearValueForStep(step, &d->horizontalScale, 1); } @@ -461,9 +456,7 @@ QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::scaleList() const */ qreal QGraphicsItemAnimation::verticalShearAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::verticalShearAt: invalid step = %f", step); - + check_step_valid(step, "verticalShearAt"); return d->linearValueForStep(step, &d->verticalShear, 0); } @@ -474,9 +467,7 @@ qreal QGraphicsItemAnimation::verticalShearAt(qreal step) const */ qreal QGraphicsItemAnimation::horizontalShearAt(qreal step) const { - if (step < 0.0 || step > 1.0) - qWarning("QGraphicsItemAnimation::horizontalShearAt: invalid step = %f", step); - + check_step_valid(step, "horizontalShearAt"); return d->linearValueForStep(step, &d->horizontalShear, 0); } @@ -529,19 +520,17 @@ void QGraphicsItemAnimation::clear() Sets the current \a step value for the animation, causing the transformations scheduled at this step to be performed. */ -void QGraphicsItemAnimation::setStep(qreal x) +void QGraphicsItemAnimation::setStep(qreal step) { - if (x < 0.0 || x > 1.0) { - qWarning("QGraphicsItemAnimation::setStep: invalid step = %f", x); + if (!check_step_valid(step, "setStep")) return; - } - beforeAnimationStep(x); + beforeAnimationStep(step); - d->step = x; + d->step = step; if (d->item) { if (!d->xPosition.isEmpty() || !d->yPosition.isEmpty()) - d->item->setPos(posAt(x)); + d->item->setPos(posAt(step)); if (!d->rotation.isEmpty() || !d->verticalScale.isEmpty() || !d->horizontalScale.isEmpty() @@ -549,11 +538,11 @@ void QGraphicsItemAnimation::setStep(qreal x) || !d->horizontalShear.isEmpty() || !d->xTranslation.isEmpty() || !d->yTranslation.isEmpty()) { - d->item->setMatrix(d->startMatrix * matrixAt(x)); + d->item->setMatrix(d->startMatrix * matrixAt(step)); } } - afterAnimationStep(x); + afterAnimationStep(step); } /*! diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 35ba1ed74e..726c2704c4 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -1651,7 +1651,7 @@ bool QAbstractItemView::viewportEvent(QEvent *event) case QEvent::WhatsThis: { QHelpEvent *he = static_cast<QHelpEvent*>(event); const QModelIndex index = indexAt(he->pos()); - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); option.rect = visualRect(index); option.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None); @@ -1851,7 +1851,7 @@ void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event) emit clicked(index); if (edited) return; - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); if (d->pressedAlreadySelected) option.state |= QStyle::State_Selected; if ((model()->flags(index) & Qt::ItemIsEnabled) @@ -2627,7 +2627,7 @@ void QAbstractItemView::updateEditorGeometries() Q_D(QAbstractItemView); if(d->editorIndexHash.isEmpty()) return; - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); QEditorIndexHash::iterator it = d->editorIndexHash.begin(); QWidgetList editorsToRelease; QWidgetList editorsToHide; @@ -2972,7 +2972,7 @@ QSize QAbstractItemView::sizeHintForIndex(const QModelIndex &index) const Q_D(const QAbstractItemView); if (!d->isIndexValid(index) || !d->itemDelegate) return QSize(); - return d->delegateForIndex(index)->sizeHint(d->viewOptions(), index); + return d->delegateForIndex(index)->sizeHint(d->viewOptionsV1(), index); } /*! @@ -3000,7 +3000,7 @@ int QAbstractItemView::sizeHintForRow(int row) const ensurePolished(); - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); int height = 0; int colCount = d->model->columnCount(d->root); QModelIndex index; @@ -3031,7 +3031,7 @@ int QAbstractItemView::sizeHintForColumn(int column) const ensurePolished(); - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); int width = 0; int rows = d->model->rowCount(d->root); QModelIndex index; @@ -3054,7 +3054,7 @@ int QAbstractItemView::sizeHintForColumn(int column) const void QAbstractItemView::openPersistentEditor(const QModelIndex &index) { Q_D(QAbstractItemView); - QStyleOptionViewItem options = d->viewOptions(); + QStyleOptionViewItem options = d->viewOptionsV1(); options.rect = visualRect(index); options.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None); @@ -3600,45 +3600,45 @@ void QAbstractItemView::startDrag(Qt::DropActions supportedActions) QStyleOptionViewItem QAbstractItemView::viewOptions() const { Q_D(const QAbstractItemView); - return d->viewOptions(); -} - -QStyleOptionViewItem QAbstractItemViewPrivate::viewOptions() const -{ - Q_Q(const QAbstractItemView); QStyleOptionViewItem option; - option.init(q); + option.init(this); option.state &= ~QStyle::State_MouseOver; - option.font = q->font(); + option.font = font(); #ifndef Q_WS_MAC // On mac the focus appearance follows window activation // not widget activation - if (!q->hasFocus()) + if (!hasFocus()) option.state &= ~QStyle::State_Active; #endif option.state &= ~QStyle::State_HasFocus; - if (iconSize.isValid()) { - option.decorationSize = iconSize; + if (d->iconSize.isValid()) { + option.decorationSize = d->iconSize; } else { - int pm = q->style()->pixelMetric(QStyle::PM_SmallIconSize, 0, q); + int pm = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this); option.decorationSize = QSize(pm, pm); } option.decorationPosition = QStyleOptionViewItem::Left; option.decorationAlignment = Qt::AlignCenter; option.displayAlignment = Qt::AlignLeft|Qt::AlignVCenter; - option.textElideMode = textElideMode; + option.textElideMode = d->textElideMode; option.rect = QRect(); - option.showDecorationSelected = q->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, 0, q); - if (wrapItemText) + option.showDecorationSelected = style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, 0, this); + if (d->wrapItemText) option.features = QStyleOptionViewItem::WrapText; - option.locale = q->locale(); + option.locale = locale(); option.locale.setNumberOptions(QLocale::OmitGroupSeparator); - option.widget = q; + option.widget = this; return option; } +QStyleOptionViewItem QAbstractItemViewPrivate::viewOptionsV1() const +{ + Q_Q(const QAbstractItemView); + return q->viewOptions(); +} + /*! Returns the item view's state. @@ -4274,7 +4274,7 @@ bool QAbstractItemViewPrivate::sendDelegateEvent(const QModelIndex &index, QEven { Q_Q(const QAbstractItemView); QModelIndex buddy = model->buddy(index); - QStyleOptionViewItem options = viewOptions(); + QStyleOptionViewItem options = viewOptionsV1(); options.rect = q->visualRect(buddy); options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None); QAbstractItemDelegate *delegate = delegateForIndex(index); @@ -4286,7 +4286,7 @@ bool QAbstractItemViewPrivate::openEditor(const QModelIndex &index, QEvent *even Q_Q(QAbstractItemView); QModelIndex buddy = model->buddy(index); - QStyleOptionViewItem options = viewOptions(); + QStyleOptionViewItem options = viewOptionsV1(); options.rect = q->visualRect(buddy); options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None); @@ -4338,7 +4338,7 @@ QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QPixmap pixmap(r->size()); pixmap.fill(Qt::transparent); QPainter painter(&pixmap); - QStyleOptionViewItem option = viewOptions(); + QStyleOptionViewItem option = viewOptionsV1(); option.state |= QStyle::State_Selected; for (int j = 0; j < paintPairs.count(); ++j) { option.rect = paintPairs.at(j).first.translated(-r->topLeft()); diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h index 5da22615e2..1b5987de16 100644 --- a/src/widgets/itemviews/qabstractitemview_p.h +++ b/src/widgets/itemviews/qabstractitemview_p.h @@ -347,7 +347,7 @@ public: QModelIndexList selectedDraggableIndexes() const; - QStyleOptionViewItem viewOptions() const; + QStyleOptionViewItem viewOptionsV1() const; void doDelayedReset() { diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 123594637a..1131ef030e 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -3693,8 +3693,7 @@ void QHeaderViewPrivate::write(QDataStream &out) const out << int(globalResizeMode); out << sectionItems; - if (out.version() >= QDataStream::Qt_5_2) - out << resizeContentsPrecision; + out << resizeContentsPrecision; } bool QHeaderViewPrivate::read(QDataStream &in) @@ -3747,8 +3746,10 @@ bool QHeaderViewPrivate::read(QDataStream &in) sectionItems = newSectionItems; recalcSectionStartPos(); - if (in.version() >= QDataStream::Qt_5_2) - in >> resizeContentsPrecision; + int tmpint; + in >> tmpint; + if (in.status() == QDataStream::Ok) // we haven't read past end + resizeContentsPrecision = tmpint; return true; } diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index e5a8647f87..616a832b88 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Samuel Gaist <samuel.gaist@deltech.ch> ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtWidgets module of the Qt Toolkit. @@ -900,20 +901,14 @@ void QListView::startDrag(Qt::DropActions supportedActions) QStyleOptionViewItem QListView::viewOptions() const { Q_D(const QListView); - return d->viewOptions(); -} - -QStyleOptionViewItem QListViewPrivate::viewOptions() const -{ - Q_Q(const QListView); - QStyleOptionViewItem option = QAbstractItemViewPrivate::viewOptions(); - if (!iconSize.isValid()) { // otherwise it was already set in abstractitemview - int pm = (viewMode == QListView::ListMode - ? q->style()->pixelMetric(QStyle::PM_ListViewIconSize, 0, q) - : q->style()->pixelMetric(QStyle::PM_IconViewIconSize, 0, q)); + QStyleOptionViewItem option = QAbstractItemView::viewOptions(); + if (!d->iconSize.isValid()) { // otherwise it was already set in abstractitemview + int pm = (d->viewMode == QListView::ListMode + ? style()->pixelMetric(QStyle::PM_ListViewIconSize, 0, this) + : style()->pixelMetric(QStyle::PM_IconViewIconSize, 0, this)); option.decorationSize = QSize(pm, pm); } - if (viewMode == QListView::IconMode) { + if (d->viewMode == QListView::IconMode) { option.showDecorationSelected = false; option.decorationPosition = QStyleOptionViewItem::Top; option.displayAlignment = Qt::AlignCenter; @@ -932,7 +927,7 @@ void QListView::paintEvent(QPaintEvent *e) Q_D(QListView); if (!d->itemDelegate) return; - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); QPainter painter(d->viewport); const QVector<QModelIndex> toBeRendered = d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false); @@ -1461,7 +1456,7 @@ void QListView::updateGeometries() verticalScrollBar()->setRange(0, 0); } else { QModelIndex index = d->model->index(0, d->column, d->root); - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); QSize step = d->itemSize(option, index); d->commonListView->updateHorizontalScrollBar(step); d->commonListView->updateVerticalScrollBar(step); @@ -1833,6 +1828,15 @@ void QCommonListViewBase::removeHiddenRow(int row) dd->hiddenRows.remove(dd->model->index(row, 0, qq->rootIndex())); } +#ifndef QT_NO_DRAGANDDROP +void QCommonListViewBase::paintDragDrop(QPainter *painter) +{ + // FIXME: Until the we can provide a proper drop indicator + // in IconMode, it makes no sense to show it + dd->paintDropIndicator(painter); +} +#endif + void QCommonListViewBase::updateHorizontalScrollBar(const QSize & /*step*/) { horizontalScrollBar()->setPageStep(viewport()->width()); @@ -1902,13 +1906,6 @@ int QCommonListViewBase::horizontalScrollToValue(const int /*index*/, QListView: */ #ifndef QT_NO_DRAGANDDROP -void QListModeViewBase::paintDragDrop(QPainter *painter) -{ - // FIXME: Until the we can provide a proper drop indicator - // in IconMode, it makes no sense to show it - dd->paintDropIndicator(painter); -} - QAbstractItemView::DropIndicatorPosition QListModeViewBase::position(const QPoint &pos, const QRect &rect, const QModelIndex &index) const { QAbstractItemView::DropIndicatorPosition r = QAbstractItemView::OnViewport; @@ -2651,23 +2648,6 @@ void QIconModeViewBase::removeHiddenRow(int row) } #ifndef QT_NO_DRAGANDDROP -void QIconModeViewBase::paintDragDrop(QPainter *painter) -{ - if (!draggedItems.isEmpty() && viewport()->rect().contains(draggedItemsPos)) { - //we need to draw the items that arre dragged - painter->translate(draggedItemsDelta()); - QStyleOptionViewItem option = viewOptions(); - option.state &= ~QStyle::State_MouseOver; - QVector<QModelIndex>::const_iterator it = draggedItems.constBegin(); - QListViewItem item = indexToListViewItem(*it); - for (; it != draggedItems.constEnd(); ++it) { - item = indexToListViewItem(*it); - option.rect = viewItemRect(item); - delegate(*it)->paint(painter, option, *it); - } - } -} - bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions) { // This function does the same thing as in QAbstractItemView::startDrag(), @@ -2682,8 +2662,14 @@ bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions) && (*it).column() == dd->column) draggedItems.push_back(*it); } + + QRect rect; + QPixmap pixmap = dd->renderToPixmap(indexes, &rect); + rect.adjust(horizontalOffset(), verticalOffset(), 0, 0); QDrag *drag = new QDrag(qq); drag->setMimeData(dd->model->mimeData(indexes)); + drag->setPixmap(pixmap); + drag->setHotSpot(dd->pressedPosition - rect.topLeft()); Qt::DropAction action = drag->exec(supportedActions, Qt::CopyAction); draggedItems.clear(); if (action == Qt::MoveAction) diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h index 35d11140ef..4f3ccedb62 100644 --- a/src/widgets/itemviews/qlistview_p.h +++ b/src/widgets/itemviews/qlistview_p.h @@ -147,7 +147,7 @@ public: virtual void setPositionForIndex(const QPoint &, const QModelIndex &) { } #ifndef QT_NO_DRAGANDDROP - virtual void paintDragDrop(QPainter *painter) = 0; + virtual void paintDragDrop(QPainter *painter); virtual bool filterDragMoveEvent(QDragMoveEvent *) { return false; } virtual bool filterDragLeaveEvent(QDragLeaveEvent *) { return false; } virtual bool filterDropEvent(QDropEvent *) { return false; } @@ -231,8 +231,6 @@ public: void updateVerticalScrollBar(const QSize &step); #ifndef QT_NO_DRAGANDDROP - void paintDragDrop(QPainter *painter); - // The next two methods are to be used on LefToRight flow only. // WARNING: Plenty of duplicated code from QAbstractItemView{,Private}. QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const; @@ -279,7 +277,6 @@ public: void setPositionForIndex(const QPoint &position, const QModelIndex &index); #ifndef QT_NO_DRAGANDDROP - void paintDragDrop(QPainter *painter); bool filterDragMoveEvent(QDragMoveEvent *); bool filterDragLeaveEvent(QDragLeaveEvent *); bool filterDropEvent(QDropEvent *e); @@ -394,8 +391,6 @@ public: } } - QStyleOptionViewItem viewOptions() const; - void scrollElasticBandBy(int dx, int dy); QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const; @@ -470,7 +465,7 @@ inline QModelIndex QCommonListViewBase::modelIndex(int row) const { return dd->model->index(row, dd->column, dd->root); } inline int QCommonListViewBase::rowCount() const { return dd->model->rowCount(dd->root); } -inline QStyleOptionViewItem QCommonListViewBase::viewOptions() const { return dd->viewOptions(); } +inline QStyleOptionViewItem QCommonListViewBase::viewOptions() const { return dd->viewOptionsV1(); } inline QWidget *QCommonListViewBase::viewport() const { return dd->viewport; } inline QRect QCommonListViewBase::clipRect() const { return dd->clipRect(); } diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index 34e881571e..08600b3ef7 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -1346,20 +1346,14 @@ void QTableView::scrollContentsBy(int dx, int dy) } } -QStyleOptionViewItem QTableViewPrivate::viewOptions() const -{ - QStyleOptionViewItem option = QAbstractItemViewPrivate::viewOptions(); - option.showDecorationSelected = true; - return option; -} - /*! \reimp */ QStyleOptionViewItem QTableView::viewOptions() const { - Q_D(const QTableView); - return d->viewOptions(); + QStyleOptionViewItem option = QAbstractItemView::viewOptions(); + option.showDecorationSelected = true; + return option; } /*! @@ -1369,7 +1363,7 @@ void QTableView::paintEvent(QPaintEvent *event) { Q_D(QTableView); // setup temp variables for the painting - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); const QPoint offset = d->scrollDelayOffset; const bool showGrid = d->showGrid; const int gridSize = showGrid ? 1 : 0; @@ -2241,7 +2235,7 @@ int QTableView::sizeHintForRow(int row) const if (right == -1) // the table don't have enough columns to fill the viewport right = d->model->columnCount(d->root) - 1; - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); int hint = 0; QModelIndex index; @@ -2329,7 +2323,7 @@ int QTableView::sizeHintForColumn(int column) const if (!isVisible() || bottom == -1) // the table don't have enough rows to fill the viewport bottom = d->model->rowCount(d->root) - 1; - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); int hint = 0; int rowsProcessed = 0; diff --git a/src/widgets/itemviews/qtableview_p.h b/src/widgets/itemviews/qtableview_p.h index 74eb7b7728..555ae50daf 100644 --- a/src/widgets/itemviews/qtableview_p.h +++ b/src/widgets/itemviews/qtableview_p.h @@ -150,8 +150,6 @@ public: void init(); void trimHiddenSelections(QItemSelectionRange *range) const; - QStyleOptionViewItem viewOptions() const; - inline bool isHidden(int row, int col) const { return verticalHeader->isSectionHidden(row) || horizontalHeader->isSectionHidden(col); diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 22cd9abc73..792b75ac69 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -1441,7 +1441,7 @@ void QTreeView::drawTree(QPainter *painter, const QRegion ®ion) const Q_D(const QTreeView); const QVector<QTreeViewItem> viewItems = d->viewItems; - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); const QStyle::State state = option.state; d->current = 0; @@ -2850,7 +2850,7 @@ int QTreeView::sizeHintForColumn(int column) const return -1; ensurePolished(); int w = 0; - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); const QVector<QTreeViewItem> viewItems = d->viewItems; const int maximumProcessRows = d->header->resizeContentsPrecision(); // To avoid this to take forever. @@ -2947,7 +2947,7 @@ int QTreeView::indexRowSizeHint(const QModelIndex &index) const qSwap(end, start); int height = -1; - QStyleOptionViewItem option = d->viewOptions(); + QStyleOptionViewItem option = d->viewOptionsV1(); // ### If we want word wrapping in the items, // ### we need to go through all the columns // ### and set the width of the column @@ -3220,7 +3220,7 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons painter.end(); //and now let's render the editors the editors - QStyleOptionViewItem option = viewOptions(); + QStyleOptionViewItem option = viewOptionsV1(); for (QEditorIndexHash::const_iterator it = editorIndexHash.constBegin(); it != editorIndexHash.constEnd(); ++it) { QWidget *editor = it.key(); const QModelIndex &index = it.value(); diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri index 533b696faa..444b9b687f 100644 --- a/src/widgets/kernel/kernel.pri +++ b/src/widgets/kernel/kernel.pri @@ -66,59 +66,9 @@ SOURCES += \ kernel/qwidgetwindow.cpp \ kernel/qwindowcontainer.cpp - -# TODO -false:!x11:mac { - SOURCES += \ - kernel/qclipboard_mac.cpp \ - kernel/qmime_mac.cpp \ - kernel/qt_mac.cpp \ - kernel/qkeymapper_mac.cpp - - OBJECTIVE_HEADERS += \ - qcocoawindow_mac_p.h \ - qcocoapanel_mac_p.h \ - qcocoawindowdelegate_mac_p.h \ - qcocoaview_mac_p.h \ - qcocoaapplication_mac_p.h \ - qcocoaapplicationdelegate_mac_p.h \ - qmacgesturerecognizer_mac_p.h \ - qmultitouch_mac_p.h \ - qcocoasharedwindowmethods_mac_p.h \ - qcocoaintrospection_p.h - - OBJECTIVE_SOURCES += \ - kernel/qcursor_mac.mm \ - kernel/qdnd_mac.mm \ - kernel/qapplication_mac.mm \ - kernel/qwidget_mac.mm \ - kernel/qcocoapanel_mac.mm \ - kernel/qcocoaview_mac.mm \ - kernel/qcocoawindow_mac.mm \ - kernel/qcocoawindowdelegate_mac.mm \ - kernel/qcocoaapplication_mac.mm \ - kernel/qcocoaapplicationdelegate_mac.mm \ - kernel/qt_cocoa_helpers_mac.mm \ - kernel/qdesktopwidget_mac.mm \ - kernel/qeventdispatcher_mac.mm \ - kernel/qcocoawindowcustomthemeframe_mac.mm \ - kernel/qmacgesturerecognizer_mac.mm \ - kernel/qmultitouch_mac.mm \ - kernel/qcocoaintrospection_mac.mm - - HEADERS += \ - kernel/qt_cocoa_helpers_mac_p.h \ - kernel/qcocoaapplication_mac_p.h \ - kernel/qcocoaapplicationdelegate_mac_p.h \ - kernel/qeventdispatcher_mac_p.h - - MENU_NIB.files = mac/qt_menu.nib - MENU_NIB.path = Resources - MENU_NIB.version = Versions - QMAKE_BUNDLE_DATA += MENU_NIB - RESOURCES += mac/macresources.qrc - - LIBS_PRIVATE += -framework AppKit +macx: { + HEADERS += kernel/qmacgesturerecognizer_p.h + SOURCES += kernel/qmacgesturerecognizer.cpp } wince*: { diff --git a/src/widgets/kernel/qgesture_p.h b/src/widgets/kernel/qgesture_p.h index c041af7317..ae203d2819 100644 --- a/src/widgets/kernel/qgesture_p.h +++ b/src/widgets/kernel/qgesture_p.h @@ -190,41 +190,6 @@ public: static int Timeout; }; -#ifndef QT_NO_GESTURES -class QNativeGestureEvent : public QEvent -{ -public: - enum Type { - None, - GestureBegin, - GestureEnd, - Pan, - Zoom, - Rotate, - Swipe - }; - - QNativeGestureEvent() - : QEvent(QEvent::NativeGesture), gestureType(None), percentage(0) -#ifdef Q_WS_WIN - , sequenceId(0), argument(0) -#endif - { - } - - Type gestureType; - float percentage; - QPoint position; - float angle; -#ifdef Q_WS_WIN - ulong sequenceId; - quint64 argument; -#endif -}; - -#endif // QT_NO_GESTURES - - QT_END_NAMESPACE #endif // QT_NO_GESTURES diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp index d90b187bf0..18abad4b40 100644 --- a/src/widgets/kernel/qgesturemanager.cpp +++ b/src/widgets/kernel/qgesturemanager.cpp @@ -51,8 +51,8 @@ #include "qevent.h" #include "qgraphicsitem.h" -#ifdef Q_WS_MAC -#include "qmacgesturerecognizer_mac_p.h" +#ifdef Q_OS_OSX +#include "qmacgesturerecognizer_p.h" #endif #if defined(Q_WS_WIN) && !defined(QT_NO_NATIVE_GESTURES) #include "qwinnativepangesturerecognizer_win_p.h" @@ -76,7 +76,7 @@ QGestureManager::QGestureManager(QObject *parent) { qRegisterMetaType<Qt::GestureState>(); -#if defined(Q_WS_MAC) +#if defined(Q_OS_OSX) registerGestureRecognizer(new QMacSwipeGestureRecognizer); registerGestureRecognizer(new QMacPinchGestureRecognizer); registerGestureRecognizer(new QMacPanGestureRecognizer); diff --git a/src/widgets/kernel/qmacgesturerecognizer.cpp b/src/widgets/kernel/qmacgesturerecognizer.cpp new file mode 100644 index 0000000000..feb779e53f --- /dev/null +++ b/src/widgets/kernel/qmacgesturerecognizer.cpp @@ -0,0 +1,275 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmacgesturerecognizer_p.h" +#include "qgesture.h" +#include "qgesture_p.h" +#include "qevent.h" +#include "qwidget.h" +#include "qdebug.h" + +#ifndef QT_NO_GESTURES + +QT_BEGIN_NAMESPACE + +QMacSwipeGestureRecognizer::QMacSwipeGestureRecognizer() +{ +} + +QGesture *QMacSwipeGestureRecognizer::create(QObject * /*target*/) +{ + return new QSwipeGesture; +} + +QGestureRecognizer::Result +QMacSwipeGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) { + QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event); + switch (ev->gestureType()) { + case Qt::SwipeNativeGesture: { + QSwipeGesture *g = static_cast<QSwipeGesture *>(gesture); + g->setSwipeAngle(ev->value()); + g->setHotSpot(ev->screenPos()); + return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint; + break; } + default: + break; + } + } + + return QGestureRecognizer::Ignore; +} + +void QMacSwipeGestureRecognizer::reset(QGesture *gesture) +{ + QSwipeGesture *g = static_cast<QSwipeGesture *>(gesture); + g->setSwipeAngle(0); + QGestureRecognizer::reset(gesture); +} + +//////////////////////////////////////////////////////////////////////// + +QMacPinchGestureRecognizer::QMacPinchGestureRecognizer() +{ +} + +QGesture *QMacPinchGestureRecognizer::create(QObject * /*target*/) +{ + return new QPinchGesture; +} + +QGestureRecognizer::Result +QMacPinchGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) { + QPinchGesture *g = static_cast<QPinchGesture *>(gesture); + QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event); + switch (ev->gestureType()) { + case Qt::BeginNativeGesture: + reset(gesture); + g->setStartCenterPoint(static_cast<QWidget*>(obj)->mapFromGlobal(ev->screenPos().toPoint())); + g->setCenterPoint(g->startCenterPoint()); + g->setChangeFlags(QPinchGesture::CenterPointChanged); + g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags()); + g->setHotSpot(ev->screenPos()); + return QGestureRecognizer::MayBeGesture | QGestureRecognizer::ConsumeEventHint; + case Qt::RotateNativeGesture: + g->setLastScaleFactor(g->scaleFactor()); + g->setLastRotationAngle(g->rotationAngle()); + g->setRotationAngle(g->rotationAngle() + ev->value()); + g->setChangeFlags(QPinchGesture::RotationAngleChanged); + g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags()); + g->setHotSpot(ev->screenPos()); + return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint; + case Qt::ZoomNativeGesture: + g->setLastScaleFactor(g->scaleFactor()); + g->setLastRotationAngle(g->rotationAngle()); + g->setScaleFactor(g->scaleFactor() * (1 + ev->value())); + g->setChangeFlags(QPinchGesture::ScaleFactorChanged); + g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags()); + g->setHotSpot(ev->screenPos()); + return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint; + case Qt::SmartZoomNativeGesture: + g->setLastScaleFactor(g->scaleFactor()); + g->setLastRotationAngle(g->rotationAngle()); + g->setScaleFactor(ev->value() ? 1.7f : 1.0f); + g->setChangeFlags(QPinchGesture::ScaleFactorChanged); + g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags()); + g->setHotSpot(ev->screenPos()); + return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint; + case Qt::EndNativeGesture: + return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint; + default: + break; + } + } + + return QGestureRecognizer::Ignore; +} + +void QMacPinchGestureRecognizer::reset(QGesture *gesture) +{ + QPinchGesture *g = static_cast<QPinchGesture *>(gesture); + g->setChangeFlags(0); + g->setTotalChangeFlags(0); + g->setScaleFactor(1.0f); + g->setTotalScaleFactor(1.0f); + g->setLastScaleFactor(1.0f); + g->setRotationAngle(0.0f); + g->setTotalRotationAngle(0.0f); + g->setLastRotationAngle(0.0f); + g->setCenterPoint(QPointF()); + g->setStartCenterPoint(QPointF()); + g->setLastCenterPoint(QPointF()); + QGestureRecognizer::reset(gesture); +} + +//////////////////////////////////////////////////////////////////////// + +QMacPanGestureRecognizer::QMacPanGestureRecognizer() : _panCanceled(true) +{ +} + +QGesture *QMacPanGestureRecognizer::create(QObject *target) +{ + if (!target) + return new QPanGesture; + + if (QWidget *w = qobject_cast<QWidget *>(target)) { + w->setAttribute(Qt::WA_AcceptTouchEvents); + w->setAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); + return new QPanGesture; + } + return 0; +} + +QGestureRecognizer::Result +QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent *event) +{ + const int panBeginDelay = 300; + const int panBeginRadius = 3; + + QPanGesture *g = static_cast<QPanGesture *>(gesture); + + switch (event->type()) { + case QEvent::TouchBegin: { + const QTouchEvent *ev = static_cast<const QTouchEvent*>(event); + if (ev->touchPoints().size() == 1) { + reset(gesture); + _startPos = QCursor::pos(); + _panTimer.start(panBeginDelay, target); + _panCanceled = false; + return QGestureRecognizer::MayBeGesture; + } + break;} + case QEvent::TouchEnd: { + if (_panCanceled) + break; + + const QTouchEvent *ev = static_cast<const QTouchEvent*>(event); + if (ev->touchPoints().size() == 1) + return QGestureRecognizer::FinishGesture; + break;} + case QEvent::TouchUpdate: { + if (_panCanceled) + break; + + const QTouchEvent *ev = static_cast<const QTouchEvent*>(event); + if (ev->touchPoints().size() == 1) { + if (_panTimer.isActive()) { + // INVARIANT: Still in maybeGesture. Check if the user + // moved his finger so much that it makes sense to cancel the pan: + const QPointF p = QCursor::pos(); + if ((p - _startPos).manhattanLength() > panBeginRadius) { + _panCanceled = true; + _panTimer.stop(); + return QGestureRecognizer::CancelGesture; + } + } else { + const QPointF p = QCursor::pos(); + const QPointF posOffset = p - _startPos; + g->setLastOffset(g->offset()); + g->setOffset(QPointF(posOffset.x(), posOffset.y())); + g->setHotSpot(_startPos); + return QGestureRecognizer::TriggerGesture; + } + } else if (_panTimer.isActive()) { + // I only want to cancel the pan if the user is pressing + // more than one finger, and the pan hasn't started yet: + _panCanceled = true; + _panTimer.stop(); + return QGestureRecognizer::CancelGesture; + } + break;} + case QEvent::Timer: { + QTimerEvent *ev = static_cast<QTimerEvent *>(event); + if (ev->timerId() == _panTimer.timerId()) { + _panTimer.stop(); + if (_panCanceled) + break; + // Begin new pan session! + _startPos = QCursor::pos(); + g->setHotSpot(_startPos); + return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint; + } + break; } + default: + break; + } + + return QGestureRecognizer::Ignore; +} + +void QMacPanGestureRecognizer::reset(QGesture *gesture) +{ + QPanGesture *g = static_cast<QPanGesture *>(gesture); + _startPos = QPointF(); + _panCanceled = true; + g->setOffset(QPointF(0, 0)); + g->setLastOffset(QPointF(0, 0)); + g->setAcceleration(qreal(1)); + QGestureRecognizer::reset(gesture); +} + +QT_END_NAMESPACE + +#endif // QT_NO_GESTURES diff --git a/src/widgets/kernel/qmacgesturerecognizer_p.h b/src/widgets/kernel/qmacgesturerecognizer_p.h new file mode 100644 index 0000000000..02f836b3f7 --- /dev/null +++ b/src/widgets/kernel/qmacgesturerecognizer_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMACSWIPEGESTURERECOGNIZER_MAC_P_H +#define QMACSWIPEGESTURERECOGNIZER_MAC_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qtimer.h" +#include "qpoint.h" +#include "qgesturerecognizer.h" + +#ifndef QT_NO_GESTURES + +QT_BEGIN_NAMESPACE + +class QMacSwipeGestureRecognizer : public QGestureRecognizer +{ +public: + QMacSwipeGestureRecognizer(); + + QGesture *create(QObject *target); + QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event); + void reset(QGesture *gesture); +}; + +class QMacPinchGestureRecognizer : public QGestureRecognizer +{ +public: + QMacPinchGestureRecognizer(); + + QGesture *create(QObject *target); + QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event); + void reset(QGesture *gesture); +}; + +class QMacPanGestureRecognizer : public QObject, public QGestureRecognizer +{ +public: + QMacPanGestureRecognizer(); + + QGesture *create(QObject *target); + QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event); + void reset(QGesture *gesture); +private: + QPointF _startPos; + QBasicTimer _panTimer; + bool _panCanceled; +}; + +QT_END_NAMESPACE + +#endif // QT_NO_GESTURES + +#endif // QMACSWIPEGESTURERECOGNIZER_MAC_P_H diff --git a/src/widgets/kernel/qsizepolicy.qdoc b/src/widgets/kernel/qsizepolicy.qdoc index 1c99131bc4..d82f3837f2 100644 --- a/src/widgets/kernel/qsizepolicy.qdoc +++ b/src/widgets/kernel/qsizepolicy.qdoc @@ -342,6 +342,7 @@ /*! \fn void QSizePolicy::retainSizeWhenHidden() const + \since 5.2 Returns if the layout should retain the widgets size when it is hidden. This is by default false. @@ -350,6 +351,7 @@ /*! \fn void QSizePolicy::setRetainSizeWhenHidden(bool retainSize) + \since 5.2 Set if a layout should retain the widgets size when it is hidden. If \a retainSize is true the layout will not be changed by hiding the widget. diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 72e3a56702..55459ac1ac 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1594,6 +1594,7 @@ void QWidgetPrivate::createExtra() extra->autoFillBackground = 0; extra->nativeChildrenForced = 0; extra->inRenderWithPainter = 0; + extra->hasWindowContainer = false; extra->hasMask = 0; createSysExtra(); #ifdef QWIDGET_EXTRA_DEBUG @@ -6543,6 +6544,9 @@ void QWidget::move(const QPoint &p) data->crect.moveTopLeft(p); // no frame yet setAttribute(Qt::WA_PendingMoveEvent); } + + if (d->extra && d->extra->hasWindowContainer) + QWindowContainer::parentWasMoved(this); } /*! \fn void QWidget::resize(int w, int h) @@ -6581,6 +6585,9 @@ void QWidget::setGeometry(const QRect &r) setAttribute(Qt::WA_PendingMoveEvent); setAttribute(Qt::WA_PendingResizeEvent); } + + if (d->extra && d->extra->hasWindowContainer) + QWindowContainer::parentWasMoved(this); } /*! @@ -9715,6 +9722,9 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) ancestorProxy->d_func()->embedSubWindow(this); } #endif + + if (d->extra && d->extra->hasWindowContainer) + QWindowContainer::parentWasChanged(this); } /*! @@ -10747,6 +10757,9 @@ void QWidget::raise() if (testAttribute(Qt::WA_WState_Created)) d->raise_sys(); + if (d->extra && d->extra->hasWindowContainer) + QWindowContainer::parentWasRaised(this); + QEvent e(QEvent::ZOrderChange); QApplication::sendEvent(this, &e); } @@ -10781,6 +10794,9 @@ void QWidget::lower() if (testAttribute(Qt::WA_WState_Created)) d->lower_sys(); + if (d->extra && d->extra->hasWindowContainer) + QWindowContainer::parentWasLowered(this); + QEvent e(QEvent::ZOrderChange); QApplication::sendEvent(this, &e); } diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index cc740034fc..df40908c00 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -254,6 +254,7 @@ struct QWExtra { uint nativeChildrenForced : 1; uint inRenderWithPainter : 1; uint hasMask : 1; + uint hasWindowContainer : 1; // *************************** Platform specific values (bit fields first) ********** #if defined(Q_WS_WIN) // <----------------------------------------------------------- WIN diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index f2bd389769..51a0eb7d72 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -49,6 +49,7 @@ #endif #include <private/qwidgetbackingstore_p.h> #include <qpa/qwindowsysteminterface_p.h> +#include <private/qgesturemanager_p.h> QT_BEGIN_NAMESPACE @@ -85,6 +86,12 @@ QWidgetWindow::QWidgetWindow(QWidget *widget) connect(m_widget, &QObject::objectNameChanged, this, &QWidgetWindow::updateObjectName); } +QWidgetWindow::~QWidgetWindow() +{ + if (m_widget == qt_tablet_target) + qt_tablet_target = 0; +} + #ifndef QT_NO_ACCESSIBILITY QAccessibleInterface *QWidgetWindow::accessibleRoot() const { @@ -220,6 +227,13 @@ bool QWidgetWindow::event(QEvent *event) handleTabletEvent(static_cast<QTabletEvent *>(event)); return true; #endif + +#ifndef QT_NO_GESTURES + case QEvent::NativeGesture: + handleGestureEvent(static_cast<QNativeGestureEvent *>(event)); + return true; +#endif + #ifndef QT_NO_CONTEXTMENU case QEvent::ContextMenu: handleContextMenuEvent(static_cast<QContextMenuEvent *>(event)); @@ -732,6 +746,25 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event) } #endif // QT_NO_TABLETEVENT +#ifndef QT_NO_GESTURES +void QWidgetWindow::handleGestureEvent(QNativeGestureEvent *e) +{ + // copy-pasted code to find correct widget follows: + QObject *receiver = 0; + if (QApplicationPrivate::inPopupMode()) { + QWidget *popup = QApplication::activePopupWidget(); + QWidget *popupFocusWidget = popup->focusWidget(); + receiver = popupFocusWidget ? popupFocusWidget : popup; + } + if (!receiver) + receiver = QApplication::widgetAt(e->globalPos()); + if (!receiver) + receiver = m_widget; // last resort + + QApplication::sendSpontaneousEvent(receiver, e); +} +#endif // QT_NO_GESTURES + #ifndef QT_NO_CONTEXTMENU void QWidgetWindow::handleContextMenuEvent(QContextMenuEvent *e) { diff --git a/src/widgets/kernel/qwidgetwindow_qpa_p.h b/src/widgets/kernel/qwidgetwindow_qpa_p.h index cb7bef8f3e..ffde44dd27 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa_p.h +++ b/src/widgets/kernel/qwidgetwindow_qpa_p.h @@ -58,6 +58,7 @@ class QWidgetWindow : public QWindow Q_OBJECT public: QWidgetWindow(QWidget *widget); + ~QWidgetWindow(); QWidget *widget() const { return m_widget; } #ifndef QT_NO_ACCESSIBILITY @@ -91,6 +92,9 @@ protected: #ifndef QT_NO_TABLETEVENT void handleTabletEvent(QTabletEvent *); #endif +#ifndef QT_NO_GESTURES + void handleGestureEvent(QNativeGestureEvent *); +#endif #ifndef QT_NO_CONTEXTMENU void handleContextMenuEvent(QContextMenuEvent *); #endif diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp index b02b05552f..6914f64f8e 100644 --- a/src/widgets/kernel/qwindowcontainer.cpp +++ b/src/widgets/kernel/qwindowcontainer.cpp @@ -42,6 +42,10 @@ #include "qwindowcontainer_p.h" #include "qwidget_p.h" #include <QtGui/qwindow.h> +#include <QDebug> + +#include <QMdiSubWindow> +#include <QAbstractScrollArea> QT_BEGIN_NAMESPACE @@ -50,11 +54,67 @@ class QWindowContainerPrivate : public QWidgetPrivate public: Q_DECLARE_PUBLIC(QWindowContainer) - QWindowContainerPrivate() : window(0), oldFocusWindow(0) { } + QWindowContainerPrivate() + : window(0) + , oldFocusWindow(0) + , usesNativeWidgets(false) + { + } + ~QWindowContainerPrivate() { } + static QWindowContainerPrivate *get(QWidget *w) { + QWindowContainer *wc = qobject_cast<QWindowContainer *>(w); + if (wc) + return wc->d_func(); + return 0; + } + + void updateGeometry() { + Q_Q(QWindowContainer); + if (usesNativeWidgets) + window->setGeometry(q->rect()); + else + window->setGeometry(QRect(q->mapTo(q->window(), QPoint()), q->size())); + } + + void updateUsesNativeWidgets() + { + if (usesNativeWidgets || window->parent() == 0) + return; + Q_Q(QWindowContainer); + QWidget *p = q->parentWidget(); + while (p) { + if (qobject_cast<QMdiSubWindow *>(p) != 0 + || qobject_cast<QAbstractScrollArea *>(p) != 0) { + q->winId(); + usesNativeWidgets = true; + break; + } + p = p->parentWidget(); + } + } + + void markParentChain() { + Q_Q(QWindowContainer); + QWidget *p = q; + while (p) { + QWidgetPrivate *d = static_cast<QWidgetPrivate *>(QWidgetPrivate::get(p)); + d->createExtra(); + d->extra->hasWindowContainer = true; + p = p->parentWidget(); + } + } + + bool isStillAnOrphan() const { + return window->parent() == &fakeParent; + } + QPointer<QWindow> window; QWindow *oldFocusWindow; + QWindow fakeParent; + + uint usesNativeWidgets : 1; }; @@ -78,6 +138,14 @@ public: be removed from the window container with a call to QWindow::setParent(). + The window container is attached as a native child window to the + toplevel window it is a child of. When a window container is used + as a child of a QAbstractScrollArea or QMdiArea, it will + create a \l {Native Widgets vs Alien Widgets} {native window} for + every widget in its parent chain to allow for proper stacking and + clipping in this use case. Applications with many native child + windows may suffer from performance issues. + The window container has a number of known limitations: \list @@ -86,11 +154,6 @@ public: widget hierarchy as an opaque box. The stacking order of multiple overlapping window container instances is undefined. - \li Window Handles; The window container will explicitly invoke - winId() which will force the use of native window handles - inside the application. See \l {Native Widgets vs Alien Widgets} - {QWidget documentation} for more details. - \li Rendering Integration; The window container does not interoperate with QGraphicsProxyWidget, QWidget::render() or similar functionality. @@ -132,13 +195,7 @@ QWindowContainer::QWindowContainer(QWindow *embeddedWindow, QWidget *parent, Qt: } d->window = embeddedWindow; - - // We force this window to become a native window and reparent the - // window directly to it. This is done so that the order in which - // the QWindowContainer is added to a QWidget tree and when it - // gets a window does not matter. - winId(); - d->window->setParent(windowHandle()); + d->window->setParent(&d->fakeParent); connect(QGuiApplication::instance(), SIGNAL(focusWindowChanged(QWindow *)), this, SLOT(focusWindowChanged(QWindow *))); } @@ -167,8 +224,6 @@ void QWindowContainer::focusWindowChanged(QWindow *focusWindow) d->oldFocusWindow = focusWindow; } - - /*! \internal */ @@ -190,22 +245,38 @@ bool QWindowContainer::event(QEvent *e) // The only thing we are interested in is making sure our sizes stay // in sync, so do a catch-all case. case QEvent::Resize: + d->updateGeometry(); + break; case QEvent::Move: + d->updateGeometry(); + break; case QEvent::PolishRequest: - d->window->setGeometry(0, 0, width(), height()); + d->updateGeometry(); break; case QEvent::Show: - d->window->show(); + d->updateUsesNativeWidgets(); + if (d->isStillAnOrphan()) { + d->window->setParent(d->usesNativeWidgets + ? windowHandle() + : window()->windowHandle()); + } + if (d->window->parent()) { + d->markParentChain(); + d->window->show(); + } break; case QEvent::Hide: - d->window->hide(); + if (d->window->parent()) + d->window->hide(); break; case QEvent::FocusIn: - if (d->oldFocusWindow != d->window) { - d->window->requestActivate(); - } else { - QWidget *next = nextInFocusChain(); - next->setFocus(); + if (d->window->parent()) { + if (d->oldFocusWindow != d->window) { + d->window->requestActivate(); + } else { + QWidget *next = nextInFocusChain(); + next->setFocus(); + } } break; default: @@ -215,4 +286,60 @@ bool QWindowContainer::event(QEvent *e) return QWidget::event(e); } +typedef void (*qwindowcontainer_traverse_callback)(QWidget *parent); +static void qwindowcontainer_traverse(QWidget *parent, qwindowcontainer_traverse_callback callback) +{ + const QObjectList &children = parent->children(); + for (int i=0; i<children.size(); ++i) { + QWidget *w = qobject_cast<QWidget *>(children.at(i)); + if (w) { + QWidgetPrivate *wd = static_cast<QWidgetPrivate *>(QWidgetPrivate::get(w)); + if (wd->extra && wd->extra->hasWindowContainer) + callback(w); + } + } +} + +void QWindowContainer::parentWasChanged(QWidget *parent) +{ + if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) { + if (d->window->parent()) { + d->updateUsesNativeWidgets(); + d->markParentChain(); + d->window->setParent(d->usesNativeWidgets + ? parent->windowHandle() + : parent->window()->windowHandle()); + d->updateGeometry(); + } + } + qwindowcontainer_traverse(parent, parentWasChanged); +} + +void QWindowContainer::parentWasMoved(QWidget *parent) +{ + if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) { + if (d->window->parent()) + d->updateGeometry(); + } + qwindowcontainer_traverse(parent, parentWasMoved); +} + +void QWindowContainer::parentWasRaised(QWidget *parent) +{ + if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) { + if (d->window->parent()) + d->window->raise(); + } + qwindowcontainer_traverse(parent, parentWasRaised); +} + +void QWindowContainer::parentWasLowered(QWidget *parent) +{ + if (QWindowContainerPrivate *d = QWindowContainerPrivate::get(parent)) { + if (d->window->parent()) + d->window->lower(); + } + qwindowcontainer_traverse(parent, parentWasLowered); +} + QT_END_NAMESPACE diff --git a/src/widgets/kernel/qwindowcontainer_p.h b/src/widgets/kernel/qwindowcontainer_p.h index 37c023fc1d..e2446bef42 100644 --- a/src/widgets/kernel/qwindowcontainer_p.h +++ b/src/widgets/kernel/qwindowcontainer_p.h @@ -57,6 +57,11 @@ public: explicit QWindowContainer(QWindow *embeddedWindow, QWidget *parent = 0, Qt::WindowFlags f = 0); ~QWindowContainer(); + static void parentWasChanged(QWidget *parent); + static void parentWasMoved(QWidget *parent); + static void parentWasRaised(QWidget *parent); + static void parentWasLowered(QWidget *parent); + protected: bool event(QEvent *ev); diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp index 08b24a8200..79ca0a5bdb 100644 --- a/src/widgets/util/qsystemtrayicon.cpp +++ b/src/widgets/util/qsystemtrayicon.cpp @@ -380,6 +380,8 @@ bool QSystemTrayIcon::supportsMessages() On Mac OS X, the Growl notification system must be installed for this function to display messages. + Has been turned into a slot in Qt 5.2. + \sa show(), supportsMessages() */ void QSystemTrayIcon::showMessage(const QString& title, const QString& msg, diff --git a/src/widgets/util/qsystemtrayicon.h b/src/widgets/util/qsystemtrayicon.h index 278efae586..d6ba553a3a 100644 --- a/src/widgets/util/qsystemtrayicon.h +++ b/src/widgets/util/qsystemtrayicon.h @@ -94,8 +94,6 @@ public: static bool supportsMessages(); enum MessageIcon { NoIcon, Information, Warning, Critical }; - void showMessage(const QString &title, const QString &msg, - MessageIcon icon = Information, int msecs = 10000); QRect geometry() const; bool isVisible() const; @@ -104,6 +102,8 @@ public Q_SLOTS: void setVisible(bool visible); inline void show() { setVisible(true); } inline void hide() { setVisible(false); } + void showMessage(const QString &title, const QString &msg, + QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::Information, int msecs = 10000); Q_SIGNALS: void activated(QSystemTrayIcon::ActivationReason reason); diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro index 3771b97a31..e3222b49e8 100644 --- a/src/widgets/widgets.pro +++ b/src/widgets/widgets.pro @@ -44,7 +44,3 @@ QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtWidgets.dynlist testcocoon { load(testcocoon) } - -win32:!contains(QT_CONFIG, directwrite) { - DEFINES += QT_NO_DIRECTWRITE -} diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index a9b21cbc81..8b151e65bd 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -674,12 +674,18 @@ void QDockWidgetPrivate::updateButtons() = qobject_cast<QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::FloatButton)); button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q)); button->setVisible(canFloat && !hideButtons); - +#ifndef QT_NO_ACCESSIBILITY + button->setAccessibleName(QDockWidget::tr("Float")); + button->setAccessibleDescription(QDockWidget::tr("Undocks and re-attaches the dock widget")); +#endif button = qobject_cast <QAbstractButton*>(dwLayout->widgetForRole(QDockWidgetLayout::CloseButton)); button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q)); button->setVisible(canClose && !hideButtons); - +#ifndef QT_NO_ACCESSIBILITY + button->setAccessibleName(QDockWidget::tr("Close")); + button->setAccessibleDescription(QDockWidget::tr("Closes the dock widget")); +#endif q->setAttribute(Qt::WA_ContentsPropagated, (canFloat || canClose) && !hideButtons); diff --git a/src/widgets/widgets/qstatusbar.cpp b/src/widgets/widgets/qstatusbar.cpp index 86fd10699c..7b1d66cf0d 100644 --- a/src/widgets/widgets/qstatusbar.cpp +++ b/src/widgets/widgets/qstatusbar.cpp @@ -551,8 +551,6 @@ void QStatusBar::showMessage(const QString &message, int timeout) { Q_D(QStatusBar); - d->tempItem = message; - if (timeout > 0) { if (!d->timer) { d->timer = new QTimer(this); @@ -563,6 +561,9 @@ void QStatusBar::showMessage(const QString &message, int timeout) delete d->timer; d->timer = 0; } + if (d->tempItem == message) + return; + d->tempItem = message; hideOrShow(); } |