Skip to content

Commit

Permalink
QCompleter: Fix completion on QFileSystemModel
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
FriedemannKleint committed May 21, 2019
1 parent 837c388 commit ea9469f
Showing 1 changed file with 35 additions and 5 deletions.
40 changes: 35 additions & 5 deletions src/widgets/util/qcompleter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit ea9469f

Please sign in to comment.