source: trunk/src/corelib/io/qdir.cpp@ 1084

Last change on this file since 1084 was 1084, checked in by Dmitry A. Kuminov, 14 years ago

QDir::cleanPath(): fix a r1042 regression.

It would treat paths like D://some/path as if they were UNC
paths and leave the double slash in.

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