--- a/src/gui/util/qcompleter.cpp Wed Jun 23 19:07:03 2010 +0300
+++ b/src/gui/util/qcompleter.cpp Tue Jul 06 15:10:48 2010 +0300
@@ -62,7 +62,7 @@
\snippet doc/src/snippets/code/src_gui_util_qcompleter.cpp 0
- A QDirModel can be used to provide auto completion of file names.
+ A QFileSystemModel can be used to provide auto completion of file names.
For example:
\snippet doc/src/snippets/code/src_gui_util_qcompleter.cpp 1
@@ -120,7 +120,7 @@
completion is then performed one level at a time.
Let's take the example of a user typing in a file system path.
- The model is a (hierarchical) QDirModel. The completion
+ The model is a (hierarchical) QFileSystemModel. The completion
occurs for every element in the path. For example, if the current
text is \c C:\Wind, QCompleter might suggest \c Windows to
complete the current path element. Similarly, if the current text
@@ -130,12 +130,12 @@
split the path into a list of strings that are matched at each level.
For \c C:\Windows\Sy, it needs to be split as "C:", "Windows" and "Sy".
The default implementation of splitPath(), splits the completionPrefix
- using QDir::separator() if the model is a QDirModel.
+ using QDir::separator() if the model is a QFileSystemModel.
To provide completions, QCompleter needs to know the path from an index.
This is provided by pathFromIndex(). The default implementation of
pathFromIndex(), returns the data for the \l{Qt::EditRole}{edit role}
- for list models and the absolute file path if the mode is a QDirModel.
+ for list models and the absolute file path if the mode is a QFileSystemModel.
\sa QAbstractItemModel, QLineEdit, QComboBox, {Completer Example}
*/
@@ -147,6 +147,7 @@
#include "QtGui/qscrollbar.h"
#include "QtGui/qstringlistmodel.h"
#include "QtGui/qdirmodel.h"
+#include "QtGui/qfilesystemmodel.h"
#include "QtGui/qheaderview.h"
#include "QtGui/qlistview.h"
#include "QtGui/qapplication.h"
@@ -470,9 +471,13 @@
QAbstractItemModel *source = c->proxy->sourceModel();
if (curParts.count() <= 1 || c->proxy->showAll || !source)
return QMatchData();
- bool dirModel = false;
+ bool isDirModel = false;
+ bool isFsModel = false;
#ifndef QT_NO_DIRMODEL
- dirModel = (qobject_cast<QDirModel *>(source) != 0);
+ isDirModel = (qobject_cast<QDirModel *>(source) != 0);
+#endif
+#ifndef QT_NO_FILESYSTEMMODEL
+ isFsModel = (qobject_cast<QFileSystemModel *>(source) != 0);
#endif
QVector<int> v;
QIndexMapper im(v);
@@ -482,7 +487,7 @@
QString str = source->index(i, c->column).data().toString();
if (str.startsWith(c->prefix, c->cs)
#if (!defined(Q_OS_WIN) || defined(Q_OS_WINCE)) && !defined(Q_OS_SYMBIAN)
- && (!dirModel || QDir::toNativeSeparators(str) != QDir::separator())
+ && ((!isFsModel && !isDirModel) || QDir::toNativeSeparators(str) != QDir::separator())
#endif
)
m.indices.append(i);
@@ -843,6 +848,13 @@
completion += QDir::separator();
}
#endif
+#ifndef QT_NO_FILESYSTEMMODEL
+ // add a trailing separator in inline
+ if (mode == QCompleter::InlineCompletion) {
+ if (qobject_cast<QFileSystemModel *>(proxy->sourceModel()) && QFileInfo(completion).isDir())
+ completion += QDir::separator();
+ }
+#endif
}
if (highlighted) {
@@ -866,7 +878,7 @@
const QRect screen = QApplication::desktop()->availableGeometry(widget);
Qt::LayoutDirection dir = widget->layoutDirection();
QPoint pos;
- int rw, rh, w;
+ int rh, w;
int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3;
QScrollBar *hsb = popup->horizontalScrollBar();
if (hsb && hsb->isVisible())
@@ -874,21 +886,30 @@
if (rect.isValid()) {
rh = rect.height();
- w = rw = rect.width();
+ w = rect.width();
pos = widget->mapToGlobal(dir == Qt::RightToLeft ? rect.bottomRight() : rect.bottomLeft());
} else {
rh = widget->height();
- rw = widget->width();
pos = widget->mapToGlobal(QPoint(0, widget->height() - 2));
w = widget->width();
}
- if ((pos.x() + rw) > (screen.x() + screen.width()))
+ if (w > screen.width())
+ w = screen.width();
+ if ((pos.x() + w) > (screen.x() + screen.width()))
pos.setX(screen.x() + screen.width() - w);
if (pos.x() < screen.x())
pos.setX(screen.x());
- if (((pos.y() + rh) > (screen.y() + screen.height())) && ((pos.y() - h - rh) >= 0))
- pos.setY(pos.y() - qMax(h, popup->minimumHeight()) - rh + 2);
+
+ int top = pos.y() - rh - screen.top() + 2;
+ int bottom = screen.bottom() - pos.y();
+ h = qMax(h, popup->minimumHeight());
+ if (h > bottom) {
+ h = qMin(qMax(top, bottom), h);
+
+ if (top > bottom)
+ pos.setY(pos.y() - h - rh + 2);
+ }
popup->setGeometry(pos.x(), pos.y(), w, h);
@@ -896,6 +917,14 @@
popup->show();
}
+void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &path)
+{
+ Q_Q(QCompleter);
+ //the path given by QFileSystemModel does not end with /
+ if (!q->completionPrefix().isEmpty() && q->completionPrefix() != path + QLatin1Char('/'))
+ q->complete();
+}
+
/*!
Constructs a completer object with the given \a parent.
*/
@@ -976,7 +1005,7 @@
be list model or a tree model. If a model has been already previously set
and it has the QCompleter as its parent, it is deleted.
- For convenience, if \a model is a QDirModel, QCompleter switches its
+ For convenience, if \a model is a QFileSystemModel, QCompleter switches its
caseSensitivity to Qt::CaseInsensitive on Windows and Qt::CaseSensitive
on other platforms.
@@ -1000,6 +1029,18 @@
#endif
}
#endif // QT_NO_DIRMODEL
+#ifndef QT_NO_FILESYSTEMMODEL
+ QFileSystemModel *fsModel = qobject_cast<QFileSystemModel *>(model);
+ if (fsModel) {
+#if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN)
+ setCaseSensitivity(Qt::CaseInsensitive);
+#else
+ setCaseSensitivity(Qt::CaseSensitive);
+#endif
+ setCompletionRole(QFileSystemModel::FileNameRole);
+ connect(fsModel, SIGNAL(directoryLoaded(QString)), this, SLOT(_q_fileSystemModelDirectoryLoaded(QString)));
+ }
+#endif // QT_NO_FILESYSTEMMODEL
}
/*!
@@ -1083,7 +1124,7 @@
delete d->popup;
if (popup->model() != d->proxy)
popup->setModel(d->proxy);
-#ifdef Q_OS_MAC
+#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA)
popup->show();
#else
popup->hide();
@@ -1631,10 +1672,11 @@
The default implementation returns the \l{Qt::EditRole}{edit role} of the
item for list models. It returns the absolute file path if the model is a
- QDirModel.
+ QFileSystemModel.
\sa splitPath()
*/
+
QString QCompleter::pathFromIndex(const QModelIndex& index) const
{
Q_D(const QCompleter);
@@ -1644,16 +1686,27 @@
QAbstractItemModel *sourceModel = d->proxy->sourceModel();
if (!sourceModel)
return QString();
+ bool isDirModel = false;
+ bool isFsModel = false;
#ifndef QT_NO_DIRMODEL
- QDirModel *dirModel = qobject_cast<QDirModel *>(sourceModel);
- if (!dirModel)
+ isDirModel = qobject_cast<QDirModel *>(d->proxy->sourceModel()) != 0;
#endif
+#ifndef QT_NO_FILESYSTEMMODEL
+ isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != 0;
+#endif
+ if (!isDirModel && !isFsModel)
return sourceModel->data(index, d->role).toString();
QModelIndex idx = index;
QStringList list;
do {
- QString t = sourceModel->data(idx, Qt::EditRole).toString();
+ QString t;
+ if (isDirModel)
+ t = sourceModel->data(idx, Qt::EditRole).toString();
+#ifndef QT_NO_FILESYSTEMMODEL
+ else
+ t = sourceModel->data(idx, QFileSystemModel::FileNameRole).toString();
+#endif
list.prepend(t);
QModelIndex parent = idx.parent();
idx = parent.sibling(parent.row(), index.column());
@@ -1673,7 +1726,7 @@
in the model().
The default implementation of splitPath() splits a file system path based on
- QDir::separator() when the sourceModel() is a QDirModel.
+ QDir::separator() when the sourceModel() is a QFileSystemModel.
When used with list models, the first item in the returned list is used for
matching.
@@ -1683,12 +1736,19 @@
QStringList QCompleter::splitPath(const QString& path) const
{
bool isDirModel = false;
+ bool isFsModel = false;
#ifndef QT_NO_DIRMODEL
Q_D(const QCompleter);
isDirModel = qobject_cast<QDirModel *>(d->proxy->sourceModel()) != 0;
#endif
+#ifndef QT_NO_FILESYSTEMMODEL
+#ifdef QT_NO_DIRMODEL
+ Q_D(const QCompleter);
+#endif
+ isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != 0;
+#endif
- if (!isDirModel || path.isEmpty())
+ if ((!isDirModel && !isFsModel) || path.isEmpty())
return QStringList(completionPrefix());
QString pathCopy = QDir::toNativeSeparators(path);