From 84ce5022ce9e65d753354bc472b7f28fbc014ebf Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 9 Nov 2018 11:26:00 +0100 Subject: QFileDialog (widgets-based): Remember selection in history Extend the history by a persistent model index list reflecting the selection. [ChangeLog][QtWidgets][QFileDialog] The widgets-based dialog now remembers the selected files when navigating the history Fixes: QTBUG-71415 Change-Id: I86774439be070c1b922acd0e9a27d029f02f68d3 Reviewed-by: Shawn Rutledge --- src/widgets/dialogs/qfiledialog.cpp | 62 +++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 10 deletions(-) (limited to 'src/widgets/dialogs/qfiledialog.cpp') diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index f772eb1241..fcac12068d 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -77,6 +77,8 @@ #include #endif +#include + QT_BEGIN_NAMESPACE Q_GLOBAL_STATIC(QUrl, lastVisitedDir) @@ -3372,6 +3374,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 +3399,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(qFileDialogUi->listView) + : static_cast(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 +3449,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 +3462,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]); } } -- cgit v1.2.3