src/corelib/io/qdir.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtCore module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qplatformdefs.h"
       
    43 #include "qdir.h"
       
    44 #include "qabstractfileengine.h"
       
    45 #ifndef QT_NO_DEBUG_STREAM
       
    46 #include "qdebug.h"
       
    47 #endif
       
    48 #include "qdiriterator.h"
       
    49 #include "qfsfileengine.h"
       
    50 #include "qdatetime.h"
       
    51 #include "qstring.h"
       
    52 #include "qregexp.h"
       
    53 #include "qvector.h"
       
    54 #include "qalgorithms.h"
       
    55 #ifdef QT_BUILD_CORE_LIB
       
    56 # include "qresource.h"
       
    57 #endif
       
    58 
       
    59 #include "qvarlengtharray.h"
       
    60 
       
    61 #include "private/qcoreglobaldata_p.h"
       
    62 #include <stdlib.h>
       
    63 
       
    64 QT_BEGIN_NAMESPACE
       
    65 
       
    66 static QString driveSpec(const QString &path)
       
    67 {
       
    68 #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
       
    69     if (path.size() < 2)
       
    70         return QString();
       
    71     char c = path.at(0).toAscii();
       
    72     if (c < 'a' && c > 'z' && c < 'A' && c > 'Z')
       
    73         return QString();
       
    74     if (path.at(1).toAscii() != ':')
       
    75         return QString();
       
    76     return path.mid(0, 2);
       
    77 #else
       
    78     Q_UNUSED(path);
       
    79     return QString();
       
    80 #endif
       
    81 }
       
    82 
       
    83 //************* QDirPrivate
       
    84 class QDirPrivate
       
    85 {
       
    86     QDir *q_ptr;
       
    87     Q_DECLARE_PUBLIC(QDir)
       
    88 
       
    89     friend struct QScopedPointerDeleter<QDirPrivate>;
       
    90 protected:
       
    91     QDirPrivate(QDir*, const QDir *copy=0);
       
    92     ~QDirPrivate();
       
    93 
       
    94     QString initFileEngine(const QString &file);
       
    95 
       
    96     void updateFileLists() const;
       
    97     void sortFileList(QDir::SortFlags, QFileInfoList &, QStringList *, QFileInfoList *) const;
       
    98 
       
    99 private:
       
   100 #ifdef QT3_SUPPORT
       
   101     QChar filterSepChar;
       
   102     bool matchAllDirs;
       
   103 #endif
       
   104     static inline QChar getFilterSepChar(const QString &nameFilter)
       
   105     {
       
   106         QChar sep(QLatin1Char(';'));
       
   107         int i = nameFilter.indexOf(sep, 0);
       
   108         if (i == -1 && nameFilter.indexOf(QLatin1Char(' '), 0) != -1)
       
   109             sep = QChar(QLatin1Char(' '));
       
   110         return sep;
       
   111     }
       
   112     static inline QStringList splitFilters(const QString &nameFilter, QChar sep=0) {
       
   113         if(sep == 0)
       
   114             sep = getFilterSepChar(nameFilter);
       
   115         QStringList ret = nameFilter.split(sep);
       
   116         for(int i = 0; i < ret.count(); i++)
       
   117             ret[i] = ret[i].trimmed();
       
   118         return ret;
       
   119     }
       
   120 
       
   121     struct Data {
       
   122         inline Data()
       
   123             : ref(1), fileEngine(0)
       
   124         { clear(); }
       
   125         inline Data(const Data &copy)
       
   126             : ref(1), path(copy.path), nameFilters(copy.nameFilters), sort(copy.sort),
       
   127               filters(copy.filters), fileEngine(0)
       
   128         { clear(); }
       
   129         inline ~Data()
       
   130         { delete fileEngine; }
       
   131 
       
   132         inline void clear() {
       
   133             listsDirty = 1;
       
   134         }
       
   135         mutable QAtomicInt ref;
       
   136 
       
   137         QString path;
       
   138         QStringList nameFilters;
       
   139         QDir::SortFlags sort;
       
   140         QDir::Filters filters;
       
   141 
       
   142         mutable QAbstractFileEngine *fileEngine;
       
   143 
       
   144         mutable uint listsDirty : 1;
       
   145         mutable QStringList files;
       
   146         mutable QFileInfoList fileInfos;
       
   147     } *data;
       
   148     inline void setPath(const QString &p)
       
   149     {
       
   150         detach(false);
       
   151         QString path = p;
       
   152         if ((path.endsWith(QLatin1Char('/')) || path.endsWith(QLatin1Char('\\')))
       
   153                 && path.length() > 1) {
       
   154 #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
       
   155             if (!(path.length() == 3 && path.at(1) == QLatin1Char(':')))
       
   156 #endif
       
   157                 path.truncate(path.length() - 1);
       
   158         }
       
   159         if(!data->fileEngine || !QDir::isRelativePath(path))
       
   160             path = initFileEngine(path);
       
   161         data->fileEngine->setFileName(path);
       
   162         // set the path to be the qt friendly version so then we can operate on it using just /
       
   163         data->path = data->fileEngine->fileName(QAbstractFileEngine::DefaultName);
       
   164         data->clear();
       
   165     }
       
   166     inline void reset() {
       
   167         detach();
       
   168         data->clear();
       
   169     }
       
   170     void detach(bool createFileEngine = true);
       
   171 };
       
   172 
       
   173 QDirPrivate::QDirPrivate(QDir *qq, const QDir *copy) : q_ptr(qq)
       
   174 #ifdef QT3_SUPPORT
       
   175                                                      , filterSepChar(0)
       
   176                                                      , matchAllDirs(false)
       
   177 #endif
       
   178 {
       
   179     if(copy) {
       
   180         copy->d_func()->data->ref.ref();
       
   181         data = copy->d_func()->data;
       
   182     } else {
       
   183         data = new QDirPrivate::Data;
       
   184         data->clear();
       
   185     }
       
   186 }
       
   187 
       
   188 QDirPrivate::~QDirPrivate()
       
   189 {
       
   190     if (!data->ref.deref())
       
   191         delete data;
       
   192     data = 0;
       
   193     q_ptr = 0;
       
   194 }
       
   195 
       
   196 /* For sorting */
       
   197 struct QDirSortItem {
       
   198     mutable QString filename_cache;
       
   199     mutable QString suffix_cache;
       
   200     QFileInfo item;
       
   201 };
       
   202 
       
   203 
       
   204 class QDirSortItemComparator {
       
   205     int qt_cmp_si_sort_flags;
       
   206 public:
       
   207     QDirSortItemComparator(int flags) : qt_cmp_si_sort_flags(flags) {}
       
   208     bool operator()(const QDirSortItem &, const QDirSortItem &);
       
   209 };
       
   210 
       
   211 bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortItem &n2)
       
   212 {
       
   213     const QDirSortItem* f1 = &n1;
       
   214     const QDirSortItem* f2 = &n2;
       
   215 
       
   216     if ((qt_cmp_si_sort_flags & QDir::DirsFirst) && (f1->item.isDir() != f2->item.isDir()))
       
   217         return f1->item.isDir();
       
   218     if ((qt_cmp_si_sort_flags & QDir::DirsLast) && (f1->item.isDir() != f2->item.isDir()))
       
   219         return !f1->item.isDir();
       
   220 
       
   221     int r = 0;
       
   222     int sortBy = (qt_cmp_si_sort_flags & QDir::SortByMask)
       
   223                  | (qt_cmp_si_sort_flags & QDir::Type);
       
   224 
       
   225     switch (sortBy) {
       
   226       case QDir::Time:
       
   227         r = f1->item.lastModified().secsTo(f2->item.lastModified());
       
   228         break;
       
   229       case QDir::Size:
       
   230           r = int(qBound<qint64>(-1, f2->item.size() - f1->item.size(), 1));
       
   231         break;
       
   232       case QDir::Type:
       
   233       {
       
   234         bool ic = qt_cmp_si_sort_flags & QDir::IgnoreCase;
       
   235 
       
   236         if (f1->suffix_cache.isNull())
       
   237             f1->suffix_cache = ic ? f1->item.suffix().toLower()
       
   238                                : f1->item.suffix();
       
   239         if (f2->suffix_cache.isNull())
       
   240             f2->suffix_cache = ic ? f2->item.suffix().toLower()
       
   241                                : f2->item.suffix();
       
   242 
       
   243 	r = qt_cmp_si_sort_flags & QDir::LocaleAware
       
   244             ? f1->suffix_cache.localeAwareCompare(f2->suffix_cache)
       
   245             : f1->suffix_cache.compare(f2->suffix_cache);
       
   246       }
       
   247         break;
       
   248       default:
       
   249         ;
       
   250     }
       
   251 
       
   252     if (r == 0 && sortBy != QDir::Unsorted) {
       
   253         // Still not sorted - sort by name
       
   254         bool ic = qt_cmp_si_sort_flags & QDir::IgnoreCase;
       
   255 
       
   256         if (f1->filename_cache.isNull())
       
   257             f1->filename_cache = ic ? f1->item.fileName().toLower()
       
   258                                     : f1->item.fileName();
       
   259         if (f2->filename_cache.isNull())
       
   260             f2->filename_cache = ic ? f2->item.fileName().toLower()
       
   261                                     : f2->item.fileName();
       
   262 
       
   263 	r = qt_cmp_si_sort_flags & QDir::LocaleAware
       
   264             ? f1->filename_cache.localeAwareCompare(f2->filename_cache)
       
   265             : f1->filename_cache.compare(f2->filename_cache);
       
   266     }
       
   267     if (r == 0) // Enforce an order - the order the items appear in the array
       
   268         r = (&n1) - (&n2);
       
   269     if (qt_cmp_si_sort_flags & QDir::Reversed)
       
   270         return r > 0;
       
   271     return r < 0;
       
   272 }
       
   273 
       
   274 inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l,
       
   275                                       QStringList *names, QFileInfoList *infos) const
       
   276 {
       
   277     if(names)
       
   278         names->clear();
       
   279     if(infos)
       
   280         infos->clear();
       
   281     int n = l.size();
       
   282     if(n > 0) {
       
   283         if (n == 1 || (sort & QDir::SortByMask) == QDir::Unsorted) {
       
   284             if(infos)
       
   285                 *infos = l;
       
   286             if(names) {
       
   287                 for (int i = 0; i < n; ++i)
       
   288                     names->append(l.at(i).fileName());
       
   289             }
       
   290         } else {
       
   291             QScopedArrayPointer<QDirSortItem> si(new QDirSortItem[n]);
       
   292             for (int i = 0; i < n; ++i)
       
   293                 si[i].item = l.at(i);
       
   294             qSort(si.data(), si.data()+n, QDirSortItemComparator(sort));
       
   295             // put them back in the list(s)
       
   296             if(infos) {
       
   297                 for (int i = 0; i < n; ++i)
       
   298                     infos->append(si[i].item);
       
   299             }
       
   300             if(names) {
       
   301                 for (int i = 0; i < n; ++i)
       
   302                     names->append(si[i].item.fileName());
       
   303             }
       
   304         }
       
   305     }
       
   306 }
       
   307 
       
   308 inline void QDirPrivate::updateFileLists() const
       
   309 {
       
   310     if(data->listsDirty) {
       
   311         QFileInfoList l;
       
   312         QDirIterator it(data->path, data->nameFilters, data->filters);
       
   313         while (it.hasNext()) {
       
   314             it.next();
       
   315             l.append(it.fileInfo());
       
   316         }
       
   317         sortFileList(data->sort, l, &data->files, &data->fileInfos);
       
   318         data->listsDirty = 0;
       
   319     }
       
   320 }
       
   321 
       
   322 QString QDirPrivate::initFileEngine(const QString &path)
       
   323 {
       
   324     detach(false);
       
   325     delete data->fileEngine;
       
   326     data->fileEngine = 0;
       
   327     data->clear();
       
   328     data->fileEngine = QAbstractFileEngine::create(path);
       
   329     return data->fileEngine->fileName(QAbstractFileEngine::DefaultName);
       
   330 }
       
   331 
       
   332 void QDirPrivate::detach(bool createFileEngine)
       
   333 {
       
   334     qAtomicDetach(data);
       
   335     if (createFileEngine) {
       
   336         QAbstractFileEngine *newFileEngine = QAbstractFileEngine::create(data->path);
       
   337         delete data->fileEngine;
       
   338         data->fileEngine = newFileEngine;
       
   339     }
       
   340 }
       
   341 
       
   342 /*!
       
   343     \class QDir
       
   344     \brief The QDir class provides access to directory structures and their contents.
       
   345 
       
   346     \ingroup io
       
   347     \ingroup shared
       
   348     \reentrant
       
   349 
       
   350 
       
   351     A QDir is used to manipulate path names, access information
       
   352     regarding paths and files, and manipulate the underlying file
       
   353     system. It can also be used to access Qt's \l{resource system}.
       
   354 
       
   355     Qt uses "/" as a universal directory separator in the same way
       
   356     that "/" is used as a path separator in URLs. If you always use
       
   357     "/" as a directory separator, Qt will translate your paths to
       
   358     conform to the underlying operating system.
       
   359 
       
   360     A QDir can point to a file using either a relative or an absolute
       
   361     path. Absolute paths begin with the directory separator
       
   362     (optionally preceded by a drive specification under Windows).
       
   363     Relative file names begin with a directory name or a file name and
       
   364     specify a path relative to the current directory.
       
   365 
       
   366     Examples of absolute paths:
       
   367 
       
   368     \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 0
       
   369 
       
   370     On Windows, the second example above will be translated to
       
   371     \c{C:\Documents and Settings} when used to access files.
       
   372 
       
   373     Examples of relative paths:
       
   374 
       
   375     \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 1
       
   376 
       
   377     You can use the isRelative() or isAbsolute() functions to check if
       
   378     a QDir is using a relative or an absolute file path. Call
       
   379     makeAbsolute() to convert a relative QDir to an absolute one.
       
   380 
       
   381     \section1 Navigation and Directory Operations
       
   382 
       
   383     A directory's path can be obtained with the path() function, and
       
   384     a new path set with the setPath() function. The absolute path to
       
   385     a directory is found by calling absolutePath().
       
   386 
       
   387     The name of a directory is found using the dirName() function. This
       
   388     typically returns the last element in the absolute path that specifies
       
   389     the location of the directory. However, it can also return "." if
       
   390     the QDir represents the current directory.
       
   391 
       
   392     \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 2
       
   393 
       
   394     The path for a directory can also be changed with the cd() and cdUp()
       
   395     functions, both of which operate like familiar shell commands.
       
   396     When cd() is called with the name of an existing directory, the QDir
       
   397     object changes directory so that it represents that directory instead.
       
   398     The cdUp() function changes the directory of the QDir object so that
       
   399     it refers to its parent directory; i.e. cd("..") is equivalent to
       
   400     cdUp().
       
   401 
       
   402     Directories can be created with mkdir(), renamed with rename(), and
       
   403     removed with rmdir().
       
   404 
       
   405     You can test for the presence of a directory with a given name by
       
   406     using exists(), and the properties of a directory can be tested with
       
   407     isReadable(), isAbsolute(), isRelative(), and isRoot().
       
   408 
       
   409     The refresh() function re-reads the directory's data from disk.
       
   410 
       
   411     \section1 Files and Directory Contents
       
   412 
       
   413     Directories contain a number of entries, representing files,
       
   414     directories, and symbolic links. The number of entries in a
       
   415     directory is returned by count().
       
   416     A string list of the names of all the entries in a directory can be
       
   417     obtained with entryList(). If you need information about each
       
   418     entry, use entryInfoList() to obtain a list of QFileInfo objects.
       
   419 
       
   420     Paths to files and directories within a directory can be
       
   421     constructed using filePath() and absoluteFilePath().
       
   422     The filePath() function returns a path to the specified file
       
   423     or directory relative to the path of the QDir object;
       
   424     absoluteFilePath() returns an absolute path to the specified
       
   425     file or directory. Neither of these functions checks for the
       
   426     existence of files or directory; they only construct paths.
       
   427 
       
   428     \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 3
       
   429 
       
   430     Files can be removed by using the remove() function. Directories
       
   431     cannot be removed in the same way as files; use rmdir() to remove
       
   432     them instead.
       
   433 
       
   434     It is possible to reduce the number of entries returned by
       
   435     entryList() and entryInfoList() by applying filters to a QDir object.
       
   436     You can apply a name filter to specify a pattern with wildcards that
       
   437     file names need to match, an attribute filter that selects properties
       
   438     of entries and can distinguish between files and directories, and a
       
   439     sort order.
       
   440 
       
   441     Name filters are lists of strings that are passed to setNameFilters().
       
   442     Attribute filters consist of a bitwise OR combination of Filters, and
       
   443     these are specified when calling setFilter().
       
   444     The sort order is specified using setSorting() with a bitwise OR
       
   445     combination of SortFlags.
       
   446 
       
   447     You can test to see if a filename matches a filter using the match()
       
   448     function.
       
   449 
       
   450     Filter and sort order flags may also be specified when calling
       
   451     entryList() and entryInfoList() in order to override previously defined
       
   452     behavior.
       
   453 
       
   454     \section1 The Current Directory and Other Special Paths
       
   455 
       
   456     Access to some common directories is provided with a number of static
       
   457     functions that return QDir objects. There are also corresponding functions
       
   458     for these that return strings:
       
   459 
       
   460     \table
       
   461     \header \o QDir      \o QString         \o Return Value
       
   462     \row    \o current() \o currentPath()   \o The application's working directory
       
   463     \row    \o home()    \o homePath()      \o The user's home directory
       
   464     \row    \o root()    \o rootPath()      \o The root directory
       
   465     \row    \o temp()    \o tempPath()      \o The system's temporary directory
       
   466     \endtable
       
   467 
       
   468     The setCurrent() static function can also be used to set the application's
       
   469     working directory.
       
   470 
       
   471     If you want to find the directory containing the application's executable,
       
   472     see \l{QCoreApplication::applicationDirPath()}.
       
   473 
       
   474     The drives() static function provides a list of root directories for each
       
   475     device that contains a filing system. On Unix systems this returns a list
       
   476     containing a single root directory "/"; on Windows the list will usually
       
   477     contain \c{C:/}, and possibly other drive letters such as \c{D:/}, depending
       
   478     on the configuration of the user's system.
       
   479 
       
   480     \section1 Path Manipulation and Strings
       
   481 
       
   482     Paths containing "." elements that reference the current directory at that
       
   483     point in the path, ".." elements that reference the parent directory, and
       
   484     symbolic links can be reduced to a canonical form using the canonicalPath()
       
   485     function.
       
   486 
       
   487     Paths can also be simplified by using cleanPath() to remove redundant "/"
       
   488     and ".." elements.
       
   489 
       
   490     It is sometimes necessary to be able to show a path in the native
       
   491     representation for the user's platform. The static toNativeSeparators()
       
   492     function returns a copy of the specified path in which each directory
       
   493     separator is replaced by the appropriate separator for the underlying
       
   494     operating system.
       
   495 
       
   496     \section1 Examples
       
   497 
       
   498     Check if a directory exists:
       
   499 
       
   500     \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 4
       
   501 
       
   502     (We could also use the static convenience function
       
   503     QFile::exists().)
       
   504 
       
   505     Traversing directories and reading a file:
       
   506 
       
   507     \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 5
       
   508 
       
   509     A program that lists all the files in the current directory
       
   510     (excluding symbolic links), sorted by size, smallest first:
       
   511 
       
   512     \snippet doc/src/snippets/qdir-listfiles/main.cpp 0
       
   513 
       
   514     \sa QFileInfo, QFile, QFileDialog, QApplication::applicationDirPath(), {Find Files Example}
       
   515 */
       
   516 
       
   517 /*!
       
   518     Constructs a QDir pointing to the given directory \a path. If path
       
   519     is empty the program's working directory, ("."), is used.
       
   520 
       
   521     \sa currentPath()
       
   522 */
       
   523 
       
   524 QDir::QDir(const QString &path) : d_ptr(new QDirPrivate(this))
       
   525 {
       
   526     Q_D(QDir);
       
   527     d->setPath(path.isEmpty() ? QString::fromLatin1(".") : path);
       
   528     d->data->nameFilters = QStringList(QString::fromLatin1("*"));
       
   529     d->data->filters = AllEntries;
       
   530     d->data->sort = SortFlags(Name | IgnoreCase);
       
   531 }
       
   532 
       
   533 /*!
       
   534     Constructs a QDir with path \a path, that filters its entries by
       
   535     name using \a nameFilter and by attributes using \a filters. It
       
   536     also sorts the names using \a sort.
       
   537 
       
   538     The default \a nameFilter is an empty string, which excludes
       
   539     nothing; the default \a filters is \l AllEntries, which also means
       
   540     exclude nothing. The default \a sort is \l Name | \l IgnoreCase,
       
   541     i.e. sort by name case-insensitively.
       
   542 
       
   543     If \a path is an empty string, QDir uses "." (the current
       
   544     directory). If \a nameFilter is an empty string, QDir uses the
       
   545     name filter "*" (all files).
       
   546 
       
   547     Note that \a path need not exist.
       
   548 
       
   549     \sa exists(), setPath(), setNameFilter(), setFilter(), setSorting()
       
   550 */
       
   551 
       
   552 QDir::QDir(const QString &path, const QString &nameFilter,
       
   553            SortFlags sort, Filters filters)  : d_ptr(new QDirPrivate(this))
       
   554 {
       
   555     Q_D(QDir);
       
   556     d->setPath(path.isEmpty() ? QString::fromLatin1(".") : path);
       
   557     d->data->nameFilters = QDir::nameFiltersFromString(nameFilter);
       
   558     bool empty = d->data->nameFilters.isEmpty();
       
   559     if(!empty) {
       
   560         empty = true;
       
   561         for(int i = 0; i < d->data->nameFilters.size(); ++i) {
       
   562             if(!d->data->nameFilters.at(i).isEmpty()) {
       
   563                 empty = false;
       
   564                 break;
       
   565             }
       
   566         }
       
   567     }
       
   568     if (empty)
       
   569         d->data->nameFilters = QStringList(QString::fromLatin1("*"));
       
   570     d->data->sort = sort;
       
   571     d->data->filters = filters;
       
   572 }
       
   573 
       
   574 /*!
       
   575     Constructs a QDir object that is a copy of the QDir object for
       
   576     directory \a dir.
       
   577 
       
   578     \sa operator=()
       
   579 */
       
   580 
       
   581 QDir::QDir(const QDir &dir)  : d_ptr(new QDirPrivate(this, &dir))
       
   582 {
       
   583 }
       
   584 
       
   585 /*!
       
   586     Destroys the QDir object frees up its resources. This has no
       
   587     effect on the underlying directory in the file system.
       
   588 */
       
   589 
       
   590 QDir::~QDir()
       
   591 {
       
   592 }
       
   593 
       
   594 /*!
       
   595     Sets the path of the directory to \a path. The path is cleaned of
       
   596     redundant ".", ".." and of multiple separators. No check is made
       
   597     to see whether a directory with this path actually exists; but you
       
   598     can check for yourself using exists().
       
   599 
       
   600     The path can be either absolute or relative. Absolute paths begin
       
   601     with the directory separator "/" (optionally preceded by a drive
       
   602     specification under Windows). Relative file names begin with a
       
   603     directory name or a file name and specify a path relative to the
       
   604     current directory. An example of an absolute path is the string
       
   605     "/tmp/quartz", a relative path might look like "src/fatlib".
       
   606 
       
   607     \sa path(), absolutePath(), exists(), cleanPath(), dirName(),
       
   608       absoluteFilePath(), isRelative(), makeAbsolute()
       
   609 */
       
   610 
       
   611 void QDir::setPath(const QString &path)
       
   612 {
       
   613     Q_D(QDir);
       
   614     d->setPath(path);
       
   615 }
       
   616 
       
   617 /*!
       
   618     Returns the path. This may contain symbolic links, but never
       
   619     contains redundant ".", ".." or multiple separators.
       
   620 
       
   621     The returned path can be either absolute or relative (see
       
   622     setPath()).
       
   623 
       
   624     \sa setPath(), absolutePath(), exists(), cleanPath(), dirName(),
       
   625     absoluteFilePath(), toNativeSeparators(), makeAbsolute()
       
   626 */
       
   627 
       
   628 QString QDir::path() const
       
   629 {
       
   630     Q_D(const QDir);
       
   631     return d->data->path;
       
   632 }
       
   633 
       
   634 /*!
       
   635     Returns the absolute path (a path that starts with "/" or with a
       
   636     drive specification), which may contain symbolic links, but never
       
   637     contains redundant ".", ".." or multiple separators.
       
   638 
       
   639     \sa setPath(), canonicalPath(), exists(), cleanPath(),
       
   640     dirName(), absoluteFilePath()
       
   641 */
       
   642 
       
   643 QString QDir::absolutePath() const
       
   644 {
       
   645     Q_D(const QDir);
       
   646     QString ret = d->data->path;
       
   647     if (QDir::isRelativePath(ret))
       
   648         ret = absoluteFilePath(QString::fromLatin1(""));
       
   649     return cleanPath(ret);
       
   650 }
       
   651 
       
   652 
       
   653 /*!
       
   654     Returns the canonical path, i.e. a path without symbolic links or
       
   655     redundant "." or ".." elements.
       
   656 
       
   657     On systems that do not have symbolic links this function will
       
   658     always return the same string that absolutePath() returns. If the
       
   659     canonical path does not exist (normally due to dangling symbolic
       
   660     links) canonicalPath() returns an empty string.
       
   661 
       
   662     Example:
       
   663 
       
   664     \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 6
       
   665 
       
   666     \sa path(), absolutePath(), exists(), cleanPath(), dirName(),
       
   667         absoluteFilePath()
       
   668 */
       
   669 
       
   670 QString QDir::canonicalPath() const
       
   671 {
       
   672     Q_D(const QDir);
       
   673 
       
   674     if(!d->data->fileEngine)
       
   675         return QLatin1String("");
       
   676     return cleanPath(d->data->fileEngine->fileName(QAbstractFileEngine::CanonicalName));
       
   677 }
       
   678 
       
   679 /*!
       
   680     Returns the name of the directory; this is \e not the same as the
       
   681     path, e.g. a directory with the name "mail", might have the path
       
   682     "/var/spool/mail". If the directory has no name (e.g. it is the
       
   683     root directory) an empty string is returned.
       
   684 
       
   685     No check is made to ensure that a directory with this name
       
   686     actually exists; but see exists().
       
   687 
       
   688     \sa path(), filePath(), absolutePath(), absoluteFilePath()
       
   689 */
       
   690 
       
   691 QString QDir::dirName() const
       
   692 {
       
   693     Q_D(const QDir);
       
   694     int pos = d->data->path.lastIndexOf(QLatin1Char('/'));
       
   695     if (pos == -1)
       
   696         return d->data->path;
       
   697     return d->data->path.mid(pos + 1);
       
   698 }
       
   699 
       
   700 /*!
       
   701     Returns the path name of a file in the directory. Does \e not
       
   702     check if the file actually exists in the directory; but see
       
   703     exists(). If the QDir is relative the returned path name will also
       
   704     be relative. Redundant multiple separators or "." and ".."
       
   705     directories in \a fileName are not removed (see cleanPath()).
       
   706 
       
   707     \sa dirName() absoluteFilePath(), isRelative(), canonicalPath()
       
   708 */
       
   709 
       
   710 QString QDir::filePath(const QString &fileName) const
       
   711 {
       
   712     Q_D(const QDir);
       
   713     if (isAbsolutePath(fileName))
       
   714         return QString(fileName);
       
   715 
       
   716     QString ret = d->data->path;
       
   717     if(!fileName.isEmpty()) {
       
   718         if (!ret.isEmpty() && ret[(int)ret.length()-1] != QLatin1Char('/') && fileName[0] != QLatin1Char('/'))
       
   719             ret += QLatin1Char('/');
       
   720         ret += fileName;
       
   721     }
       
   722     return ret;
       
   723 }
       
   724 
       
   725 /*!
       
   726     Returns the absolute path name of a file in the directory. Does \e
       
   727     not check if the file actually exists in the directory; but see
       
   728     exists(). Redundant multiple separators or "." and ".."
       
   729     directories in \a fileName are not removed (see cleanPath()).
       
   730 
       
   731     \sa relativeFilePath() filePath() canonicalPath()
       
   732 */
       
   733 
       
   734 QString QDir::absoluteFilePath(const QString &fileName) const
       
   735 {
       
   736     Q_D(const QDir);
       
   737     if (isAbsolutePath(fileName))
       
   738         return fileName;
       
   739     if(!d->data->fileEngine)
       
   740         return fileName;
       
   741 
       
   742     QString ret;
       
   743 #ifndef QT_NO_FSFILEENGINE
       
   744     if (isRelativePath(d->data->path)) //get pwd
       
   745         ret = QFSFileEngine::currentPath(fileName);
       
   746 #endif
       
   747     if(!d->data->path.isEmpty() && d->data->path != QLatin1String(".")) {
       
   748         if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/')))
       
   749             ret += QLatin1Char('/');
       
   750         ret += d->data->path;
       
   751     }
       
   752     if (!fileName.isEmpty()) {
       
   753         if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/')))
       
   754             ret += QLatin1Char('/');
       
   755         ret += fileName;
       
   756     }
       
   757     return ret;
       
   758 }
       
   759 
       
   760 /*!
       
   761     Returns the path to \a fileName relative to the directory.
       
   762 
       
   763     \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 7
       
   764 
       
   765     \sa absoluteFilePath() filePath() canonicalPath()
       
   766 */
       
   767 
       
   768 QString QDir::relativeFilePath(const QString &fileName) const
       
   769 {
       
   770     QString dir = absolutePath();
       
   771     QString file = cleanPath(fileName);
       
   772 
       
   773     if (isRelativePath(file) || isRelativePath(dir))
       
   774         return file;
       
   775 
       
   776     QString dirDrive = driveSpec(dir);
       
   777     QString fileDrive = driveSpec(file);
       
   778 
       
   779     bool fileDriveMissing = false;
       
   780     if (fileDrive.isEmpty()) {
       
   781         fileDrive = dirDrive;
       
   782         fileDriveMissing = true;
       
   783     }
       
   784 
       
   785 #ifdef Q_OS_WIN
       
   786     if (fileDrive.toLower() != dirDrive.toLower()
       
   787         || (file.startsWith(QLatin1String("//"))
       
   788         && !dir.startsWith(QLatin1String("//"))))
       
   789 #elif defined(Q_OS_SYMBIAN)
       
   790     if (fileDrive.toLower() != dirDrive.toLower())
       
   791 #else
       
   792     if (fileDrive != dirDrive)
       
   793 #endif
       
   794         return file;
       
   795 
       
   796     dir.remove(0, dirDrive.size());
       
   797     if (!fileDriveMissing)
       
   798         file.remove(0, fileDrive.size());
       
   799 
       
   800     QString result;
       
   801     QStringList dirElts = dir.split(QLatin1Char('/'), QString::SkipEmptyParts);
       
   802     QStringList fileElts = file.split(QLatin1Char('/'), QString::SkipEmptyParts);
       
   803 
       
   804     int i = 0;
       
   805     while (i < dirElts.size() && i < fileElts.size() &&
       
   806 #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
       
   807            dirElts.at(i).toLower() == fileElts.at(i).toLower())
       
   808 #else
       
   809            dirElts.at(i) == fileElts.at(i))
       
   810 #endif
       
   811         ++i;
       
   812 
       
   813     for (int j = 0; j < dirElts.size() - i; ++j)
       
   814         result += QLatin1String("../");
       
   815 
       
   816     for (int j = i; j < fileElts.size(); ++j) {
       
   817         result += fileElts.at(j);
       
   818         if (j < fileElts.size() - 1)
       
   819             result += QLatin1Char('/');
       
   820     }
       
   821 
       
   822     return result;
       
   823 }
       
   824 
       
   825 /*!
       
   826     \obsolete
       
   827 
       
   828     Use QDir::toNativeSeparators() instead.
       
   829 */
       
   830 QString QDir::convertSeparators(const QString &pathName)
       
   831 {
       
   832     return toNativeSeparators(pathName);
       
   833 }
       
   834 
       
   835 /*!
       
   836     \since 4.2
       
   837 
       
   838     Returns \a pathName with the '/' separators converted to
       
   839     separators that are appropriate for the underlying operating
       
   840     system.
       
   841 
       
   842     On Windows, toNativeSeparators("c:/winnt/system32") returns
       
   843     "c:\\winnt\\system32".
       
   844 
       
   845     The returned string may be the same as the argument on some
       
   846     operating systems, for example on Unix.
       
   847 
       
   848     \sa fromNativeSeparators(), separator()
       
   849 */
       
   850 QString QDir::toNativeSeparators(const QString &pathName)
       
   851 {
       
   852     QString n(pathName);
       
   853 #if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX) || defined(Q_OS_SYMBIAN)
       
   854     for (int i=0; i<(int)n.length(); i++) {
       
   855         if (n[i] == QLatin1Char('/'))
       
   856             n[i] = QLatin1Char('\\');
       
   857     }
       
   858 #endif
       
   859     return n;
       
   860 }
       
   861 
       
   862 /*!
       
   863     \since 4.2
       
   864 
       
   865     Returns \a pathName using '/' as file separator. On Windows,
       
   866     for instance, fromNativeSeparators("\c{c:\\winnt\\system32}") returns
       
   867     "c:/winnt/system32".
       
   868 
       
   869     The returned string may be the same as the argument on some
       
   870     operating systems, for example on Unix.
       
   871 
       
   872     \sa toNativeSeparators(), separator()
       
   873 */
       
   874 QString QDir::fromNativeSeparators(const QString &pathName)
       
   875 {
       
   876     QString n(pathName);
       
   877 #if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX) || defined(Q_OS_SYMBIAN)
       
   878     for (int i=0; i<(int)n.length(); i++) {
       
   879         if (n[i] == QLatin1Char('\\'))
       
   880             n[i] = QLatin1Char('/');
       
   881     }
       
   882 #endif
       
   883     return n;
       
   884 }
       
   885 
       
   886 /*!
       
   887     Changes the QDir's directory to \a dirName.
       
   888 
       
   889     Returns true if the new directory exists and is readable;
       
   890     otherwise returns false. Note that the logical cd() operation is
       
   891     not performed if the new directory does not exist.
       
   892 
       
   893     Calling cd("..") is equivalent to calling cdUp().
       
   894 
       
   895     \sa cdUp(), isReadable(), exists(), path()
       
   896 */
       
   897 
       
   898 bool QDir::cd(const QString &dirName)
       
   899 {
       
   900     Q_D(QDir);
       
   901 
       
   902     if (dirName.isEmpty() || dirName == QLatin1String("."))
       
   903         return true;
       
   904     QString newPath = d->data->path;
       
   905     if (isAbsolutePath(dirName)) {
       
   906         newPath = cleanPath(dirName);
       
   907     } else {
       
   908         if (isRoot()) {
       
   909             if (dirName == QLatin1String(".."))
       
   910                 return false;
       
   911         } else {
       
   912             newPath += QLatin1Char('/');
       
   913         }
       
   914 
       
   915         newPath += dirName;
       
   916         if (dirName.indexOf(QLatin1Char('/')) >= 0
       
   917             || d->data->path == QLatin1String(".")
       
   918             || dirName == QLatin1String("..")) {
       
   919             newPath = cleanPath(newPath);
       
   920             /*
       
   921               If newPath starts with .., we convert it to absolute to
       
   922               avoid infinite looping on
       
   923 
       
   924                   QDir dir(".");
       
   925                   while (dir.cdUp())
       
   926                       ;
       
   927             */
       
   928             if (newPath.startsWith(QLatin1String(".."))) {
       
   929                 newPath = QFileInfo(newPath).absoluteFilePath();
       
   930             }
       
   931         }
       
   932     }
       
   933     {
       
   934         QFileInfo fi(newPath);
       
   935         if (!(fi.exists() && fi.isDir()))
       
   936             return false;
       
   937     }
       
   938 
       
   939     d->setPath(newPath);
       
   940     refresh();
       
   941     return true;
       
   942 }
       
   943 
       
   944 /*!
       
   945     Changes directory by moving one directory up from the QDir's
       
   946     current directory.
       
   947 
       
   948     Returns true if the new directory exists and is readable;
       
   949     otherwise returns false. Note that the logical cdUp() operation is
       
   950     not performed if the new directory does not exist.
       
   951 
       
   952     \sa cd(), isReadable(), exists(), path()
       
   953 */
       
   954 
       
   955 bool QDir::cdUp()
       
   956 {
       
   957     return cd(QString::fromLatin1(".."));
       
   958 }
       
   959 
       
   960 /*!
       
   961     Returns the string list set by setNameFilters()
       
   962 */
       
   963 
       
   964 QStringList QDir::nameFilters() const
       
   965 {
       
   966     Q_D(const QDir);
       
   967 
       
   968     return d->data->nameFilters;
       
   969 }
       
   970 
       
   971 /*!
       
   972     Sets the name filters used by entryList() and entryInfoList() to the
       
   973     list of filters specified by \a nameFilters.
       
   974 
       
   975     Each name filter is a wildcard (globbing) filter that understands
       
   976     \c{*} and \c{?} wildcards. (See \l{QRegExp wildcard matching}.)
       
   977 
       
   978     For example, the following code sets three name filters on a QDir
       
   979     to ensure that only files with extensions typically used for C++
       
   980     source files are listed:
       
   981 
       
   982     \snippet doc/src/snippets/qdir-namefilters/main.cpp 0
       
   983 
       
   984     \sa nameFilters(), setFilter()
       
   985 */
       
   986 
       
   987 void QDir::setNameFilters(const QStringList &nameFilters)
       
   988 {
       
   989     Q_D(QDir);
       
   990     d->detach();
       
   991     d->data->nameFilters = nameFilters;
       
   992 }
       
   993 
       
   994 /*!
       
   995     \obsolete
       
   996     Adds \a path to the search paths searched in to find resources
       
   997     that are not specified with an absolute path. The default search
       
   998     path is to search only in the root (\c{:/}).
       
   999 
       
  1000     Use QDir::addSearchPath() with a prefix instead.
       
  1001 
       
  1002     \sa {The Qt Resource System}, QResource::addSearchPath()
       
  1003 */
       
  1004 
       
  1005 void QDir::addResourceSearchPath(const QString &path)
       
  1006 {
       
  1007 #ifdef QT_BUILD_CORE_LIB
       
  1008     QResource::addSearchPath(path);
       
  1009 #else
       
  1010     Q_UNUSED(path)
       
  1011 #endif
       
  1012 }
       
  1013 
       
  1014 #ifdef QT_BUILD_CORE_LIB
       
  1015 /*!
       
  1016     \since 4.3
       
  1017 
       
  1018     Sets or replaces Qt's search paths for file names with the prefix \a prefix
       
  1019     to \a searchPaths.
       
  1020 
       
  1021     To specify a prefix for a file name, prepend the prefix followed by a single
       
  1022     colon (e.g., "images:undo.png", "xmldocs:books.xml"). \a prefix can only
       
  1023     contain letters or numbers (e.g., it cannot contain a colon, nor a slash).
       
  1024 
       
  1025     Qt uses this search path to locate files with a known prefix. The search
       
  1026     path entries are tested in order, starting with the first entry.
       
  1027 
       
  1028     \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 8
       
  1029 
       
  1030     File name prefix must be at least 2 characters long to avoid conflicts with
       
  1031     Windows drive letters.
       
  1032 
       
  1033     Search paths may contain paths to \l{The Qt Resource System}.
       
  1034 */
       
  1035 void QDir::setSearchPaths(const QString &prefix, const QStringList &searchPaths)
       
  1036 {
       
  1037     if (prefix.length() < 2) {
       
  1038         qWarning("QDir::setSearchPaths: Prefix must be longer than 1 character");
       
  1039         return;
       
  1040     }
       
  1041 
       
  1042     for (int i = 0; i < prefix.count(); i++) {
       
  1043         if (!prefix.at(i).isLetterOrNumber()) {
       
  1044             qWarning("QDir::setSearchPaths: Prefix can only contain letters or numbers");
       
  1045             return;
       
  1046         }
       
  1047     }
       
  1048 
       
  1049     QWriteLocker lock(&QCoreGlobalData::instance()->dirSearchPathsLock);
       
  1050     QMap<QString, QStringList> &paths = QCoreGlobalData::instance()->dirSearchPaths;
       
  1051     if (searchPaths.isEmpty()) {
       
  1052         paths.remove(prefix);
       
  1053     } else {
       
  1054         paths.insert(prefix, searchPaths);
       
  1055     }
       
  1056 }
       
  1057 
       
  1058 /*!
       
  1059     \since 4.3
       
  1060 
       
  1061     Adds \a path to the search path for \a prefix.
       
  1062 
       
  1063     \sa setSearchPaths()
       
  1064 */
       
  1065 void QDir::addSearchPath(const QString &prefix, const QString &path)
       
  1066 {
       
  1067     if (path.isEmpty())
       
  1068         return;
       
  1069 
       
  1070     QWriteLocker lock(&QCoreGlobalData::instance()->dirSearchPathsLock);
       
  1071     QCoreGlobalData::instance()->dirSearchPaths[prefix] += path;
       
  1072 }
       
  1073 
       
  1074 /*!
       
  1075     \since 4.3
       
  1076 
       
  1077     Returns the search paths for \a prefix.
       
  1078 
       
  1079     \sa setSearchPaths(), addSearchPath()
       
  1080 */
       
  1081 QStringList QDir::searchPaths(const QString &prefix)
       
  1082 {
       
  1083     QReadLocker lock(&QCoreGlobalData::instance()->dirSearchPathsLock);
       
  1084     return QCoreGlobalData::instance()->dirSearchPaths.value(prefix);
       
  1085 }
       
  1086 
       
  1087 #endif // QT_BUILD_CORE_LIB
       
  1088 
       
  1089 /*!
       
  1090     Returns the value set by setFilter()
       
  1091 */
       
  1092 
       
  1093 QDir::Filters QDir::filter() const
       
  1094 {
       
  1095     Q_D(const QDir);
       
  1096 
       
  1097     return d->data->filters;
       
  1098 }
       
  1099 
       
  1100 /*!
       
  1101     \enum QDir::Filter
       
  1102 
       
  1103     This enum describes the filtering options available to QDir; e.g.
       
  1104     for entryList() and entryInfoList(). The filter value is specified
       
  1105     by combining values from the following list using the bitwise OR
       
  1106     operator:
       
  1107 
       
  1108     \value Dirs    List directories that match the filters.
       
  1109     \value AllDirs  List all directories; i.e. don't apply the filters
       
  1110                     to directory names.
       
  1111     \value Files   List files.
       
  1112     \value Drives  List disk drives (ignored under Unix).
       
  1113     \value NoSymLinks  Do not list symbolic links (ignored by operating
       
  1114                        systems that don't support symbolic links).
       
  1115     \value NoDotAndDotDot Do not list the special entries "." and "..".
       
  1116     \value AllEntries  List directories, files, drives and symlinks (this does not list
       
  1117                 broken symlinks unless you specify System).
       
  1118     \value Readable    List files for which the application has read
       
  1119                        access. The Readable value needs to be combined
       
  1120                        with Dirs or Files.
       
  1121     \value Writable    List files for which the application has write
       
  1122                        access. The Writable value needs to be combined
       
  1123                        with Dirs or Files.
       
  1124     \value Executable  List files for which the application has
       
  1125                        execute access. The Executable value needs to be
       
  1126                        combined with Dirs or Files.
       
  1127     \value Modified  Only list files that have been modified (ignored
       
  1128                      under Unix).
       
  1129     \value Hidden  List hidden files (on Unix, files starting with a .).
       
  1130     \value System  List system files (on Unix, FIFOs, sockets and
       
  1131                    device files)
       
  1132     \value CaseSensitive  The filter should be case sensitive.
       
  1133 
       
  1134     \omitvalue DefaultFilter
       
  1135     \omitvalue TypeMask
       
  1136     \omitvalue All
       
  1137     \omitvalue RWEMask
       
  1138     \omitvalue AccessMask
       
  1139     \omitvalue PermissionMask
       
  1140     \omitvalue NoFilter
       
  1141 
       
  1142     Functions that use Filter enum values to filter lists of files
       
  1143     and directories will include symbolic links to files and directories
       
  1144     unless you set the NoSymLinks value.
       
  1145 
       
  1146     A default constructed QDir will not filter out files based on
       
  1147     their permissions, so entryList() and entryInfoList() will return
       
  1148     all files that are readable, writable, executable, or any
       
  1149     combination of the three.  This makes the default easy to write,
       
  1150     and at the same time useful.
       
  1151 
       
  1152     For example, setting the \c Readable, \c Writable, and \c Files
       
  1153     flags allows all files to be listed for which the application has read
       
  1154     access, write access or both. If the \c Dirs and \c Drives flags are
       
  1155     also included in this combination then all drives, directories, all
       
  1156     files that the application can read, write, or execute, and symlinks
       
  1157     to such files/directories can be listed.
       
  1158 
       
  1159     To retrieve the permissons for a directory, use the
       
  1160     entryInfoList() function to get the associated QFileInfo objects
       
  1161     and then use the QFileInfo::permissons() to obtain the permissions
       
  1162     and ownership for each file.
       
  1163 */
       
  1164 
       
  1165 /*!
       
  1166     Sets the filter used by entryList() and entryInfoList() to \a
       
  1167     filters. The filter is used to specify the kind of files that
       
  1168     should be returned by entryList() and entryInfoList(). See
       
  1169     \l{QDir::Filter}.
       
  1170 
       
  1171     \sa filter(), setNameFilters()
       
  1172 */
       
  1173 
       
  1174 void QDir::setFilter(Filters filters)
       
  1175 {
       
  1176     Q_D(QDir);
       
  1177 
       
  1178     d->detach();
       
  1179     d->data->filters = filters;
       
  1180 }
       
  1181 
       
  1182 /*!
       
  1183     Returns the value set by setSorting()
       
  1184 
       
  1185     \sa setSorting() SortFlag
       
  1186 */
       
  1187 
       
  1188 QDir::SortFlags QDir::sorting() const
       
  1189 {
       
  1190     Q_D(const QDir);
       
  1191 
       
  1192     return d->data->sort;
       
  1193 }
       
  1194 
       
  1195 /*!
       
  1196     \enum QDir::SortFlag
       
  1197 
       
  1198     This enum describes the sort options available to QDir, e.g. for
       
  1199     entryList() and entryInfoList(). The sort value is specified by
       
  1200     OR-ing together values from the following list:
       
  1201 
       
  1202     \value Name  Sort by name.
       
  1203     \value Time  Sort by time (modification time).
       
  1204     \value Size  Sort by file size.
       
  1205     \value Type  Sort by file type (extension).
       
  1206     \value Unsorted  Do not sort.
       
  1207     \value NoSort Not sorted by default.
       
  1208 
       
  1209     \value DirsFirst  Put the directories first, then the files.
       
  1210     \value DirsLast Put the files first, then the directories.
       
  1211     \value Reversed  Reverse the sort order.
       
  1212     \value IgnoreCase  Sort case-insensitively.
       
  1213     \value LocaleAware Sort items appropriately using the current locale settings.
       
  1214 
       
  1215     \omitvalue SortByMask
       
  1216     \omitvalue DefaultSort
       
  1217 
       
  1218     You can only specify one of the first four.
       
  1219 
       
  1220     If you specify both DirsFirst and Reversed, directories are
       
  1221     still put first, but in reverse order; the files will be listed
       
  1222     after the directories, again in reverse order.
       
  1223 */
       
  1224 
       
  1225 /*!
       
  1226     Sets the sort order used by entryList() and entryInfoList().
       
  1227 
       
  1228     The \a sort is specified by OR-ing values from the enum
       
  1229     \l{QDir::SortFlag}.
       
  1230 
       
  1231     \sa sorting() SortFlag
       
  1232 */
       
  1233 
       
  1234 void QDir::setSorting(SortFlags sort)
       
  1235 {
       
  1236     Q_D(QDir);
       
  1237 
       
  1238     d->detach();
       
  1239     d->data->sort = sort;
       
  1240 }
       
  1241 
       
  1242 
       
  1243 /*!
       
  1244     Returns the total number of directories and files in the directory.
       
  1245 
       
  1246     Equivalent to entryList().count().
       
  1247 
       
  1248     \sa operator[](), entryList()
       
  1249 */
       
  1250 
       
  1251 uint QDir::count() const
       
  1252 {
       
  1253     Q_D(const QDir);
       
  1254 
       
  1255     d->updateFileLists();
       
  1256     return d->data->files.count();
       
  1257 }
       
  1258 
       
  1259 /*!
       
  1260     Returns the file name at position \a pos in the list of file
       
  1261     names. Equivalent to entryList().at(index).
       
  1262 
       
  1263     Returns an empty string if \a pos is out of range or if the
       
  1264     entryList() function failed.
       
  1265 
       
  1266     \sa count(), entryList()
       
  1267 */
       
  1268 
       
  1269 QString QDir::operator[](int pos) const
       
  1270 {
       
  1271     Q_D(const QDir);
       
  1272 
       
  1273     d->updateFileLists();
       
  1274     return d->data->files[pos];
       
  1275 }
       
  1276 
       
  1277 /*!
       
  1278     \overload
       
  1279 
       
  1280     Returns a list of the names of all the files and directories in
       
  1281     the directory, ordered according to the name and attribute filters
       
  1282     previously set with setNameFilters() and setFilter(), and sorted according
       
  1283     to the flags set with setSorting().
       
  1284 
       
  1285     The attribute filter and sorting specifications can be overridden using the
       
  1286     \a filters and \a sort arguments.
       
  1287 
       
  1288     Returns an empty list if the directory is unreadable, does not
       
  1289     exist, or if nothing matches the specification.
       
  1290 
       
  1291     \note To list symlinks that point to non existing files, \l System must be
       
  1292      passed to the filter.
       
  1293 
       
  1294     \sa entryInfoList(), setNameFilters(), setSorting(), setFilter()
       
  1295 */
       
  1296 
       
  1297 QStringList QDir::entryList(Filters filters, SortFlags sort) const
       
  1298 {
       
  1299     Q_D(const QDir);
       
  1300 
       
  1301     return entryList(d->data->nameFilters, filters, sort);
       
  1302 }
       
  1303 
       
  1304 
       
  1305 /*!
       
  1306     \overload
       
  1307 
       
  1308     Returns a list of QFileInfo objects for all the files and directories in
       
  1309     the directory, ordered according to the name and attribute filters
       
  1310     previously set with setNameFilters() and setFilter(), and sorted according
       
  1311     to the flags set with setSorting().
       
  1312 
       
  1313     The attribute filter and sorting specifications can be overridden using the
       
  1314     \a filters and \a sort arguments.
       
  1315 
       
  1316     Returns an empty list if the directory is unreadable, does not
       
  1317     exist, or if nothing matches the specification.
       
  1318 
       
  1319     \sa entryList(), setNameFilters(), setSorting(), setFilter(), isReadable(), exists()
       
  1320 */
       
  1321 QFileInfoList QDir::entryInfoList(Filters filters, SortFlags sort) const
       
  1322 {
       
  1323     Q_D(const QDir);
       
  1324 
       
  1325     return entryInfoList(d->data->nameFilters, filters, sort);
       
  1326 }
       
  1327 
       
  1328 /*!
       
  1329     Returns a list of the names of all the files and
       
  1330     directories in the directory, ordered according to the name
       
  1331     and attribute filters previously set with setNameFilters()
       
  1332     and setFilter(), and sorted according to the flags set with
       
  1333     setSorting().
       
  1334 
       
  1335     The name filter, file attribute filter, and sorting specification
       
  1336     can be overridden using the \a nameFilters, \a filters, and \a sort
       
  1337     arguments.
       
  1338 
       
  1339     Returns an empty list if the directory is unreadable, does not
       
  1340     exist, or if nothing matches the specification.
       
  1341 
       
  1342     \sa entryInfoList(), setNameFilters(), setSorting(), setFilter()
       
  1343 */
       
  1344 
       
  1345 QStringList QDir::entryList(const QStringList &nameFilters, Filters filters,
       
  1346                             SortFlags sort) const
       
  1347 {
       
  1348     Q_D(const QDir);
       
  1349 
       
  1350     if (filters == NoFilter)
       
  1351         filters = d->data->filters;
       
  1352 #ifdef QT3_SUPPORT
       
  1353     if (d->matchAllDirs)
       
  1354         filters |= AllDirs;
       
  1355 #endif
       
  1356     if (sort == NoSort)
       
  1357         sort = d->data->sort;
       
  1358     if (filters == NoFilter && sort == NoSort && nameFilters == d->data->nameFilters) {
       
  1359         d->updateFileLists();
       
  1360         return d->data->files;
       
  1361     }
       
  1362     QFileInfoList l;
       
  1363     QDirIterator it(d->data->path, nameFilters, filters);
       
  1364     while (it.hasNext()) {
       
  1365         it.next();
       
  1366         l.append(it.fileInfo());
       
  1367     }
       
  1368     QStringList ret;
       
  1369     d->sortFileList(sort, l, &ret, 0);
       
  1370     return ret;
       
  1371 }
       
  1372 
       
  1373 /*!
       
  1374     Returns a list of QFileInfo objects for all the files and
       
  1375     directories in the directory, ordered according to the name
       
  1376     and attribute filters previously set with setNameFilters()
       
  1377     and setFilter(), and sorted according to the flags set with
       
  1378     setSorting().
       
  1379 
       
  1380     The name filter, file attribute filter, and sorting specification
       
  1381     can be overridden using the \a nameFilters, \a filters, and \a sort
       
  1382     arguments.
       
  1383 
       
  1384     Returns an empty list if the directory is unreadable, does not
       
  1385     exist, or if nothing matches the specification.
       
  1386 
       
  1387     \sa entryList(), setNameFilters(), setSorting(), setFilter(), isReadable(), exists()
       
  1388 */
       
  1389 
       
  1390 QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filters,
       
  1391                                   SortFlags sort) const
       
  1392 {
       
  1393     Q_D(const QDir);
       
  1394 
       
  1395     if (filters == NoFilter)
       
  1396         filters = d->data->filters;
       
  1397 #ifdef QT3_SUPPORT
       
  1398     if (d->matchAllDirs)
       
  1399         filters |= AllDirs;
       
  1400 #endif
       
  1401     if (sort == NoSort)
       
  1402         sort = d->data->sort;
       
  1403     if (filters == NoFilter && sort == NoSort && nameFilters == d->data->nameFilters) {
       
  1404         d->updateFileLists();
       
  1405         return d->data->fileInfos;
       
  1406     }
       
  1407     QFileInfoList l;
       
  1408     QDirIterator it(d->data->path, nameFilters, filters);
       
  1409     while (it.hasNext()) {
       
  1410         it.next();
       
  1411         l.append(it.fileInfo());
       
  1412     }
       
  1413     QFileInfoList ret;
       
  1414     d->sortFileList(sort, l, 0, &ret);
       
  1415     return ret;
       
  1416 }
       
  1417 
       
  1418 /*!
       
  1419     Creates a sub-directory called \a dirName.
       
  1420 
       
  1421     Returns true on success; otherwise returns false.
       
  1422 
       
  1423     \sa rmdir()
       
  1424 */
       
  1425 
       
  1426 bool QDir::mkdir(const QString &dirName) const
       
  1427 {
       
  1428     Q_D(const QDir);
       
  1429 
       
  1430     if (dirName.isEmpty()) {
       
  1431         qWarning("QDir::mkdir: Empty or null file name(s)");
       
  1432         return false;
       
  1433     }
       
  1434     if(!d->data->fileEngine)
       
  1435         return false;
       
  1436 
       
  1437     QString fn = filePath(dirName);
       
  1438     return d->data->fileEngine->mkdir(fn, false);
       
  1439 }
       
  1440 
       
  1441 /*!
       
  1442     Removes the directory specified by \a dirName.
       
  1443 
       
  1444     The directory must be empty for rmdir() to succeed.
       
  1445 
       
  1446     Returns true if successful; otherwise returns false.
       
  1447 
       
  1448     \sa mkdir()
       
  1449 */
       
  1450 
       
  1451 bool QDir::rmdir(const QString &dirName) const
       
  1452 {
       
  1453     Q_D(const QDir);
       
  1454 
       
  1455     if (dirName.isEmpty()) {
       
  1456         qWarning("QDir::rmdir: Empty or null file name(s)");
       
  1457         return false;
       
  1458     }
       
  1459     if(!d->data->fileEngine)
       
  1460         return false;
       
  1461 
       
  1462     QString fn = filePath(dirName);
       
  1463     return d->data->fileEngine->rmdir(fn, false);
       
  1464 }
       
  1465 
       
  1466 /*!
       
  1467     Creates the directory path \a dirPath.
       
  1468 
       
  1469     The function will create all parent directories necessary to
       
  1470     create the directory.
       
  1471 
       
  1472     Returns true if successful; otherwise returns false.
       
  1473 
       
  1474     \sa rmpath()
       
  1475 */
       
  1476 
       
  1477 bool QDir::mkpath(const QString &dirPath) const
       
  1478 {
       
  1479     Q_D(const QDir);
       
  1480 
       
  1481     if (dirPath.isEmpty()) {
       
  1482         qWarning("QDir::mkpath: Empty or null file name(s)");
       
  1483         return false;
       
  1484     }
       
  1485     if(!d->data->fileEngine)
       
  1486         return false;
       
  1487 
       
  1488     QString fn = filePath(dirPath);
       
  1489     return d->data->fileEngine->mkdir(fn, true);
       
  1490 }
       
  1491 
       
  1492 /*!
       
  1493     Removes the directory path \a dirPath.
       
  1494 
       
  1495     The function will remove all parent directories in \a dirPath,
       
  1496     provided that they are empty. This is the opposite of
       
  1497     mkpath(dirPath).
       
  1498 
       
  1499     Returns true if successful; otherwise returns false.
       
  1500 
       
  1501     \sa mkpath()
       
  1502 */
       
  1503 bool QDir::rmpath(const QString &dirPath) const
       
  1504 {
       
  1505     Q_D(const QDir);
       
  1506 
       
  1507     if (dirPath.isEmpty()) {
       
  1508         qWarning("QDir::rmpath: Empty or null file name(s)");
       
  1509         return false;
       
  1510     }
       
  1511     if(!d->data->fileEngine)
       
  1512         return false;
       
  1513 
       
  1514     QString fn = filePath(dirPath);
       
  1515     return d->data->fileEngine->rmdir(fn, true);
       
  1516 }
       
  1517 
       
  1518 /*!
       
  1519     Returns true if the directory is readable \e and we can open files
       
  1520     by name; otherwise returns false.
       
  1521 
       
  1522     \warning A false value from this function is not a guarantee that
       
  1523     files in the directory are not accessible.
       
  1524 
       
  1525     \sa QFileInfo::isReadable()
       
  1526 */
       
  1527 
       
  1528 
       
  1529 bool QDir::isReadable() const
       
  1530 {
       
  1531     Q_D(const QDir);
       
  1532 
       
  1533     if(!d->data->fileEngine)
       
  1534         return false;
       
  1535     const QAbstractFileEngine::FileFlags info = d->data->fileEngine->fileFlags(QAbstractFileEngine::DirectoryType
       
  1536                                                                        |QAbstractFileEngine::PermsMask);
       
  1537     if(!(info & QAbstractFileEngine::DirectoryType))
       
  1538         return false;
       
  1539     return info & QAbstractFileEngine::ReadUserPerm;
       
  1540 }
       
  1541 
       
  1542 /*!
       
  1543     \overload
       
  1544 
       
  1545     Returns true if the directory exists; otherwise returns false.
       
  1546     (If a file with the same name is found this function will return false).
       
  1547 
       
  1548     The overload of this function that accepts an argument is used to test
       
  1549     for the presence of files and directories within a directory.
       
  1550 
       
  1551     \sa QFileInfo::exists(), QFile::exists()
       
  1552 */
       
  1553 
       
  1554 bool QDir::exists() const
       
  1555 {
       
  1556     Q_D(const QDir);
       
  1557 
       
  1558     if(!d->data->fileEngine)
       
  1559         return false;
       
  1560     const QAbstractFileEngine::FileFlags info =
       
  1561         d->data->fileEngine->fileFlags(
       
  1562             QAbstractFileEngine::DirectoryType
       
  1563             | QAbstractFileEngine::ExistsFlag
       
  1564             | QAbstractFileEngine::Refresh);
       
  1565     if(!(info & QAbstractFileEngine::DirectoryType))
       
  1566         return false;
       
  1567     return info & QAbstractFileEngine::ExistsFlag;
       
  1568 }
       
  1569 
       
  1570 /*!
       
  1571     Returns true if the directory is the root directory; otherwise
       
  1572     returns false.
       
  1573 
       
  1574     Note: If the directory is a symbolic link to the root directory
       
  1575     this function returns false. If you want to test for this use
       
  1576     canonicalPath(), e.g.
       
  1577 
       
  1578     \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 9
       
  1579 
       
  1580     \sa root(), rootPath()
       
  1581 */
       
  1582 
       
  1583 bool QDir::isRoot() const
       
  1584 {
       
  1585     Q_D(const QDir);
       
  1586 
       
  1587     if(!d->data->fileEngine)
       
  1588         return true;
       
  1589     return d->data->fileEngine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::RootFlag;
       
  1590 }
       
  1591 
       
  1592 /*!
       
  1593     \fn bool QDir::isAbsolute() const
       
  1594 
       
  1595     Returns true if the directory's path is absolute; otherwise
       
  1596     returns false. See isAbsolutePath().
       
  1597 
       
  1598     \sa isRelative() makeAbsolute() cleanPath()
       
  1599 */
       
  1600 
       
  1601 /*!
       
  1602    \fn bool QDir::isAbsolutePath(const QString &)
       
  1603 
       
  1604     Returns true if \a path is absolute; returns false if it is
       
  1605     relative.
       
  1606 
       
  1607     \sa isAbsolute() isRelativePath() makeAbsolute() cleanPath()
       
  1608 */
       
  1609 
       
  1610 /*!
       
  1611     Returns true if the directory path is relative; otherwise returns
       
  1612     false. (Under Unix a path is relative if it does not start with a
       
  1613     "/").
       
  1614 
       
  1615     \sa makeAbsolute() isAbsolute() isAbsolutePath() cleanPath()
       
  1616 */
       
  1617 
       
  1618 bool QDir::isRelative() const
       
  1619 {
       
  1620     Q_D(const QDir);
       
  1621 
       
  1622     if(!d->data->fileEngine)
       
  1623         return false;
       
  1624     return d->data->fileEngine->isRelativePath();
       
  1625 }
       
  1626 
       
  1627 
       
  1628 /*!
       
  1629     Converts the directory path to an absolute path. If it is already
       
  1630     absolute nothing happens. Returns true if the conversion
       
  1631     succeeded; otherwise returns false.
       
  1632 
       
  1633     \sa isAbsolute() isAbsolutePath() isRelative() cleanPath()
       
  1634 */
       
  1635 
       
  1636 bool QDir::makeAbsolute() // ### What do the return values signify?
       
  1637 {
       
  1638     Q_D(QDir);
       
  1639 
       
  1640     if(!d->data->fileEngine)
       
  1641         return false;
       
  1642     QString absolutePath = d->data->fileEngine->fileName(QAbstractFileEngine::AbsoluteName);
       
  1643     if(QDir::isRelativePath(absolutePath))
       
  1644         return false;
       
  1645     d->detach();
       
  1646     d->data->path = absolutePath;
       
  1647     d->data->fileEngine->setFileName(absolutePath);
       
  1648     if(!(d->data->fileEngine->fileFlags(QAbstractFileEngine::TypesMask) & QAbstractFileEngine::DirectoryType))
       
  1649         return false;
       
  1650     return true;
       
  1651 }
       
  1652 
       
  1653 /*!
       
  1654     Returns true if directory \a dir and this directory have the same
       
  1655     path and their sort and filter settings are the same; otherwise
       
  1656     returns false.
       
  1657 
       
  1658     Example:
       
  1659 
       
  1660     \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 10
       
  1661 */
       
  1662 
       
  1663 bool QDir::operator==(const QDir &dir) const
       
  1664 {
       
  1665     const QDirPrivate *d = d_func();
       
  1666     const QDirPrivate *other = dir.d_func();
       
  1667 
       
  1668     if(d->data == other->data)
       
  1669         return true;
       
  1670     Q_ASSERT(d->data->fileEngine && other->data->fileEngine);
       
  1671     if(d->data->fileEngine->caseSensitive() != other->data->fileEngine->caseSensitive())
       
  1672         return false;
       
  1673     if(d->data->filters == other->data->filters
       
  1674        && d->data->sort == other->data->sort
       
  1675        && d->data->nameFilters == other->data->nameFilters) {
       
  1676         QString dir1 = absolutePath(), dir2 = dir.absolutePath();
       
  1677         if(!other->data->fileEngine->caseSensitive())
       
  1678             return (dir1.toLower() == dir2.toLower());
       
  1679 
       
  1680         return (dir1 == dir2);
       
  1681 
       
  1682     }
       
  1683     return false;
       
  1684 }
       
  1685 
       
  1686 /*!
       
  1687     Makes a copy of the \a dir object and assigns it to this QDir
       
  1688     object.
       
  1689 */
       
  1690 
       
  1691 QDir &QDir::operator=(const QDir &dir)
       
  1692 {
       
  1693     if (this == &dir)
       
  1694         return *this;
       
  1695 
       
  1696     Q_D(QDir);
       
  1697     qAtomicAssign(d->data, dir.d_func()->data);
       
  1698     return *this;
       
  1699 }
       
  1700 
       
  1701 /*!
       
  1702     \overload
       
  1703     \obsolete
       
  1704 
       
  1705     Sets the directory path to the given \a path.
       
  1706 
       
  1707     Use setPath() instead.
       
  1708 */
       
  1709 
       
  1710 QDir &QDir::operator=(const QString &path)
       
  1711 {
       
  1712     Q_D(QDir);
       
  1713 
       
  1714     d->setPath(path);
       
  1715     return *this;
       
  1716 }
       
  1717 
       
  1718 /*!
       
  1719     \fn bool QDir::operator!=(const QDir &dir) const
       
  1720 
       
  1721     Returns true if directory \a dir and this directory have different
       
  1722     paths or different sort or filter settings; otherwise returns
       
  1723     false.
       
  1724 
       
  1725     Example:
       
  1726 
       
  1727     \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 11
       
  1728 */
       
  1729 
       
  1730 
       
  1731 /*!
       
  1732     Removes the file, \a fileName.
       
  1733 
       
  1734     Returns true if the file is removed successfully; otherwise
       
  1735     returns false.
       
  1736 */
       
  1737 
       
  1738 bool QDir::remove(const QString &fileName)
       
  1739 {
       
  1740     if (fileName.isEmpty()) {
       
  1741         qWarning("QDir::remove: Empty or null file name");
       
  1742         return false;
       
  1743     }
       
  1744     QString p = filePath(fileName);
       
  1745     return QFile::remove(p);
       
  1746 }
       
  1747 
       
  1748 /*!
       
  1749     Renames a file or directory from \a oldName to \a newName, and returns
       
  1750     true if successful; otherwise returns false.
       
  1751 
       
  1752     On most file systems, rename() fails only if \a oldName does not
       
  1753     exist, if \a newName and \a oldName are not on the same
       
  1754     partition or if a file with the new name already exists.
       
  1755     However, there are also other reasons why rename() can
       
  1756     fail. For example, on at least one file system rename() fails if
       
  1757     \a newName points to an open file.
       
  1758 */
       
  1759 
       
  1760 bool QDir::rename(const QString &oldName, const QString &newName)
       
  1761 {
       
  1762     Q_D(QDir);
       
  1763 
       
  1764     if (oldName.isEmpty() || newName.isEmpty()) {
       
  1765         qWarning("QDir::rename: Empty or null file name(s)");
       
  1766         return false;
       
  1767     }
       
  1768     if(!d->data->fileEngine)
       
  1769         return false;
       
  1770 
       
  1771     QFile file(filePath(oldName));
       
  1772     if(!file.exists())
       
  1773         return false;
       
  1774     return file.rename(filePath(newName));
       
  1775 }
       
  1776 
       
  1777 /*!
       
  1778     Returns true if the file called \a name exists; otherwise returns
       
  1779     false.
       
  1780 
       
  1781     Unless \a name contains an absolute file path, the file name is assumed
       
  1782     to be relative to the directory itself, so this function is typically used
       
  1783     to check for the presence of files within a directory.
       
  1784 
       
  1785     \sa QFileInfo::exists(), QFile::exists()
       
  1786 */
       
  1787 
       
  1788 bool QDir::exists(const QString &name) const
       
  1789 {
       
  1790     if (name.isEmpty()) {
       
  1791         qWarning("QDir::exists: Empty or null file name");
       
  1792         return false;
       
  1793     }
       
  1794     QString tmp = filePath(name);
       
  1795     return QFile::exists(tmp);
       
  1796 }
       
  1797 
       
  1798 /*!
       
  1799     Returns a list of the root directories on this system.
       
  1800 
       
  1801     On Windows this returns a list of QFileInfo objects containing "C:/",
       
  1802     "D:/", etc. On other operating systems, it returns a list containing
       
  1803     just one root directory (i.e. "/").
       
  1804 
       
  1805     \sa root(), rootPath()
       
  1806 */
       
  1807 
       
  1808 QFileInfoList QDir::drives()
       
  1809 {
       
  1810 #ifdef QT_NO_FSFILEENGINE
       
  1811     return QFileInfoList();
       
  1812 #else
       
  1813     return QFSFileEngine::drives();
       
  1814 #endif
       
  1815 }
       
  1816 
       
  1817 /*!
       
  1818     Returns the native directory separator: "/" under Unix (including
       
  1819     Mac OS X) and "\\" under Windows.
       
  1820 
       
  1821     You do not need to use this function to build file paths. If you
       
  1822     always use "/", Qt will translate your paths to conform to the
       
  1823     underlying operating system. If you want to display paths to the
       
  1824     user using their operating system's separator use
       
  1825     toNativeSeparators().
       
  1826 */
       
  1827 
       
  1828 QChar QDir::separator()
       
  1829 {
       
  1830 #if defined (Q_FS_FAT) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN)
       
  1831     return QLatin1Char('\\');
       
  1832 #elif defined(Q_OS_UNIX)
       
  1833     return QLatin1Char('/');
       
  1834 #elif defined (Q_OS_MAC)
       
  1835     return QLatin1Char(':');
       
  1836 #else
       
  1837     return QLatin1Char('/');
       
  1838 #endif
       
  1839 }
       
  1840 
       
  1841 /*!
       
  1842     Sets the application's current working directory to \a path.
       
  1843     Returns true if the directory was successfully changed; otherwise
       
  1844     returns false.
       
  1845 
       
  1846     \sa current() currentPath() home() root() temp()
       
  1847 */
       
  1848 
       
  1849 bool QDir::setCurrent(const QString &path)
       
  1850 {
       
  1851 #ifdef QT_NO_FSFILEENGINE
       
  1852     Q_UNUSED(path);
       
  1853     return false;
       
  1854 #else
       
  1855     return QFSFileEngine::setCurrentPath(path);
       
  1856 #endif
       
  1857 }
       
  1858 
       
  1859 /*!
       
  1860     \fn QDir QDir::current()
       
  1861 
       
  1862     Returns the application's current directory.
       
  1863 
       
  1864     The directory is constructed using the absolute path of the current directory,
       
  1865     ensuring that its path() will be the same as its absolutePath().
       
  1866 
       
  1867     \sa currentPath(), home(), root(), temp()
       
  1868 */
       
  1869 
       
  1870 /*!
       
  1871     Returns the absolute path of the application's current directory.
       
  1872 
       
  1873     \sa current(), homePath(), rootPath(), tempPath()
       
  1874 */
       
  1875 QString QDir::currentPath()
       
  1876 {
       
  1877 #ifdef QT_NO_FSFILEENGINE
       
  1878     return QString();
       
  1879 #else
       
  1880     return QFSFileEngine::currentPath();
       
  1881 #endif
       
  1882 }
       
  1883 
       
  1884 /*!
       
  1885   \fn QString QDir::currentDirPath()
       
  1886     Returns the absolute path of the application's current directory.
       
  1887 
       
  1888     Use currentPath() instead.
       
  1889 
       
  1890     \sa currentPath()
       
  1891 */
       
  1892 
       
  1893 /*!
       
  1894     \fn QDir QDir::home()
       
  1895 
       
  1896     Returns the user's home directory.
       
  1897 
       
  1898     The directory is constructed using the absolute path of the home directory,
       
  1899     ensuring that its path() will be the same as its absolutePath().
       
  1900 
       
  1901     See homePath() for details.
       
  1902 
       
  1903     \sa drives(), current(), root(), temp()
       
  1904 */
       
  1905 
       
  1906 /*!
       
  1907     Returns the absolute path of the user's home directory.
       
  1908 
       
  1909     Under Windows this function will return the directory of the
       
  1910     current user's profile. Typically, this is:
       
  1911 
       
  1912     \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 12
       
  1913 
       
  1914     Use the toNativeSeparators() function to convert the separators to
       
  1915     the ones that are appropriate for the underlying operating system.
       
  1916 
       
  1917     If the directory of the current user's profile does not exist or
       
  1918     cannot be retrieved, the following alternatives will be checked (in
       
  1919     the given order) until an existing and available path is found:
       
  1920 
       
  1921     \list 1
       
  1922     \o The path specified by the \c USERPROFILE environment variable.
       
  1923     \o The path formed by concatenating the \c HOMEDRIVE and \c HOMEPATH
       
  1924     environment variables.
       
  1925     \o The path specified by the \c HOME environment variable.
       
  1926     \o The path returned by the rootPath() function (which uses the \c SystemDrive
       
  1927     environment variable)
       
  1928     \o  The \c{C:/} directory.
       
  1929     \endlist
       
  1930 
       
  1931     Under non-Windows operating systems the \c HOME environment
       
  1932     variable is used if it exists, otherwise the path returned by the
       
  1933     rootPath(). On Symbian always the same as the path returned by the rootPath().
       
  1934 
       
  1935     \sa home(), currentPath(), rootPath(), tempPath()
       
  1936 */
       
  1937 QString QDir::homePath()
       
  1938 {
       
  1939 #ifdef QT_NO_FSFILEENGINE
       
  1940     return QString();
       
  1941 #else
       
  1942     return cleanPath(QFSFileEngine::homePath());
       
  1943 #endif
       
  1944 }
       
  1945 
       
  1946 /*!
       
  1947   \fn QString QDir::homeDirPath()
       
  1948 
       
  1949   Returns the absolute path of the user's home directory.
       
  1950 
       
  1951   Use homePath() instead.
       
  1952 
       
  1953   \sa homePath()
       
  1954  */
       
  1955 
       
  1956 /*!
       
  1957     \fn QDir QDir::temp()
       
  1958 
       
  1959     Returns the system's temporary directory.
       
  1960 
       
  1961     The directory is constructed using the absolute path of the temporary directory,
       
  1962     ensuring that its path() will be the same as its absolutePath().
       
  1963 
       
  1964     See tempPath() for details.
       
  1965 
       
  1966     \sa drives(), current(), home(), root()
       
  1967 */
       
  1968 
       
  1969 /*!
       
  1970     Returns the absolute path of the system's temporary directory.
       
  1971 
       
  1972     On Unix/Linux systems this is usually \c{/tmp}; on Windows this is
       
  1973     usually the path in the \c TEMP or \c TMP environment
       
  1974     variable. Whether a directory separator is added to the end or
       
  1975     not, depends on the operating system.
       
  1976 
       
  1977     \sa temp(), currentPath(), homePath(), rootPath()
       
  1978 */
       
  1979 QString QDir::tempPath()
       
  1980 {
       
  1981 #ifdef QT_NO_FSFILEENGINE
       
  1982     return QString();
       
  1983 #else
       
  1984     return cleanPath(QFSFileEngine::tempPath());
       
  1985 #endif
       
  1986 }
       
  1987 
       
  1988 /*!
       
  1989     \fn QDir QDir::root()
       
  1990 
       
  1991     Returns the root directory.
       
  1992 
       
  1993     The directory is constructed using the absolute path of the root directory,
       
  1994     ensuring that its path() will be the same as its absolutePath().
       
  1995 
       
  1996     See rootPath() for details.
       
  1997 
       
  1998     \sa drives(), current(), home(), temp()
       
  1999 */
       
  2000 
       
  2001 /*!
       
  2002     Returns the absolute path of the root directory.
       
  2003 
       
  2004     For Unix operating systems this returns "/". For Windows file
       
  2005     systems this normally returns "c:/". On Symbian this typically returns
       
  2006     "c:/data", i.e. the same as native PathInfo::PhoneMemoryRootPath().
       
  2007 
       
  2008     \sa root(), drives(), currentPath(), homePath(), tempPath()
       
  2009 */
       
  2010 QString QDir::rootPath()
       
  2011 {
       
  2012 #ifdef QT_NO_FSFILEENGINE
       
  2013     return QString();
       
  2014 #else
       
  2015     return QFSFileEngine::rootPath();
       
  2016 #endif
       
  2017 }
       
  2018 
       
  2019 /*!
       
  2020   \fn QString QDir::rootDirPath()
       
  2021 
       
  2022   Returns the absolute path of the root directory.
       
  2023 
       
  2024   Use rootPath() instead.
       
  2025 
       
  2026   \sa rootPath()
       
  2027 */
       
  2028 
       
  2029 #ifndef QT_NO_REGEXP
       
  2030 /*!
       
  2031     \overload
       
  2032 
       
  2033     Returns true if the \a fileName matches any of the wildcard (glob)
       
  2034     patterns in the list of \a filters; otherwise returns false. The
       
  2035     matching is case insensitive.
       
  2036 
       
  2037     \sa {QRegExp wildcard matching}, QRegExp::exactMatch() entryList() entryInfoList()
       
  2038 */
       
  2039 
       
  2040 
       
  2041 bool QDir::match(const QStringList &filters, const QString &fileName)
       
  2042 {
       
  2043     for(QStringList::ConstIterator sit = filters.begin(); sit != filters.end(); ++sit) {
       
  2044         QRegExp rx(*sit, Qt::CaseInsensitive, QRegExp::Wildcard);
       
  2045         if (rx.exactMatch(fileName))
       
  2046             return true;
       
  2047     }
       
  2048     return false;
       
  2049 }
       
  2050 
       
  2051 /*!
       
  2052     Returns true if the \a fileName matches the wildcard (glob)
       
  2053     pattern \a filter; otherwise returns false. The \a filter may
       
  2054     contain multiple patterns separated by spaces or semicolons.
       
  2055     The matching is case insensitive.
       
  2056 
       
  2057     \sa {QRegExp wildcard matching}, QRegExp::exactMatch() entryList() entryInfoList()
       
  2058 */
       
  2059 
       
  2060 bool QDir::match(const QString &filter, const QString &fileName)
       
  2061 {
       
  2062     return match(nameFiltersFromString(filter), fileName);
       
  2063 }
       
  2064 #endif
       
  2065 
       
  2066 /*!
       
  2067     Removes all multiple directory separators "/" and resolves any
       
  2068     "."s or ".."s found in the path, \a path.
       
  2069 
       
  2070     Symbolic links are kept. This function does not return the
       
  2071     canonical path, but rather the simplest version of the input.
       
  2072     For example, "./local" becomes "local", "local/../bin" becomes
       
  2073     "bin" and "/local/usr/../bin" becomes "/local/bin".
       
  2074 
       
  2075     \sa absolutePath() canonicalPath()
       
  2076 */
       
  2077 
       
  2078 QString QDir::cleanPath(const QString &path)
       
  2079 {
       
  2080     if (path.isEmpty())
       
  2081         return path;
       
  2082     QString name = path;
       
  2083     QChar dir_separator = separator();
       
  2084     if(dir_separator != QLatin1Char('/'))
       
  2085  	name.replace(dir_separator, QLatin1Char('/'));
       
  2086 
       
  2087     int used = 0, levels = 0;
       
  2088     const int len = name.length();
       
  2089     QVarLengthArray<QChar> outVector(len);
       
  2090     QChar *out = outVector.data();
       
  2091 
       
  2092     const QChar *p = name.unicode();
       
  2093     for(int i = 0, last = -1, iwrite = 0; i < len; i++) {
       
  2094         if(p[i] == QLatin1Char('/')) {
       
  2095             while(i < len-1 && p[i+1] == QLatin1Char('/')) {
       
  2096 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) //allow unc paths
       
  2097                 if(!i)
       
  2098                     break;
       
  2099 #endif
       
  2100                 i++;
       
  2101             }
       
  2102             bool eaten = false;
       
  2103             if(i < len - 1 && p[i+1] == QLatin1Char('.')) {
       
  2104                 int dotcount = 1;
       
  2105                 if(i < len - 2 && p[i+2] == QLatin1Char('.'))
       
  2106                     dotcount++;
       
  2107                 if(i == len - dotcount - 1) {
       
  2108                     if(dotcount == 1) {
       
  2109                         break;
       
  2110                     } else if(levels) {
       
  2111                         if(last == -1) {
       
  2112                             for(int i2 = iwrite-1; i2 >= 0; i2--) {
       
  2113                                 if(out[i2] == QLatin1Char('/')) {
       
  2114                                     last = i2;
       
  2115                                     break;
       
  2116                                 }
       
  2117                             }
       
  2118                         }
       
  2119                         used -= iwrite - last - 1;
       
  2120                         break;
       
  2121                     }
       
  2122                 } else if(p[i+dotcount+1] == QLatin1Char('/')) {
       
  2123                     if(dotcount == 2 && levels) {
       
  2124                         if(last == -1 || iwrite - last == 1) {
       
  2125                             for(int i2 = (last == -1) ? (iwrite-1) : (last-1); i2 >= 0; i2--) {
       
  2126                                 if(out[i2] == QLatin1Char('/')) {
       
  2127                                     eaten = true;
       
  2128                                     last = i2;
       
  2129                                     break;
       
  2130                                 }
       
  2131                             }
       
  2132                         } else {
       
  2133                             eaten = true;
       
  2134                         }
       
  2135                         if(eaten) {
       
  2136                             levels--;
       
  2137                             used -= iwrite - last;
       
  2138                             iwrite = last;
       
  2139                             last = -1;
       
  2140                         }
       
  2141                     } else if (dotcount == 2 && i > 0 && p[i - 1] != QLatin1Char('.')) {
       
  2142                         eaten = true;
       
  2143                         used -= iwrite - qMax(0, last);
       
  2144                         iwrite = qMax(0, last);
       
  2145                         last = -1;
       
  2146                         ++i;
       
  2147                     } else if(dotcount == 1) {
       
  2148                         eaten = true;
       
  2149                     }
       
  2150                     if(eaten)
       
  2151                         i += dotcount;
       
  2152                 } else {
       
  2153                     levels++;
       
  2154                 }
       
  2155             } else if(last != -1 && iwrite - last == 1) {
       
  2156 #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
       
  2157                 eaten = (iwrite > 2);
       
  2158 #else
       
  2159                 eaten = true;
       
  2160 #endif
       
  2161                 last = -1;
       
  2162             } else if(last != -1 && i == len-1) {
       
  2163                 eaten = true;
       
  2164             } else {
       
  2165                 levels++;
       
  2166             }
       
  2167             if(!eaten)
       
  2168                 last = i - (i - iwrite);
       
  2169             else
       
  2170                 continue;
       
  2171         } else if(!i && p[i] == QLatin1Char('.')) {
       
  2172             int dotcount = 1;
       
  2173             if(len >= 1 && p[1] == QLatin1Char('.'))
       
  2174                 dotcount++;
       
  2175             if(len >= dotcount && p[dotcount] == QLatin1Char('/')) {
       
  2176                 if(dotcount == 1) {
       
  2177                     i++;
       
  2178                     while(i+1 < len-1 && p[i+1] == QLatin1Char('/'))
       
  2179                         i++;
       
  2180                     continue;
       
  2181                 }
       
  2182             }
       
  2183         }
       
  2184         out[iwrite++] = p[i];
       
  2185         used++;
       
  2186     }
       
  2187     QString ret;
       
  2188     if(used == len)
       
  2189         ret = name;
       
  2190     else
       
  2191 	ret = QString(out, used);
       
  2192 
       
  2193     // Strip away last slash except for root directories
       
  2194     if (ret.endsWith(QLatin1Char('/'))
       
  2195         && !(ret.size() == 1 || (ret.size() == 3 && ret.at(1) == QLatin1Char(':'))))
       
  2196         ret = ret.left(ret.length() - 1);
       
  2197 
       
  2198     return ret;
       
  2199 }
       
  2200 
       
  2201 /*!
       
  2202     Returns true if \a path is relative; returns false if it is
       
  2203     absolute.
       
  2204 
       
  2205     \sa isRelative() isAbsolutePath() makeAbsolute()
       
  2206 */
       
  2207 
       
  2208 bool QDir::isRelativePath(const QString &path)
       
  2209 {
       
  2210     return QFileInfo(path).isRelative();
       
  2211 }
       
  2212 
       
  2213 /*!
       
  2214     Refreshes the directory information.
       
  2215 */
       
  2216 
       
  2217 void QDir::refresh() const
       
  2218 {
       
  2219     Q_D(const QDir);
       
  2220 
       
  2221     d->data->clear();
       
  2222 }
       
  2223 
       
  2224 /*!
       
  2225     \internal
       
  2226 
       
  2227     Returns a list of name filters from the given \a nameFilter. (If
       
  2228     there is more than one filter, each pair of filters is separated
       
  2229     by a space or by a semicolon.)
       
  2230 */
       
  2231 
       
  2232 QStringList QDir::nameFiltersFromString(const QString &nameFilter)
       
  2233 {
       
  2234     return QDirPrivate::splitFilters(nameFilter);
       
  2235 }
       
  2236 
       
  2237 /*!
       
  2238     \macro void Q_INIT_RESOURCE(name)
       
  2239     \relates QDir
       
  2240 
       
  2241     Initializes the resources specified by the \c .qrc file with the
       
  2242     specified base \a name. Normally, Qt resources are loaded
       
  2243     automatically at startup. The Q_INIT_RESOURCE() macro is
       
  2244     necessary on some platforms for resources stored in a static
       
  2245     library.
       
  2246 
       
  2247     For example, if your application's resources are listed in a file
       
  2248     called \c myapp.qrc, you can ensure that the resources are
       
  2249     initialized at startup by adding this line to your \c main()
       
  2250     function:
       
  2251 
       
  2252     \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 13
       
  2253 
       
  2254     If the file name contains characters that cannot be part of a valid C++ function name
       
  2255     (such as '-'), they have to be replaced by the underscore character ('_').
       
  2256 
       
  2257     Note: This macro cannot be used in a namespace. It should be called from
       
  2258     main(). If that is not possible, the following workaround can be used
       
  2259     to init the resource \c myapp from the function \c{MyNamespace::myFunction}:
       
  2260 
       
  2261     \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 14
       
  2262 
       
  2263     \sa Q_CLEANUP_RESOURCE(), {The Qt Resource System}
       
  2264 */
       
  2265 
       
  2266 /*!
       
  2267     \since 4.1
       
  2268     \macro void Q_CLEANUP_RESOURCE(name)
       
  2269     \relates QDir
       
  2270 
       
  2271     Unloads the resources specified by the \c .qrc file with the base
       
  2272     name \a name.
       
  2273 
       
  2274     Normally, Qt resources are unloaded automatically when the
       
  2275     application terminates, but if the resources are located in a
       
  2276     plugin that is being unloaded, call Q_CLEANUP_RESOURCE() to force
       
  2277     removal of your resources.
       
  2278 
       
  2279     Note: This macro cannot be used in a namespace. Please see the
       
  2280     Q_INIT_RESOURCE documentation for a workaround.
       
  2281 
       
  2282     Example:
       
  2283 
       
  2284     \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 15
       
  2285 
       
  2286     \sa Q_INIT_RESOURCE(), {The Qt Resource System}
       
  2287 */
       
  2288 
       
  2289 #ifdef QT3_SUPPORT
       
  2290 
       
  2291 /*!
       
  2292     \fn bool QDir::matchAllDirs() const
       
  2293 
       
  2294     Use filter() & AllDirs instead.
       
  2295 */
       
  2296 bool QDir::matchAllDirs() const
       
  2297 {
       
  2298     Q_D(const QDir);
       
  2299     return d->matchAllDirs;
       
  2300 }
       
  2301 
       
  2302 
       
  2303 /*!
       
  2304     \fn void QDir::setMatchAllDirs(bool on)
       
  2305 
       
  2306     Use setFilter() instead.
       
  2307 */
       
  2308 void QDir::setMatchAllDirs(bool on)
       
  2309 {
       
  2310     Q_D(QDir);
       
  2311     d->matchAllDirs = on;
       
  2312 }
       
  2313 
       
  2314 /*!
       
  2315     Use nameFilters() instead.
       
  2316 */
       
  2317 QString QDir::nameFilter() const
       
  2318 {
       
  2319     Q_D(const QDir);
       
  2320 
       
  2321     return nameFilters().join(QString(d->filterSepChar));
       
  2322 }
       
  2323 
       
  2324 /*!
       
  2325     Use setNameFilters() instead.
       
  2326 
       
  2327     The \a nameFilter is a wildcard (globbing) filter that understands
       
  2328     "*" and "?" wildcards. (See \l{QRegExp wildcard matching}.) You may
       
  2329     specify several filter entries, each separated by spaces or by
       
  2330     semicolons.
       
  2331 
       
  2332     For example, if you want entryList() and entryInfoList() to list
       
  2333     all files ending with either ".cpp" or ".h", you would use either
       
  2334     dir.setNameFilters("*.cpp *.h") or dir.setNameFilters("*.cpp;*.h").
       
  2335 
       
  2336     \oldcode
       
  2337         QString filter = "*.cpp *.cxx *.cc";
       
  2338         dir.setNameFilter(filter);
       
  2339     \newcode
       
  2340         QString filter = "*.cpp *.cxx *.cc";
       
  2341         dir.setNameFilters(filter.split(' '));
       
  2342     \endcode
       
  2343 */
       
  2344 void QDir::setNameFilter(const QString &nameFilter)
       
  2345 {
       
  2346     Q_D(QDir);
       
  2347 
       
  2348     d->filterSepChar = QDirPrivate::getFilterSepChar(nameFilter);
       
  2349     setNameFilters(QDirPrivate::splitFilters(nameFilter, d->filterSepChar));
       
  2350 }
       
  2351 
       
  2352 /*!
       
  2353     \fn QString QDir::absPath() const
       
  2354 
       
  2355     Use absolutePath() instead.
       
  2356 */
       
  2357 
       
  2358 /*!
       
  2359     \fn QString QDir::absFilePath(const QString &fileName, bool acceptAbsPath) const
       
  2360 
       
  2361     Use absoluteFilePath(\a fileName) instead.
       
  2362 
       
  2363     The \a acceptAbsPath parameter is ignored.
       
  2364 */
       
  2365 
       
  2366 /*!
       
  2367     \fn bool QDir::mkdir(const QString &dirName, bool acceptAbsPath) const
       
  2368 
       
  2369     Use mkdir(\a dirName) instead.
       
  2370 
       
  2371     The \a acceptAbsPath parameter is ignored.
       
  2372 */
       
  2373 
       
  2374 /*!
       
  2375     \fn bool QDir::rmdir(const QString &dirName, bool acceptAbsPath) const
       
  2376 
       
  2377     Use rmdir(\a dirName) instead.
       
  2378 
       
  2379     The \a acceptAbsPath parameter is ignored.
       
  2380 */
       
  2381 
       
  2382 /*!
       
  2383     \fn QStringList QDir::entryList(const QString &nameFilter, Filters filters,
       
  2384                                     SortFlags sort) const
       
  2385     \overload
       
  2386 
       
  2387     Use the overload that takes a name filter string list as first
       
  2388     argument instead of a combination of attribute filter flags.
       
  2389 */
       
  2390 
       
  2391 /*!
       
  2392     \fn QFileInfoList QDir::entryInfoList(const QString &nameFilter, Filters filters,
       
  2393                                           SortFlags sort) const
       
  2394     \overload
       
  2395 
       
  2396     Use the overload that takes a name filter string list as first
       
  2397     argument instead of a combination of attribute filter flags.
       
  2398 */
       
  2399 
       
  2400 /*!
       
  2401     \fn void QDir::convertToAbs()
       
  2402 
       
  2403     Use makeAbsolute() instead.
       
  2404 */
       
  2405 
       
  2406 /*!
       
  2407     \fn QString QDir::cleanDirPath(const QString &name)
       
  2408 
       
  2409     Use cleanPath() instead.
       
  2410 */
       
  2411 
       
  2412 /*!
       
  2413     \typedef QDir::FilterSpec
       
  2414 
       
  2415     Use QDir::Filters instead.
       
  2416 */
       
  2417 
       
  2418 /*!
       
  2419     \typedef QDir::SortSpec
       
  2420 
       
  2421     Use QDir::SortFlags instead.
       
  2422 */
       
  2423 #endif
       
  2424 #ifndef QT_NO_DEBUG_STREAM
       
  2425 QDebug operator<<(QDebug debug, QDir::Filters filters)
       
  2426 {
       
  2427     QStringList flags;
       
  2428     if (filters == QDir::NoFilter) {
       
  2429         flags << QLatin1String("NoFilter");
       
  2430     } else {
       
  2431         if (filters & QDir::Dirs) flags << QLatin1String("Dirs");
       
  2432         if (filters & QDir::AllDirs) flags << QLatin1String("AllDirs");
       
  2433         if (filters & QDir::Files) flags << QLatin1String("Files");
       
  2434         if (filters & QDir::Drives) flags << QLatin1String("Drives");
       
  2435         if (filters & QDir::NoSymLinks) flags << QLatin1String("NoSymLinks");
       
  2436         if (filters & QDir::NoDotAndDotDot) flags << QLatin1String("NoDotAndDotDot");
       
  2437         if ((filters & QDir::AllEntries) == QDir::AllEntries) flags << QLatin1String("AllEntries");
       
  2438         if (filters & QDir::Readable) flags << QLatin1String("Readable");
       
  2439         if (filters & QDir::Writable) flags << QLatin1String("Writable");
       
  2440         if (filters & QDir::Executable) flags << QLatin1String("Executable");
       
  2441         if (filters & QDir::Modified) flags << QLatin1String("Modified");
       
  2442         if (filters & QDir::Hidden) flags << QLatin1String("Hidden");
       
  2443         if (filters & QDir::System) flags << QLatin1String("System");
       
  2444         if (filters & QDir::CaseSensitive) flags << QLatin1String("CaseSensitive");
       
  2445     }
       
  2446     debug << "QDir::Filters(" << qPrintable(flags.join(QLatin1String("|"))) << ')';
       
  2447     return debug;
       
  2448 }
       
  2449 
       
  2450 static QDebug operator<<(QDebug debug, QDir::SortFlags sorting)
       
  2451 {
       
  2452     if (sorting == QDir::NoSort) {
       
  2453         debug << "QDir::SortFlags(NoSort)";
       
  2454     } else {
       
  2455         QString type;
       
  2456         if ((sorting & 3) == QDir::Name) type = QLatin1String("Name");
       
  2457         if ((sorting & 3) == QDir::Time) type = QLatin1String("Time");
       
  2458         if ((sorting & 3) == QDir::Size) type = QLatin1String("Size");
       
  2459         if ((sorting & 3) == QDir::Unsorted) type = QLatin1String("Unsorted");
       
  2460 
       
  2461         QStringList flags;
       
  2462         if (sorting & QDir::DirsFirst) flags << QLatin1String("DirsFirst");
       
  2463         if (sorting & QDir::DirsLast) flags << QLatin1String("DirsLast");
       
  2464         if (sorting & QDir::IgnoreCase) flags << QLatin1String("IgnoreCase");
       
  2465         if (sorting & QDir::LocaleAware) flags << QLatin1String("LocaleAware");
       
  2466         if (sorting & QDir::Type) flags << QLatin1String("Type");
       
  2467         debug << "QDir::SortFlags(" << qPrintable(type)
       
  2468               << '|'
       
  2469               << qPrintable(flags.join(QLatin1String("|"))) << ')';
       
  2470     }
       
  2471     return debug;
       
  2472 }
       
  2473 
       
  2474 QDebug operator<<(QDebug debug, const QDir &dir)
       
  2475 {
       
  2476     debug.maybeSpace() << "QDir(" << dir.path()
       
  2477                        << ", nameFilters = {"
       
  2478                        << qPrintable(dir.nameFilters().join(QLatin1String(",")))
       
  2479                        << "}, "
       
  2480                        << dir.sorting()
       
  2481                        << ','
       
  2482                        << dir.filter()
       
  2483                        << ')';
       
  2484     return debug.space();
       
  2485 }
       
  2486 
       
  2487 
       
  2488 
       
  2489 #endif
       
  2490 
       
  2491 QT_END_NAMESPACE