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

Last change on this file since 395 was 367, checked in by Dmitry A. Kuminov, 16 years ago

corelib/io: Fixed: QDir::midir()/mkpath()/rmdir()/rmpath() didn't properly handle relative paths and UNC paths which could result into a false failure to create a requested path or creating it at the wrong location.

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