From ea9469f2b6b7f78f66c22f391b80b3374a4737ba Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 16 May 2019 15:17:12 +0200 Subject: QCompleter: Fix completion on QFileSystemModel Fix the condition introduced by that determines whether a completion is started on signal QFileSystemModel::directoryLoaded() (introduced by 416ec00e7c859a844a5bcb24c7a31147aed974c / Qt 4). Observe case sensitivity and the native separator and return true for root directories. Task-number: QTBUG-38014 Task-number: QTBUG-14292 Change-Id: Ie425c04d2df256248e84250ba777793a8106a738 Reviewed-by: Richard Moe Gustavsen --- src/widgets/util/qcompleter.cpp | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) (limited to 'src/widgets/util') diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp index 0daa4a4b41..e41f7e7573 100644 --- a/src/widgets/util/qcompleter.cpp +++ b/src/widgets/util/qcompleter.cpp @@ -976,18 +976,48 @@ void QCompleterPrivate::showPopup(const QRect& rect) popup->show(); } +#if QT_CONFIG(filesystemmodel) +static bool isRoot(const QFileSystemModel *model, const QString &path) +{ + const auto index = model->index(path); + return index.isValid() && model->fileInfo(index).isRoot(); +} + +static bool completeOnLoaded(const QFileSystemModel *model, + const QString &nativePrefix, + const QString &path, + Qt::CaseSensitivity caseSensitivity) +{ + const auto pathSize = path.size(); + const auto prefixSize = nativePrefix.size(); + if (prefixSize < pathSize) + return false; + const QString prefix = QDir::fromNativeSeparators(nativePrefix); + if (prefixSize == pathSize) + return path.compare(prefix, caseSensitivity) == 0 && isRoot(model, path); + // The user is typing something within that directory and is not in a subdirectory yet. + const auto separator = QLatin1Char('/'); + return prefix.startsWith(path, caseSensitivity) && prefix.at(pathSize) == separator + && !prefix.rightRef(prefixSize - pathSize - 1).contains(separator); +} + void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &path) { Q_Q(QCompleter); // Slot called when QFileSystemModel has finished loading. // If we hide the popup because there was no match because the model was not loaded yet, - // we re-start the completion when we get the results - if (hiddenBecauseNoMatch - && prefix.startsWith(path) && prefix != (path + QLatin1Char('/')) - && widget) { - q->complete(); + // we re-start the completion when we get the results (unless triggered by + // something else, see QTBUG-14292). + if (hiddenBecauseNoMatch && widget) { + if (auto model = qobject_cast(proxy->sourceModel())) { + if (completeOnLoaded(model, prefix, path, cs)) + q->complete(); + } } } +#else // QT_CONFIG(filesystemmodel) +void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &) {} +#endif /*! Constructs a completer object with the given \a parent. -- cgit v1.2.3