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

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

trunk: Merged in qt 4.6.1 sources.

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