Chameleon

Chameleon Svn Source Tree

Root/branches/xZenu/src/util/doxygen/qtools/qdir.cpp

Source at commit 1322 created 12 years 8 months ago.
By meklort, Add doxygen to utils folder
1/****************************************************************************
2**
3**
4** Implementation of QDir class
5**
6** Created : 950427
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the tools module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qglobal.h"
39
40#include "qdir.h"
41
42#ifndef QT_NO_DIR
43#include "qfileinfo.h"
44#include "qfiledefs_p.h"
45#include "qregexp.h"
46#include "qstringlist.h"
47#include <stdlib.h>
48#include <ctype.h>
49
50// NOT REVISED
51/*!
52 \class QDir qdir.h
53 \brief Traverses directory structures and contents in a
54 platform-independent way.
55
56 \ingroup io
57
58 A QDir can point to a file using either a relative or an absolute file
59 path. Absolute file paths begin with the directory separator ('/') or a
60 drive specification (not applicable to UNIX). Relative file names begin
61 with a directory name or a file name and specify a path relative to the
62 current directory.
63
64 An example of an absolute path is the string "/tmp/quartz", a relative
65 path might look like "src/fatlib". You can use the function isRelative()
66 to check if a QDir is using a relative or an absolute file path. You can
67 call the function convertToAbs() to convert a relative QDir to an
68 absolute one.
69
70 The directory "example" under the current directory is checked for existence
71 in the example below:
72
73 \code
74 QDir d( "example" );// "./example"
75 if ( !d.exists() )
76qWarning( "Cannot find the example directory" );
77 \endcode
78
79 If you always use '/' as a directory separator, Qt will translate your
80 paths to conform to the underlying operating system.
81
82 cd() and cdUp() can be used to navigate the directory tree. Note that the
83 logical cd and cdUp operations are not performed if the new directory does
84 not exist.
85
86 Example:
87 \code
88 QDir d = QDir::root();// "/"
89 if ( !d.cd("tmp") ) {// "/tmp"
90qWarning( "Cannot find the \"/tmp\" directory" );
91 } else {
92QFile f( d.filePath("ex1.txt") );// "/tmp/ex1.txt"
93if ( !f.open(IO_ReadWrite) )
94 qWarning( "Cannot create the file %s", f.name() );
95 }
96 \endcode
97
98 To read the contents of a directory you can use the entryList() and
99 entryInfoList() functions.
100
101 Example:
102 \code
103 #include <stdio.h>
104 #include <qdir.h>
105
106 //
107 // This program scans the current directory and lists all files
108 // that are not symbolic links, sorted by size with the smallest files
109 // first.
110 //
111
112 int main( int argc, char **argv )
113 {
114QDir d;
115d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
116d.setSorting( QDir::Size | QDir::Reversed );
117
118const QFileInfoList *list = d.entryInfoList();
119QFileInfoListIterator it( *list );// create list iterator
120QFileInfo *fi;// pointer for traversing
121
122printf( " BYTES FILENAME\n" );// print header
123while ( (fi=it.current()) ) {// for each file...
124 printf( "%10li %s\n", fi->size(), fi->fileName().data() );
125 ++it;// goto next list element
126}
127 }
128 \endcode
129*/
130
131
132/*!
133 Constructs a QDir pointing to the current directory.
134 \sa currentDirPath()
135*/
136
137QDir::QDir()
138{
139 dPath = QString::fromLatin1(".");
140 init();
141}
142
143/*!
144 Constructs a QDir.
145
146 \arg \e path is the directory.
147 \arg \e nameFilter is the file name filter.
148 \arg \e sortSpec is the sort specification, which describes how to
149 sort the files in the directory.
150 \arg \e filterSpec is the filter specification, which describes how
151 to filter the files in the directory.
152
153 Most of these arguments (except \e path) have optional values.
154
155 Example:
156 \code
157 // lists all files in /tmp
158
159 QDir d( "/tmp" );
160 for ( int i=0; i<d.count(); i++ )
161printf( "%s\n", d[i] );
162 \endcode
163
164 If \e path is "" or null, the directory is set to "." (the current
165 directory). If \e nameFilter is "" or null, it is set to "*" (all
166 files).
167
168 No check is made to ensure that the directory exists.
169
170 \sa exists(), setPath(), setNameFilter(), setFilter(), setSorting()
171*/
172
173QDir::QDir( const QString &path, const QString &nameFilter,
174 int sortSpec, int filterSpec )
175{
176 init();
177 dPath = cleanDirPath( path );
178 if ( dPath.isEmpty() )
179dPath = QString::fromLatin1(".");
180 nameFilt = nameFilter;
181 if ( nameFilt.isEmpty() )
182nameFilt = QString::fromLatin1("*");
183 filtS = (FilterSpec)filterSpec;
184 sortS = (SortSpec)sortSpec;
185}
186
187/*!
188 Constructs a QDir that is a copy of the given directory.
189 \sa operator=()
190*/
191
192QDir::QDir( const QDir &d )
193{
194 dPath = d.dPath;
195 fList = 0;
196 fiList = 0;
197 nameFilt = d.nameFilt;
198 dirty = TRUE;
199 allDirs = d.allDirs;
200 filtS = d.filtS;
201 sortS = d.sortS;
202}
203
204
205void QDir::init()
206{
207 fList = 0;
208 fiList = 0;
209 nameFilt = QString::fromLatin1("*");
210 dirty = TRUE;
211 allDirs = FALSE;
212 filtS = All;
213 sortS = SortSpec(Name | IgnoreCase);
214}
215
216/*!
217 Destructs the QDir and cleans up.
218*/
219
220QDir::~QDir()
221{
222 if ( fList )
223 delete fList;
224 if ( fiList )
225 delete fiList;
226}
227
228
229/*!
230 Sets the path of the directory. The path is cleaned of redundant ".", ".."
231 and multiple separators. No check is made to ensure that a directory
232 with this path exists.
233
234 The path can be either absolute or relative. Absolute paths begin with the
235 directory separator ('/') or a drive specification (not
236 applicable to UNIX).
237 Relative file names begin with a directory name or a file name and specify
238 a path relative to the current directory. An example of
239 an absolute path is the string "/tmp/quartz", a relative path might look like
240 "src/fatlib". You can use the function isRelative() to check if a QDir
241 is using a relative or an absolute file path. You can call the function
242 convertToAbs() to convert a relative QDir to an absolute one.
243
244 \sa path(), absPath(), exists(), cleanDirPath(), dirName(),
245 absFilePath(), isRelative(), convertToAbs()
246*/
247
248void QDir::setPath( const QString &path )
249{
250 dPath = cleanDirPath( path );
251 if ( dPath.isEmpty() )
252dPath = QString::fromLatin1(".");
253 dirty = TRUE;
254}
255
256/*!
257 \fn QString QDir::path() const
258 Returns the path, this may contain symbolic links, but never contains
259 redundant ".", ".." or multiple separators.
260
261 The returned path can be either absolute or relative (see setPath()).
262
263 \sa setPath(), absPath(), exists(), cleanDirPath(), dirName(),
264 absFilePath(), convertSeparators()
265*/
266
267/*!
268 Returns the absolute (a path that starts with '/') path, which may
269 contain symbolic links, but never contains redundant ".", ".." or
270 multiple separators.
271
272 \sa setPath(), canonicalPath(), exists(), cleanDirPath(), dirName(),
273 absFilePath()
274*/
275
276QString QDir::absPath() const
277{
278 if ( QDir::isRelativePath(dPath) ) {
279QString tmp = currentDirPath();
280if ( tmp.right(1) != QString::fromLatin1("/") )
281 tmp += '/';
282tmp += dPath;
283return cleanDirPath( tmp );
284 } else {
285return cleanDirPath( dPath );
286 }
287}
288
289/*!
290 Returns the name of the directory, this is NOT the same as the path, e.g.
291 a directory with the name "mail", might have the path "/var/spool/mail".
292 If the directory has no name (e.g. the root directory) a null string is
293 returned.
294
295 No check is made to ensure that a directory with this name actually exists.
296
297 \sa path(), absPath(), absFilePath(), exists(), QString::isNull()
298*/
299
300QString QDir::dirName() const
301{
302 int pos = dPath.findRev( '/' );
303 if ( pos == -1 )
304return dPath;
305 return dPath.right( dPath.length() - pos - 1 );
306}
307
308/*!
309 Returns the path name of a file in the directory. Does NOT check if
310 the file actually exists in the directory. If the QDir is relative
311 the returned path name will also be relative. Redundant multiple separators
312 or "." and ".." directories in \e fileName will not be removed (see
313 cleanDirPath()).
314
315 If \e acceptAbsPath is TRUE a \e fileName starting with a separator
316 ('/') will be returned without change.
317 If \e acceptAbsPath is FALSE an absolute path will be appended to
318 the directory path.
319
320 \sa absFilePath(), isRelative(), canonicalPath()
321*/
322
323QString QDir::filePath( const QString &fileName,
324bool acceptAbsPath ) const
325{
326 if ( acceptAbsPath && !isRelativePath(fileName) )
327return QString(fileName);
328
329 QString tmp = dPath;
330 if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
331 fileName[0] != '/') )
332tmp += '/';
333 tmp += fileName;
334 return tmp;
335}
336
337/*!
338 Returns the absolute path name of a file in the directory. Does NOT check if
339 the file actually exists in the directory. Redundant multiple separators
340 or "." and ".." directories in \e fileName will NOT be removed (see
341 cleanDirPath()).
342
343 If \e acceptAbsPath is TRUE a \e fileName starting with a separator
344 ('/') will be returned without change.
345 if \e acceptAbsPath is FALSE an absolute path will be appended to
346 the directory path.
347
348 \sa filePath()
349*/
350
351QString QDir::absFilePath( const QString &fileName,
352 bool acceptAbsPath ) const
353{
354 if ( acceptAbsPath && !isRelativePath( fileName ) )
355return fileName;
356
357 QString tmp = absPath();
358 if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
359 fileName[0] != '/') )
360tmp += '/';
361 tmp += fileName;
362 return tmp;
363}
364
365
366/*!
367 Converts the '/' separators in \a pathName to system native
368 separators. Returns the translated string.
369
370 On Windows, convertSeparators("c:/winnt/system32") returns
371 "c:\winnt\system32".
372
373 No conversion is done on UNIX.
374*/
375
376QString QDir::convertSeparators( const QString &pathName )
377{
378 QString n( pathName );
379#if defined(_OS_FATFS_) || defined(_OS_OS2EMX_)
380 for ( int i=0; i<(int)n.length(); i++ ) {
381if ( n[i] == '/' )
382 n[i] = '\\';
383 }
384#endif
385 return n;
386}
387
388
389/*!
390 Changes directory by descending into the given directory. Returns
391 TRUE if the new directory exists and is readable. Note that the logical
392 cd operation is NOT performed if the new directory does not exist.
393
394 If \e acceptAbsPath is TRUE a path starting with a separator ('/')
395 will cd to the absolute directory, if \e acceptAbsPath is FALSE
396 any number of separators at the beginning of \e dirName will be removed.
397
398 Example:
399 \code
400 QDir d = QDir::home(); // now points to home directory
401 if ( !d.cd("c++") ) { // now points to "c++" under home directory if OK
402 QFileInfo fi( d, "c++" );
403 if ( fi.exists() ) {
404 if ( fi.isDir() )
405 qWarning( "Cannot cd into \"%s\".", (char*)d.absFilePath("c++") );
406 else
407 qWarning( "Cannot create directory \"%s\"\n"
408 "A file named \"c++\" already exists in \"%s\"",
409 (const char *)d.absFilePath("c++"),
410 (const char *)d.path() );
411 return;
412 } else {
413 qWarning( "Creating directory \"%s\"",
414 (const char *) d.absFilePath("c++") );
415 if ( !d.mkdir( "c++" ) ) {
416 qWarning("Could not create directory \"%s\"",
417 (const char *)d.absFilePath("c++") );
418 return;
419 }
420 }
421 }
422 \endcode
423
424 Calling cd( ".." ) is equivalent to calling cdUp().
425
426 \sa cdUp(), isReadable(), exists(), path()
427*/
428
429bool QDir::cd( const QString &dirName, bool acceptAbsPath )
430{
431 if ( dirName.isEmpty() || dirName==QString::fromLatin1(".") )
432return TRUE;
433 QString old = dPath;
434 if ( acceptAbsPath && !isRelativePath(dirName) ) {
435dPath = cleanDirPath( dirName );
436 } else {
437if ( !isRoot() )
438 dPath += '/';
439dPath += dirName;
440if ( dirName.find('/') >= 0
441|| old == QString::fromLatin1(".")
442|| dirName == QString::fromLatin1("..") )
443 dPath = cleanDirPath( dPath );
444 }
445 if ( !exists() ) {
446dPath = old;// regret
447return FALSE;
448 }
449 dirty = TRUE;
450 return TRUE;
451}
452
453/*!
454 Changes directory by moving one directory up the path followed to arrive
455 at the current directory.
456
457 Returns TRUE if the new directory exists and is readable. Note that the
458 logical cdUp() operation is not performed if the new directory does not
459 exist.
460
461 \sa cd(), isReadable(), exists(), path()
462*/
463
464bool QDir::cdUp()
465{
466 return cd( QString::fromLatin1("..") );
467}
468
469/*!
470 \fn QString QDir::nameFilter() const
471 Returns the string set by setNameFilter()
472*/
473
474/*!
475 Sets the name filter used by entryList() and entryInfoList().
476
477 The name filter is a wildcarding filter that understands "*" and "?"
478 wildcards, You may specify several filter entries separated by a " " or a ";". If
479 you want entryList() and entryInfoList() to list all files ending with
480 ".cpp" and all files ending with ".h", you simply call
481 dir.setNameFilter("*.cpp *.h") or dir.setNameFilter("*.cpp;*.h")
482
483 \sa nameFilter(), setFilter()
484*/
485
486void QDir::setNameFilter( const QString &nameFilter )
487{
488 nameFilt = nameFilter;
489 if ( nameFilt.isEmpty() )
490nameFilt = QString::fromLatin1("*");
491 dirty = TRUE;
492}
493
494/*!
495 \fn QDir::FilterSpec QDir::filter() const
496 Returns the value set by setFilter()
497*/
498
499/*! \enum QDir::FilterSpec
500
501 This enum describes how QDir is to select what entries in a
502 directory to return. The filter value is specified by or-ing
503 together values from the following list: <ul>
504
505 <li> \c Dirs - List directories only
506 <li> \c Files - List files only
507
508 <li> \c Drives - List disk drives (does nothing under unix)
509 <li> \c NoSymLinks - Do not list symbolic links (where they exist)
510 <li> \c Readable - List files for which the application has read access.
511 <li> \c Writable - List files for which the application has write access.
512 <li> \c Executable - List files for which the application has execute access
513 <li> \c Modified - Only list files that have been modified (does nothing
514 under unix)
515 <li> \c Hidden - List hidden files (on unix, files starting with a .)
516 <li> \c System - List system files (does nothing under unix)
517 </ul>
518
519 If you do not set any of \c Readable, \c Writable or \c Executable,
520 QDir will set all three of them. This makes the default easy to
521 write and at the same time useful.
522
523 Examples: \c Readable|Writable means list all files for which the
524 application has read access, write access or both. \c Dirs|Drives
525 means list drives, directories, all files that the application can
526 read, write or execute, and also symlinks to such files/directories.
527*/
528
529
530/*!
531 Sets the filter used by entryList() and entryInfoList(). The filter is used
532 to specify the kind of files that should be returned by entryList() and
533 entryInfoList().
534
535 \sa filter(), setNameFilter()
536*/
537
538void QDir::setFilter( int filterSpec )
539{
540 if ( filtS == (FilterSpec) filterSpec )
541return;
542 filtS = (FilterSpec) filterSpec;
543 dirty = TRUE;
544}
545
546/*!
547 \fn QDir::SortSpec QDir::sorting() const
548
549 Returns the value set by setSorting()
550
551 \sa setSorting()
552*/
553
554/*! \enum QDir::SortSpec
555
556 This enum describes how QDir is to sort entries in a directory when
557 it returns a list of them. The sort value is specified by or-ing
558 together values from the following list: <ul>
559
560 <li> \c Name - sort by name
561 <li> \c Time - sort by time (modification time)
562 <li> \c Size - sort by file size
563 <li> \c Unsorted - do not sort
564
565 <li> \c DirsFirst - put all directories first in the list
566 <li> \c Reversed - reverse the sort order
567 <li> \c IgnoreCase - sort case-insensitively
568
569 </ul>
570
571 You can only specify one of the first four. If you specify both \c
572 DirsFirst and \c Reversed, directories are still put first but the
573 list is otherwise reversed.
574*/
575
576// ### Unsorted+DirsFirst ? Unsorted+Reversed?
577
578/*!
579 Sets the sorting order used by entryList() and entryInfoList().
580
581 The \e sortSpec is specified by or-ing values from the enum
582 SortSpec. The different values are:
583
584 One of these:
585 <dl compact>
586 <dt>Name<dd> Sort by name (alphabetical order).
587 <dt>Time<dd> Sort by time (most recent first).
588 <dt>Size<dd> Sort by size (largest first).
589 <dt>Unsorted<dd> Use the operating system order (UNIX does NOT sort
590 alphabetically).
591
592 ORed with zero or more of these:
593
594 <dt>DirsFirst<dd> Always put directory names first.
595 <dt>Reversed<dd> Reverse sort order.
596 <dt>IgnoreCase<dd> Ignore case when sorting by name.
597 </dl>
598*/
599
600void QDir::setSorting( int sortSpec )
601{
602 if ( sortS == (SortSpec) sortSpec )
603return;
604 sortS = (SortSpec) sortSpec;
605 dirty = TRUE;
606}
607
608/*!
609 \fn bool QDir::matchAllDirs() const
610 Returns the value set by setMatchAllDirs()
611
612 \sa setMatchAllDirs()
613*/
614
615/*!
616 If \e enable is TRUE, all directories will be listed (even if they do not
617 match the filter or the name filter), otherwise only matched directories
618 will be listed.
619
620 \bug Currently, directories that do not match the filter will not be
621 included (the name filter will be ignored as expected).
622
623 \sa matchAllDirs()
624*/
625
626void QDir::setMatchAllDirs( bool enable )
627{
628 if ( (bool)allDirs == enable )
629return;
630 allDirs = enable;
631 dirty = TRUE;
632}
633
634
635/*!
636 Returns the number of files that was found.
637 Equivalent to entryList().count().
638 \sa operator[](), entryList()
639*/
640
641uint QDir::count() const
642{
643 return entryList().count();
644}
645
646/*!
647 Returns the file name at position \e index in the list of found file
648 names.
649 Equivalent to entryList().at(index).
650
651 Returns null if the \e index is out of range or if the entryList()
652 function failed.
653
654 \sa count(), entryList()
655*/
656
657QString QDir::operator[]( int index ) const
658{
659 entryList();
660 return fList && index >= 0 && index < (int)fList->count() ?
661(*fList)[index] : QString::null;
662}
663
664
665/*!
666 This function is included to easy porting from Qt 1.x to Qt 2.0,
667 it is the same as entryList(), but encodes the filenames as 8-bit
668 strings using QFile::encodedName().
669
670 It is more efficient to use entryList().
671*/
672QStrList QDir::encodedEntryList( int filterSpec, int sortSpec ) const
673{
674 QStrList r;
675 QStringList l = entryList(filterSpec,sortSpec);
676 for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
677r.append( QFile::encodeName(*it) );
678 }
679 return r;
680}
681
682/*!
683 This function is included to easy porting from Qt 1.x to Qt 2.0,
684 it is the same as entryList(), but encodes the filenames as 8-bit
685 strings using QFile::encodedName().
686
687 It is more efficient to use entryList().
688*/
689QStrList QDir::encodedEntryList( const QString &nameFilter,
690 int filterSpec,
691 int sortSpec ) const
692{
693 QStrList r;
694 QStringList l = entryList(nameFilter,filterSpec,sortSpec);
695 for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
696r.append( QFile::encodeName(*it) );
697 }
698 return r;
699}
700
701
702
703/*!
704 Returns a list of the names of all files and directories in the directory
705 indicated by the setSorting(), setFilter() and setNameFilter()
706 specifications.
707
708 The the filter and sorting specifications can be overridden using the
709 \e filterSpec and \e sortSpec arguments.
710
711 Returns an empty list if the directory is unreadable or does not exist.
712
713 \sa entryInfoList(), setNameFilter(), setSorting(), setFilter(),
714encodedEntryList()
715*/
716
717QStringList QDir::entryList( int filterSpec, int sortSpec ) const
718{
719 if ( !dirty && filterSpec == (int)DefaultFilter &&
720 sortSpec == (int)DefaultSort )
721return *fList;
722 return entryList( nameFilt, filterSpec, sortSpec );
723}
724
725/*!
726 Returns a list of the names of all files and directories in the directory
727 indicated by the setSorting(), setFilter() and setNameFilter()
728 specifications.
729
730 The the filter and sorting specifications can be overridden using the
731 \e nameFilter, \e filterSpec and \e sortSpec arguments.
732
733 Returns and empty list if the directory is unreadable or does not exist.
734
735 \sa entryInfoList(), setNameFilter(), setSorting(), setFilter(),
736encodedEntryList()
737*/
738
739QStringList QDir::entryList( const QString &nameFilter,
740 int filterSpec, int sortSpec ) const
741{
742 if ( filterSpec == (int)DefaultFilter )
743filterSpec = filtS;
744 if ( sortSpec == (int)DefaultSort )
745sortSpec = sortS;
746 QDir *that = (QDir*)this;// mutable function
747 if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) )
748return *that->fList;
749 else
750return QStringList();
751}
752
753/*!
754 Returns a list of QFileInfo objects for all files and directories in
755 the directory pointed to using the setSorting(), setFilter() and
756 setNameFilter() specifications.
757
758 The the filter and sorting specifications can be overridden using the
759 \e filterSpec and \e sortSpec arguments.
760
761 Returns 0 if the directory is unreadable or does not exist.
762
763 The returned pointer is a const pointer to a QFileInfoList. The list is
764 owned by the QDir object and will be reused on the next call to
765 entryInfoList() for the same QDir instance. If you want to keep the
766 entries of the list after a subsequent call to this function you will
767 need to copy them.
768
769 \sa entryList(), setNameFilter(), setSorting(), setFilter()
770*/
771
772const QFileInfoList *QDir::entryInfoList( int filterSpec, int sortSpec ) const
773{
774 if ( !dirty && filterSpec == (int)DefaultFilter &&
775 sortSpec == (int)DefaultSort )
776return fiList;
777 return entryInfoList( nameFilt, filterSpec, sortSpec );
778}
779
780/*!
781 Returns a list of QFileInfo objects for all files and directories in
782 the directory pointed to using the setSorting(), setFilter() and
783 setNameFilter() specifications.
784
785 The the filter and sorting specifications can be overridden using the
786 \e nameFilter, \e filterSpec and \e sortSpec arguments.
787
788 Returns 0 if the directory is unreadable or does not exist.
789
790 The returned pointer is a const pointer to a QFileInfoList. The list is
791 owned by the QDir object and will be reused on the next call to
792 entryInfoList() for the same QDir instance. If you want to keep the
793 entries of the list after a subsequent call to this function you will
794 need to copy them.
795
796 \sa entryList(), setNameFilter(), setSorting(), setFilter()
797*/
798
799const QFileInfoList *QDir::entryInfoList( const QString &nameFilter,
800 int filterSpec, int sortSpec ) const
801{
802 if ( filterSpec == (int)DefaultFilter )
803filterSpec = filtS;
804 if ( sortSpec == (int)DefaultSort )
805sortSpec = sortS;
806 QDir *that = (QDir*)this;// mutable function
807 if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) )
808return that->fiList;
809 else
810return 0;
811}
812
813/*!
814 Returns TRUE if the directory exists. (If a file with the same
815 name is found this function will of course return FALSE).
816
817 \sa QFileInfo::exists(), QFile::exists()
818*/
819
820bool QDir::exists() const
821{
822 QFileInfo fi( dPath );
823 return fi.exists() && fi.isDir();
824}
825
826/*!
827 Returns TRUE if the directory path is relative to the current directory,
828 FALSE if the path is absolute (e.g. under UNIX a path is relative if it
829 does not start with a '/').
830
831 According to Einstein this function should always return TRUE.
832
833 \sa convertToAbs()
834*/
835
836bool QDir::isRelative() const
837{
838 return isRelativePath( dPath );
839}
840
841/*!
842 Converts the directory path to an absolute path. If it is already
843 absolute nothing is done.
844
845 \sa isRelative()
846*/
847
848void QDir::convertToAbs()
849{
850 dPath = absPath();
851}
852
853/*!
854 Makes a copy of d and assigns it to this QDir.
855*/
856
857QDir &QDir::operator=( const QDir &d )
858{
859 dPath = d.dPath;
860 delete fList;
861 fList = 0;
862 delete fiList;
863 fiList = 0;
864 nameFilt = d.nameFilt;
865 dirty = TRUE;
866 allDirs = d.allDirs;
867 filtS = d.filtS;
868 sortS = d.sortS;
869 return *this;
870}
871
872/*!
873 Sets the directory path to be the given path.
874*/
875
876QDir &QDir::operator=( const QString &path )
877{
878 dPath = cleanDirPath( path );
879 dirty = TRUE;
880 return *this;
881}
882
883
884/*!
885 \fn bool QDir::operator!=( const QDir &d ) const
886 Returns TRUE if the \e d and this dir have different path or
887 different sort/filter settings, otherwise FALSE.
888*/
889
890/*!
891 Returns TRUE if the \e d and this dir have the same path and all sort
892 and filter settings are equal, otherwise FALSE.
893*/
894
895bool QDir::operator==( const QDir &d ) const
896{
897 return dPath == d.dPath &&
898 nameFilt == d.nameFilt &&
899 allDirs == d.allDirs &&
900 filtS == d.filtS &&
901 sortS == d.sortS;
902}
903
904
905/*!
906 Removes a file.
907
908 If \e acceptAbsPath is TRUE a path starting with a separator ('/')
909 will remove the file with the absolute path, if \e acceptAbsPath is FALSE
910 any number of separators at the beginning of \e fileName will be removed.
911
912 Returns TRUE if successful, otherwise FALSE.
913*/
914
915bool QDir::remove( const QString &fileName, bool acceptAbsPath )
916{
917 if ( fileName.isEmpty() ) {
918#if defined(CHECK_NULL)
919qWarning( "QDir::remove: Empty or null file name" );
920#endif
921return FALSE;
922 }
923 QString p = filePath( fileName, acceptAbsPath );
924 return QFile::remove( p );
925}
926
927/*!
928 Checks for existence of a file.
929
930 If \e acceptAbsPaths is TRUE a path starting with a separator ('/')
931 will check the file with the absolute path, if \e acceptAbsPath is FALSE
932 any number of separators at the beginning of \e name will be removed.
933
934 Returns TRUE if the file exists, otherwise FALSE.
935
936 \sa QFileInfo::exists(), QFile::exists()
937*/
938
939bool QDir::exists( const QString &name, bool acceptAbsPath )
940{
941 if ( name.isEmpty() ) {
942#if defined(CHECK_NULL)
943qWarning( "QDir::exists: Empty or null file name" );
944#endif
945return FALSE;
946 }
947 QString tmp = filePath( name, acceptAbsPath );
948 return QFile::exists( tmp );
949}
950
951/*!
952 Returns the native directory separator; '/' under UNIX and '\' under
953 MS-DOS, Windows NT and OS/2.
954
955 You do not need to use this function to build file paths. If you always
956 use '/', Qt will translate your paths to conform to the underlying
957 operating system.
958*/
959
960char QDir::separator()
961{
962#if defined(_OS_UNIX_)
963 return '/';
964#elif defined (_OS_FATFS_)
965 return '\\';
966#elif defined (_OS_MAC_)
967 return ':';
968#else
969 return '/';
970#endif
971}
972
973/*!
974 Returns the current directory.
975 \sa currentDirPath(), QDir::QDir()
976*/
977
978QDir QDir::current()
979{
980 return QDir( currentDirPath() );
981}
982
983/*!
984 Returns the home directory.
985 \sa homeDirPath()
986*/
987
988QDir QDir::home()
989{
990 return QDir( homeDirPath() );
991}
992
993/*!
994 Returns the root directory.
995 \sa rootDirPath() drives()
996*/
997
998QDir QDir::root()
999{
1000 return QDir( rootDirPath() );
1001}
1002
1003/*!
1004 \fn QString QDir::homeDirPath()
1005
1006 Returns the absolute path for the user's home directory,
1007 \sa home()
1008*/
1009
1010QStringList qt_makeFilterList( const QString &filter )
1011{
1012 if ( filter.isEmpty() )
1013return QStringList();
1014
1015 QChar sep( ';' );
1016 int i = filter.find( sep, 0 );
1017 if ( i == -1 && filter.find( ' ', 0 ) != -1 )
1018sep = QChar( ' ' );
1019
1020 QStringList lst = QStringList::split( sep, filter );
1021 QStringList lst2;
1022 QStringList::Iterator it = lst.begin();
1023
1024 for ( ; it != lst.end(); ++it ) {
1025QString s = *it;
1026lst2 << s.stripWhiteSpace();
1027 }
1028 return lst2;
1029}
1030
1031/*!
1032 Returns TRUE if the \e fileName matches one of the wildcards in the list \e filters.
1033 \sa QRegExp
1034*/
1035
1036bool QDir::match( const QStringList &filters, const QString &fileName )
1037{
1038 QStringList::ConstIterator sit = filters.begin();
1039 bool matched = FALSE;
1040 for ( ; sit != filters.end(); ++sit ) {
1041QRegExp regexp( (*sit).data(), FALSE, TRUE );
1042if ( regexp.match( fileName.data() ) != -1 ) {
1043 matched = TRUE;
1044 break;
1045}
1046 }
1047
1048 return matched;
1049}
1050
1051/*!
1052 Returns TRUE if the \e fileName matches the wildcard \e filter.
1053 \a Filter may also contain multiple wildcards separated by spaces or
1054 semicolons.
1055 \sa QRegExp
1056*/
1057
1058bool QDir::match( const QString &filter, const QString &fileName )
1059{
1060 QStringList lst = qt_makeFilterList( filter );
1061 return match( lst, fileName );
1062}
1063
1064
1065/*!
1066 Removes all multiple directory separators ('/') and resolves
1067 any "." or ".." found in the path.
1068
1069 Symbolic links are kept. This function does not return the
1070 canonical path, but rather the most simplified version of the input.
1071 "../stuff" becomes "stuff", "stuff/../nonsense" becomes "nonsense"
1072 and "\\stuff\\more\\..\\nonsense" becomes "\\stuff\\nonsense".
1073
1074 \sa absPath() canonicalPath()
1075*/
1076
1077QString QDir::cleanDirPath( const QString &filePath )
1078{
1079 QString name = filePath;
1080 QString newPath;
1081
1082 if ( name.isEmpty() )
1083return name;
1084
1085 slashify( name );
1086
1087 bool addedSeparator;
1088 if ( isRelativePath(name) ) {
1089addedSeparator = TRUE;
1090name.insert( 0, '/' );
1091 } else {
1092addedSeparator = FALSE;
1093 }
1094
1095 int ePos, pos, upLevel;
1096
1097 pos = ePos = name.length();
1098 upLevel = 0;
1099 int len;
1100
1101 while ( pos && (pos = name.findRev('/',--pos)) != -1 ) {
1102len = ePos - pos - 1;
1103if ( len == 2 && name.at(pos + 1) == '.'
1104 && name.at(pos + 2) == '.' ) {
1105 upLevel++;
1106} else {
1107 if ( len != 0 && (len != 1 || name.at(pos + 1) != '.') ) {
1108if ( !upLevel )
1109 newPath = QString::fromLatin1("/")
1110+ name.mid(pos + 1, len) + newPath;
1111else
1112 upLevel--;
1113 }
1114}
1115ePos = pos;
1116 }
1117 if ( addedSeparator ) {
1118while ( upLevel-- )
1119 newPath.insert( 0, QString::fromLatin1("/..") );
1120if ( !newPath.isEmpty() )
1121 newPath.remove( 0, 1 );
1122else
1123 newPath = QString::fromLatin1(".");
1124 } else {
1125if ( newPath.isEmpty() )
1126 newPath = QString::fromLatin1("/");
1127#if defined(_OS_FATFS_) || defined(_OS_OS2EMX_)
1128if ( name[0] == '/' ) {
1129 if ( name[1] == '/' )// "\\machine\x\ ..."
1130newPath.insert( 0, '/' );
1131} else {
1132 newPath = name.left(2) + newPath;
1133}
1134#endif
1135 }
1136 return newPath;
1137}
1138
1139int qt_cmp_si_sortSpec;
1140
1141#if defined(Q_C_CALLBACKS)
1142extern "C" {
1143#endif
1144
1145int qt_cmp_si( const void *n1, const void *n2 )
1146{
1147 if ( !n1 || !n2 )
1148return 0;
1149
1150 QDirSortItem* f1 = (QDirSortItem*)n1;
1151 QDirSortItem* f2 = (QDirSortItem*)n2;
1152
1153 if ( qt_cmp_si_sortSpec & QDir::DirsFirst )
1154if ( f1->item->isDir() != f2->item->isDir() )
1155 return f1->item->isDir() ? -1 : 1;
1156
1157 int r = 0;
1158 int sortBy = qt_cmp_si_sortSpec & QDir::SortByMask;
1159
1160 switch ( sortBy ) {
1161 case QDir::Time:
1162r = f1->item->lastModified().secsTo(f2->item->lastModified());
1163break;
1164 case QDir::Size:
1165r = f2->item->size() - f1->item->size();
1166break;
1167 default:
1168;
1169 }
1170
1171 if ( r == 0 && sortBy != QDir::Unsorted ) {
1172// Still not sorted - sort by name
1173bool ic = qt_cmp_si_sortSpec & QDir::IgnoreCase;
1174
1175if ( f1->filename_cache.isNull() )
1176 f1->filename_cache = ic ? f1->item->fileName().lower()
1177 : f1->item->fileName();
1178if ( f2->filename_cache.isNull() )
1179 f2->filename_cache = ic ? f2->item->fileName().lower()
1180 : f2->item->fileName();
1181
1182r = f1->filename_cache.compare(f2->filename_cache);
1183 }
1184
1185 if ( r == 0 ) {
1186// Enforce an order - the order the items appear in the array
1187r = (char*)n1 - (char*)n2;
1188 }
1189
1190 if ( qt_cmp_si_sortSpec & QDir::Reversed )
1191return -r;
1192 else
1193return r;
1194}
1195
1196#if defined(Q_C_CALLBACKS)
1197}
1198#endif
1199
1200#endif // QT_NO_DIR
1201

Archive Download this file

Revision: 1322