Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/dialogs/qfilesystemmodel.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    5252#include <qt_windows.h>
    5353#endif
     54#ifdef Q_OS_WIN32
     55#include <QtCore/QVarLengthArray>
     56#endif
    5457
    5558QT_BEGIN_NAMESPACE
     
    7780    directories. In the simplest case, it can be used with a suitable display
    7881    widget as part of a browser or filter.
    79 
    80     QFileSystemModel will not fetch any files or directories until setRootPath
    81     is called.  This will prevent any unnecessary querying on the file system
    82     until that point such as listing the drives on Windows.
    83 
    84     Unlike the QDirModel, QFileSystemModel uses a separate thread to populate
    85     itself so it will not cause the main thread to hang as the file system
    86     is being queried.  Calls to rowCount() will return 0 until the model
    87     populates a directory.
    88 
    89     QFileSystemModel keeps a cache with file information. The cache is
    90     automatically kept up to date using the QFileSystemWatcher.
    9182
    9283    QFileSystemModel can be accessed using the standard interface provided by
     
    9990    \note QFileSystemModel requires an instance of a GUI application.
    10091
     92    \section1 Example Usage
     93
     94    A directory model that displays the contents of a default directory
     95    is usually constructed with a parent object:
     96
     97    \snippet doc/src/snippets/shareddirmodel/main.cpp 2
     98
     99    A tree view can be used to display the contents of the model
     100
     101    \snippet doc/src/snippets/shareddirmodel/main.cpp 4
     102
     103    and the contents of a particular directory can be displayed by
     104    setting the tree view's root index:
     105
     106    \snippet doc/src/snippets/shareddirmodel/main.cpp 7
     107
     108    The view's root index can be used to control how much of a
     109    hierarchical model is displayed. QDirModel provides a convenience
     110    function that returns a suitable model index for a path to a
     111    directory within the model.
     112
     113    \section1 Caching and Performance
     114
     115    QFileSystemModel will not fetch any files or directories until setRootPath()
     116    is called.  This will prevent any unnecessary querying on the file system
     117    until that point such as listing the drives on Windows.
     118
     119    Unlike QDirModel, QFileSystemModel uses a separate thread to populate
     120    itself so it will not cause the main thread to hang as the file system
     121    is being queried.  Calls to rowCount() will return 0 until the model
     122    populates a directory.
     123
     124    QFileSystemModel keeps a cache with file information. The cache is
     125    automatically kept up to date using the QFileSystemWatcher.
     126
    101127    \sa {Model Classes}
    102128*/
     
    148174    This signal is emitted whenever a file with the \a oldName is successfully
    149175    renamed to \a newName.  The file is located in in the directory \a path.
     176*/
     177
     178/*!
     179    \since 4.7
     180    \fn void QFileSystemModel::directoryLoaded(const QString &path)
     181
     182    This signal is emitted when the gatherer thread has finished to load the \a path.
     183
    150184*/
    151185
     
    271305}
    272306
    273 #ifdef Q_OS_WIN
     307#ifdef Q_OS_WIN32
    274308static QString qt_GetLongPathName(const QString &strShortPath)
    275309{
    276     QString longPath;
    277     int i = 0;
    278     if (strShortPath == QLatin1String(".")
    279         || (strShortPath.startsWith(QLatin1String("//")))
    280         || (strShortPath.startsWith(QLatin1String("\\\\")))) // unc
     310    if (strShortPath.isEmpty()
     311        || strShortPath == QLatin1String(".") || strShortPath == QLatin1String(".."))
    281312        return strShortPath;
    282     QString::const_iterator it = strShortPath.constBegin();
    283     QString::const_iterator constEnd = strShortPath.constEnd();
    284     do {
    285         bool isSep = (*it == QLatin1Char('\\') || *it == QLatin1Char('/'));
    286         if (isSep || it == constEnd) {
    287             QString section = (it == constEnd ? strShortPath : strShortPath.left(i));
    288             // FindFirstFile does not handle volumes ("C:"), so we have to catch that ourselves.
    289             if (section.endsWith(QLatin1Char(':'))) {
    290                 longPath.append(section.toUpper());
    291             } else {
    292                 HANDLE h;
    293 #ifndef Q_OS_WINCE
    294                 //We add the extend length prefix to handle long path
    295                 QString longSection = QLatin1String("\\\\?\\")+QDir::toNativeSeparators(section);
    296 #else
    297                 QString longSection = QDir::toNativeSeparators(section);
    298 #endif
    299                 WIN32_FIND_DATA findData;
    300                 h = ::FindFirstFile((wchar_t*)longSection.utf16(), &findData);
    301                 if (h != INVALID_HANDLE_VALUE) {
    302                     longPath.append(QString::fromWCharArray(findData.cFileName));
    303                     ::FindClose(h);
    304                 } else {
    305                     longPath.append(section);
    306                     break;
    307                 }
    308             }
    309             if (it != constEnd)
    310                 longPath.append(*it);
    311             else
    312                 break;
    313         }
    314         ++it;
    315         if (isSep && it == constEnd)    // break out if the last character is a separator
    316             break;
    317         ++i;
    318     } while (true);
    319     return longPath;
     313    if (strShortPath.length() == 2 && strShortPath.endsWith(QLatin1Char(':')))
     314        return strShortPath.toUpper();
     315    const QString absPath = QDir(strShortPath).absolutePath();
     316    if (absPath.startsWith(QLatin1String("//"))
     317        || absPath.startsWith(QLatin1String("\\\\"))) // unc
     318        return QDir::fromNativeSeparators(absPath);
     319    if (absPath.startsWith(QLatin1Char('/')))
     320        return QString();
     321    const QString inputString = QLatin1String("\\\\?\\") + QDir::toNativeSeparators(absPath);
     322    QVarLengthArray<TCHAR, MAX_PATH> buffer(MAX_PATH);
     323    DWORD result = ::GetLongPathName((wchar_t*)inputString.utf16(),
     324                                     buffer.data(),
     325                                     buffer.size());
     326    if (result > DWORD(buffer.size())) {
     327        buffer.resize(result);
     328        result = ::GetLongPathName((wchar_t*)inputString.utf16(),
     329                                   buffer.data(),
     330                                   buffer.size());
     331    }
     332    if (result > 4) {
     333        QString longPath = QString::fromWCharArray(buffer.data() + 4); // ignoring prefix
     334        longPath[0] = longPath.at(0).toUpper(); // capital drive letters
     335        return QDir::fromNativeSeparators(longPath);
     336    } else {
     337        return QDir::fromNativeSeparators(strShortPath);
     338    }
    320339}
    321340#endif
     
    335354    // Construct the nodes up to the new root path if they need to be built
    336355    QString absolutePath;
    337 #ifdef Q_OS_WIN
     356#ifdef Q_OS_WIN32
    338357    QString longPath = qt_GetLongPathName(path);
    339358#else
     
    673692    case Qt::DisplayRole:
    674693        switch (index.column()) {
    675         case 0: return d->name(index);
     694        case 0: return d->displayName(index);
    676695        case 1: return d->size(index);
    677696        case 2: return d->type(index);
     
    789808            return resolvedSymLinks[fullPath];
    790809    }
    791     // ### TODO it would be nice to grab the volume name if dirNode->parent == root
    792810    return dirNode->fileName;
     811}
     812
     813/*!
     814    \internal
     815*/
     816QString QFileSystemModelPrivate::displayName(const QModelIndex &index) const
     817{
     818#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
     819    QFileSystemNode *dirNode = node(index);
     820    if (!dirNode->volumeName.isNull())
     821        return dirNode->volumeName + QLatin1String(" (") + name(index) + QLatin1Char(')');
     822#endif
     823    return name(index);
    793824}
    794825
     
    13371368    Q_D(QFileSystemModel);
    13381369#ifdef Q_OS_WIN
    1339     QString longNewPath = QDir::fromNativeSeparators(qt_GetLongPathName(newPath));
     1370#ifdef Q_OS_WIN32
     1371    QString longNewPath = qt_GetLongPathName(newPath);
     1372#else
     1373    QString longNewPath = QDir::fromNativeSeparators(newPath);
     1374#endif
    13401375#else
    13411376    QString longNewPath = newPath;
     
    16491684#ifndef QT_NO_FILESYSTEMWATCHER
    16501685    node->populate(info);
     1686#endif
     1687#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
     1688    //The parentNode is "" so we are listing the drives
     1689    if (parentNode->fileName.isEmpty()) {
     1690        wchar_t name[MAX_PATH + 1];
     1691        //GetVolumeInformation requires to add trailing backslash
     1692        const QString nodeName = fileName + QLatin1String("\\");
     1693        BOOL success = ::GetVolumeInformation((wchar_t *)(nodeName.utf16()),
     1694                name, MAX_PATH + 1, NULL, 0, NULL, NULL, 0);
     1695        if (success && name[0])
     1696            node->volumeName = QString::fromWCharArray(name);
     1697    }
    16511698#endif
    16521699    parentNode->children.insert(fileName, node);
     
    18861933    q->connect(&fileInfoGatherer, SIGNAL(nameResolved(QString,QString)),
    18871934            q, SLOT(_q_resolvedName(QString,QString)));
     1935    q->connect(&fileInfoGatherer, SIGNAL(directoryLoaded(QString)),
     1936               q, SIGNAL(directoryLoaded(QString)));
    18881937    q->connect(&delayedSortTimer, SIGNAL(timeout()), q, SLOT(_q_performDelayedSort()), Qt::QueuedConnection);
     1938
     1939    QHash<int, QByteArray> roles = q->roleNames();
     1940    roles.insertMulti(QFileSystemModel::FileIconRole, "fileIcon"); // == Qt::decoration
     1941    roles.insert(QFileSystemModel::FilePathRole, "filePath");
     1942    roles.insert(QFileSystemModel::FileNameRole, "fileName");
     1943    roles.insert(QFileSystemModel::FilePermissions, "filePermissions");
     1944    q->setRoleNames(roles);
    18891945}
    18901946
Note: See TracChangeset for help on using the changeset viewer.