diff options
Diffstat (limited to 'src/widgets/dialogs/qfiledialog.cpp')
-rw-r--r-- | src/widgets/dialogs/qfiledialog.cpp | 78 |
1 files changed, 61 insertions, 17 deletions
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 2c2d209226..a89192e76f 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -44,6 +44,7 @@ #include "qfiledialog.h" #include "qfiledialog_p.h" +#include <private/qapplication_p.h> #include <private/qguiapplication_p.h> #include <qfontmetrics.h> #include <qaction.h> @@ -77,6 +78,8 @@ #include <private/qwasmlocalfileaccess_p.h> #endif +#include <algorithm> + QT_BEGIN_NAMESPACE Q_GLOBAL_STATIC(QUrl, lastVisitedDir) @@ -3372,6 +3375,18 @@ void QFileDialogPrivate::_q_goHome() q->setDirectory(QDir::homePath()); } + +void QFileDialogPrivate::saveHistorySelection() +{ + if (qFileDialogUi.isNull() || currentHistoryLocation < 0 || currentHistoryLocation >= currentHistory.size()) + return; + auto &item = currentHistory[currentHistoryLocation]; + item.selection.clear(); + const auto selectedIndexes = qFileDialogUi->listView->selectionModel()->selectedRows(); + for (const auto &index : selectedIndexes) + item.selection.append(QPersistentModelIndex(index)); +} + /*! \internal @@ -3385,17 +3400,49 @@ void QFileDialogPrivate::_q_pathChanged(const QString &newPath) qFileDialogUi->sidebar->selectUrl(QUrl::fromLocalFile(newPath)); q->setHistory(qFileDialogUi->lookInCombo->history()); - if (currentHistoryLocation < 0 || currentHistory.value(currentHistoryLocation) != QDir::toNativeSeparators(newPath)) { + const QString newNativePath = QDir::toNativeSeparators(newPath); + + // equal paths indicate this was invoked by _q_navigateBack/Forward() + if (currentHistoryLocation < 0 || currentHistory.value(currentHistoryLocation).path != newNativePath) { + if (currentHistoryLocation >= 0) + saveHistorySelection(); while (currentHistoryLocation >= 0 && currentHistoryLocation + 1 < currentHistory.count()) { currentHistory.removeLast(); } - currentHistory.append(QDir::toNativeSeparators(newPath)); + currentHistory.append({newNativePath, PersistentModelIndexList()}); ++currentHistoryLocation; } qFileDialogUi->forwardButton->setEnabled(currentHistory.size() - currentHistoryLocation > 1); qFileDialogUi->backButton->setEnabled(currentHistoryLocation > 0); } +void QFileDialogPrivate::navigate(HistoryItem &historyItem) +{ + Q_Q(QFileDialog); + q->setDirectory(historyItem.path); + // Restore selection unless something has changed in the file system + if (qFileDialogUi.isNull() || historyItem.selection.isEmpty()) + return; + if (std::any_of(historyItem.selection.cbegin(), historyItem.selection.cend(), + [](const QPersistentModelIndex &i) { return !i.isValid(); })) { + historyItem.selection.clear(); + return; + } + + QAbstractItemView *view = q->viewMode() == QFileDialog::List + ? static_cast<QAbstractItemView *>(qFileDialogUi->listView) + : static_cast<QAbstractItemView *>(qFileDialogUi->treeView); + auto selectionModel = view->selectionModel(); + const QItemSelectionModel::SelectionFlags flags = QItemSelectionModel::Select + | QItemSelectionModel::Rows; + selectionModel->select(historyItem.selection.constFirst(), + flags | QItemSelectionModel::Clear | QItemSelectionModel::Current); + for (int i = 1, size = historyItem.selection.size(); i < size; ++i) + selectionModel->select(historyItem.selection.at(i), flags); + + view->scrollTo(historyItem.selection.constFirst()); +} + /*! \internal @@ -3403,11 +3450,9 @@ void QFileDialogPrivate::_q_pathChanged(const QString &newPath) */ void QFileDialogPrivate::_q_navigateBackward() { - Q_Q(QFileDialog); if (!currentHistory.isEmpty() && currentHistoryLocation > 0) { - --currentHistoryLocation; - QString previousHistory = currentHistory.at(currentHistoryLocation); - q->setDirectory(previousHistory); + saveHistorySelection(); + navigate(currentHistory[--currentHistoryLocation]); } } @@ -3418,11 +3463,9 @@ void QFileDialogPrivate::_q_navigateBackward() */ void QFileDialogPrivate::_q_navigateForward() { - Q_Q(QFileDialog); if (!currentHistory.isEmpty() && currentHistoryLocation < currentHistory.size() - 1) { - ++currentHistoryLocation; - QString nextHistory = currentHistory.at(currentHistoryLocation); - q->setDirectory(nextHistory); + saveHistorySelection(); + navigate(currentHistory[++currentHistoryLocation]); } } @@ -3633,12 +3676,13 @@ void QFileDialogPrivate::_q_autoCompleteFileName(const QString &text) if (oldFiles.removeAll(idx) == 0) newFiles.append(idx); } - for (int i = 0; i < newFiles.count(); ++i) - select(newFiles.at(i)); - if (lineEdit()->hasFocus()) - for (int i = 0; i < oldFiles.count(); ++i) - qFileDialogUi->listView->selectionModel()->select(oldFiles.at(i), - QItemSelectionModel::Toggle | QItemSelectionModel::Rows); + for (const auto &newFile : qAsConst(newFiles)) + select(newFile); + if (lineEdit()->hasFocus()) { + auto *sm = qFileDialogUi->listView->selectionModel(); + for (const auto &oldFile : qAsConst(oldFiles)) + sm->select(oldFile, QItemSelectionModel::Toggle | QItemSelectionModel::Rows); + } } } @@ -3992,7 +4036,7 @@ bool QFileDialogPrivate::itemViewKeyboardEvent(QKeyEvent *event) { return true; case Qt::Key_Back: #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) + if (QApplicationPrivate::keypadNavigationEnabled()) return false; #endif case Qt::Key_Left: |