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