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 <richard.gustavsen@qt.io>
Friedemann Kleint 2019-05-16 15:17:12 +02:00
parent 837c388dd3
commit ea9469f2b6
1 changed files with 35 additions and 5 deletions

View File

@ -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<const QFileSystemModel *>(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.