-rw-r--r-- | qmake/tools/qdir.cpp | 1294 |
1 files changed, 1294 insertions, 0 deletions
diff --git a/qmake/tools/qdir.cpp b/qmake/tools/qdir.cpp new file mode 100644 index 0000000..418ea49 --- a/dev/null +++ b/qmake/tools/qdir.cpp | |||
@@ -0,0 +1,1294 @@ | |||
1 | /**************************************************************************** | ||
2 | ** $Id$ | ||
3 | ** | ||
4 | ** Implementation of QDir class | ||
5 | ** | ||
6 | ** Created : 950427 | ||
7 | ** | ||
8 | ** Copyright (C) 1992-2002 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 "qplatformdefs.h" | ||
39 | #include "qdir.h" | ||
40 | |||
41 | #ifndef QT_NO_DIR | ||
42 | #include <private/qdir_p.h> | ||
43 | #include "qfileinfo.h" | ||
44 | #include "qregexp.h" | ||
45 | #include "qstringlist.h" | ||
46 | #include <stdlib.h> | ||
47 | #include <ctype.h> | ||
48 | |||
49 | |||
50 | |||
51 | /*! | ||
52 | \class QDir | ||
53 | \brief The QDir class provides access to directory structures and their contents in a platform-independent way. | ||
54 | |||
55 | \ingroup io | ||
56 | \mainclass | ||
57 | |||
58 | A QDir is used to manipulate path names, access information | ||
59 | regarding paths and files, and manipulate the underlying file | ||
60 | system. | ||
61 | |||
62 | A QDir can point to a file using either a relative or an absolute | ||
63 | path. Absolute paths begin with the directory separator "/" | ||
64 | (optionally preceded by a drive specification under Windows). If | ||
65 | you always use "/" as a directory separator, Qt will translate | ||
66 | your paths to conform to the underlying operating system. Relative | ||
67 | file names begin with a directory name or a file name and specify | ||
68 | a path relative to the current directory. | ||
69 | |||
70 | The "current" path refers to the application's working directory. | ||
71 | A QDir's own path is set and retrieved with setPath() and path(). | ||
72 | |||
73 | An example of an absolute path is the string "/tmp/quartz", a | ||
74 | relative path might look like "src/fatlib". You can use the | ||
75 | function isRelative() to check if a QDir is using a relative or an | ||
76 | absolute file path. Call convertToAbs() to convert a relative QDir | ||
77 | to an absolute one. For a simplified path use cleanDirPath(). To | ||
78 | obtain a path which has no symbolic links or redundant ".." | ||
79 | elements use canonicalPath(). The path can be set with setPath(), | ||
80 | and changed with cd() and cdUp(). | ||
81 | |||
82 | QDir provides several static functions, for example, setCurrent() | ||
83 | to set the application's working directory and currentDirPath() to | ||
84 | retrieve the application's working directory. Access to some | ||
85 | common paths is provided with the static functions, current(), | ||
86 | home() and root() which return QDir objects or currentDirPath(), | ||
87 | homeDirPath() and rootDirPath() which return the path as a string. | ||
88 | |||
89 | The number of entries in a directory is returned by count(). | ||
90 | Obtain a string list of the names of all the files and directories | ||
91 | in a directory with entryList(). If you prefer a list of QFileInfo | ||
92 | pointers use entryInfoList(). Both these functions can apply a | ||
93 | name filter, an attributes filter (e.g. read-only, files not | ||
94 | directories, etc.), and a sort order. The filters and sort may be | ||
95 | set with calls to setNameFilter(), setFilter() and setSorting(). | ||
96 | They may also be specified in the entryList() and | ||
97 | entryInfoList()'s arguments. | ||
98 | |||
99 | Create a new directory with mkdir(), rename a directory with | ||
100 | rename() and remove an existing directory with rmdir(). Remove a | ||
101 | file with remove(). You can interrogate a directory with exists(), | ||
102 | isReadable() and isRoot(). | ||
103 | |||
104 | To get a path with a filename use filePath(), and to get a | ||
105 | directory name use dirName(); neither of these functions checks | ||
106 | for the existence of the file or directory. | ||
107 | |||
108 | The list of root directories is provided by drives(); on Unix | ||
109 | systems this returns a list containing one root directory, "/"; on | ||
110 | Windows the list will usually contain "C:/", and possibly "D:/", | ||
111 | etc. | ||
112 | |||
113 | If you need the path in a form suitable for the underlying | ||
114 | operating system use convertSeparators(). | ||
115 | |||
116 | Examples: | ||
117 | |||
118 | See if a directory exists. | ||
119 | \code | ||
120 | QDir d( "example" ); // "./example" | ||
121 | if ( !d.exists() ) | ||
122 | qWarning( "Cannot find the example directory" ); | ||
123 | \endcode | ||
124 | |||
125 | Traversing directories and reading a file. | ||
126 | \code | ||
127 | QDir d = QDir::root(); // "/" | ||
128 | if ( !d.cd("tmp") ) { // "/tmp" | ||
129 | qWarning( "Cannot find the \"/tmp\" directory" ); | ||
130 | } else { | ||
131 | QFile f( d.filePath("ex1.txt") );// "/tmp/ex1.txt" | ||
132 | if ( !f.open(IO_ReadWrite) ) | ||
133 | qWarning( "Cannot create the file %s", f.name() ); | ||
134 | } | ||
135 | \endcode | ||
136 | |||
137 | A program that lists all the files in the current directory | ||
138 | (excluding symbolic links), sorted by size, smallest first: | ||
139 | \code | ||
140 | #include <stdio.h> | ||
141 | #include <qdir.h> | ||
142 | |||
143 | int main( int argc, char **argv ) | ||
144 | { | ||
145 | QDir d; | ||
146 | d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks ); | ||
147 | d.setSorting( QDir::Size | QDir::Reversed ); | ||
148 | |||
149 | const QFileInfoList *list = d.entryInfoList(); | ||
150 | QFileInfoListIterator it( *list ); | ||
151 | QFileInfo *fi; | ||
152 | |||
153 | printf( " Bytes Filename\n" ); | ||
154 | while ( (fi = it.current()) != 0 ) { | ||
155 | printf( "%10li %s\n", fi->size(), fi->fileName().latin1() ); | ||
156 | ++it; | ||
157 | } | ||
158 | return 0; | ||
159 | } | ||
160 | \endcode | ||
161 | */ | ||
162 | |||
163 | /*! | ||
164 | Constructs a QDir pointing to the current directory. | ||
165 | |||
166 | \sa currentDirPath() | ||
167 | */ | ||
168 | |||
169 | QDir::QDir() | ||
170 | { | ||
171 | dPath = QString::fromLatin1("."); | ||
172 | init(); | ||
173 | } | ||
174 | |||
175 | /*! | ||
176 | Constructs a QDir with path \a path, that filters its entries by | ||
177 | name using \a nameFilter and by attributes using \a filterSpec. It | ||
178 | also sorts the names using \a sortSpec. | ||
179 | |||
180 | The default \a nameFilter is an empty string, which excludes | ||
181 | nothing; the default \a filterSpec is \c All, which also means | ||
182 | exclude nothing. The default \a sortSpec is \c Name|IgnoreCase, | ||
183 | i.e. sort by name case-insensitively. | ||
184 | |||
185 | Example that lists all the files in "/tmp": | ||
186 | \code | ||
187 | QDir d( "/tmp" ); | ||
188 | for ( int i = 0; i < d.count(); i++ ) | ||
189 | printf( "%s\n", d[i] ); | ||
190 | \endcode | ||
191 | |||
192 | If \a path is "" or QString::null, QDir uses "." (the current | ||
193 | directory). If \a nameFilter is "" or QString::null, QDir uses the | ||
194 | name filter "*" (all files). | ||
195 | |||
196 | Note that \a path need not exist. | ||
197 | |||
198 | \sa exists(), setPath(), setNameFilter(), setFilter(), setSorting() | ||
199 | */ | ||
200 | |||
201 | QDir::QDir( const QString &path, const QString &nameFilter, | ||
202 | int sortSpec, int filterSpec ) | ||
203 | { | ||
204 | init(); | ||
205 | dPath = cleanDirPath( path ); | ||
206 | if ( dPath.isEmpty() ) | ||
207 | dPath = QString::fromLatin1("."); | ||
208 | nameFilt = nameFilter; | ||
209 | if ( nameFilt.isEmpty() ) | ||
210 | nameFilt = QString::fromLatin1("*"); | ||
211 | filtS = (FilterSpec)filterSpec; | ||
212 | sortS = (SortSpec)sortSpec; | ||
213 | } | ||
214 | |||
215 | /*! | ||
216 | Constructs a QDir that is a copy of the directory \a d. | ||
217 | |||
218 | \sa operator=() | ||
219 | */ | ||
220 | |||
221 | QDir::QDir( const QDir &d ) | ||
222 | { | ||
223 | dPath = d.dPath; | ||
224 | fList = 0; | ||
225 | fiList = 0; | ||
226 | nameFilt = d.nameFilt; | ||
227 | dirty = TRUE; | ||
228 | allDirs = d.allDirs; | ||
229 | filtS = d.filtS; | ||
230 | sortS = d.sortS; | ||
231 | } | ||
232 | |||
233 | |||
234 | void QDir::init() | ||
235 | { | ||
236 | fList = 0; | ||
237 | fiList = 0; | ||
238 | nameFilt = QString::fromLatin1("*"); | ||
239 | dirty = TRUE; | ||
240 | allDirs = FALSE; | ||
241 | filtS = All; | ||
242 | sortS = SortSpec(Name | IgnoreCase); | ||
243 | } | ||
244 | |||
245 | /*! | ||
246 | Destroys the QDir frees up its resources. | ||
247 | */ | ||
248 | |||
249 | QDir::~QDir() | ||
250 | { | ||
251 | delete fList; | ||
252 | delete fiList; | ||
253 | } | ||
254 | |||
255 | |||
256 | /*! | ||
257 | Sets the path of the directory to \a path. The path is cleaned of | ||
258 | redundant ".", ".." and of multiple separators. No check is made | ||
259 | to ensure that a directory with this path exists. | ||
260 | |||
261 | The path can be either absolute or relative. Absolute paths begin | ||
262 | with the directory separator "/" (optionally preceded by a drive | ||
263 | specification under Windows). Relative file names begin with a | ||
264 | directory name or a file name and specify a path relative to the | ||
265 | current directory. An example of an absolute path is the string | ||
266 | "/tmp/quartz", a relative path might look like "src/fatlib". | ||
267 | |||
268 | \sa path(), absPath(), exists(), cleanDirPath(), dirName(), | ||
269 | absFilePath(), isRelative(), convertToAbs() | ||
270 | */ | ||
271 | |||
272 | void QDir::setPath( const QString &path ) | ||
273 | { | ||
274 | dPath = cleanDirPath( path ); | ||
275 | if ( dPath.isEmpty() ) | ||
276 | dPath = QString::fromLatin1("."); | ||
277 | dirty = TRUE; | ||
278 | } | ||
279 | |||
280 | /*! | ||
281 | \fn QString QDir::path() const | ||
282 | |||
283 | Returns the path, this may contain symbolic links, but never | ||
284 | contains redundant ".", ".." or multiple separators. | ||
285 | |||
286 | The returned path can be either absolute or relative (see | ||
287 | setPath()). | ||
288 | |||
289 | \sa setPath(), absPath(), exists(), cleanDirPath(), dirName(), | ||
290 | absFilePath(), convertSeparators() | ||
291 | */ | ||
292 | |||
293 | /*! | ||
294 | Returns the absolute path (a path that starts with "/" or with a | ||
295 | drive specification), which may contain symbolic links, but never | ||
296 | contains redundant ".", ".." or multiple separators. | ||
297 | |||
298 | \sa setPath(), canonicalPath(), exists(), cleanDirPath(), | ||
299 | dirName(), absFilePath() | ||
300 | */ | ||
301 | |||
302 | QString QDir::absPath() const | ||
303 | { | ||
304 | if ( QDir::isRelativePath(dPath) ) { | ||
305 | QString tmp = currentDirPath(); | ||
306 | if ( tmp.right(1) != QString::fromLatin1("/") ) | ||
307 | tmp += '/'; | ||
308 | tmp += dPath; | ||
309 | return cleanDirPath( tmp ); | ||
310 | } else { | ||
311 | return cleanDirPath( dPath ); | ||
312 | } | ||
313 | } | ||
314 | |||
315 | /*! | ||
316 | Returns the name of the directory; this is \e not the same as the | ||
317 | path, e.g. a directory with the name "mail", might have the path | ||
318 | "/var/spool/mail". If the directory has no name (e.g. it is the | ||
319 | root directory) QString::null is returned. | ||
320 | |||
321 | No check is made to ensure that a directory with this name | ||
322 | actually exists. | ||
323 | |||
324 | \sa path(), absPath(), absFilePath(), exists(), QString::isNull() | ||
325 | */ | ||
326 | |||
327 | QString QDir::dirName() const | ||
328 | { | ||
329 | int pos = dPath.findRev( '/' ); | ||
330 | if ( pos == -1 ) | ||
331 | return dPath; | ||
332 | return dPath.right( dPath.length() - pos - 1 ); | ||
333 | } | ||
334 | |||
335 | /*! | ||
336 | Returns the path name of a file in the directory. Does \e not | ||
337 | check if the file actually exists in the directory. If the QDir is | ||
338 | relative the returned path name will also be relative. Redundant | ||
339 | multiple separators or "." and ".." directories in \a fileName | ||
340 | will not be removed (see cleanDirPath()). | ||
341 | |||
342 | If \a acceptAbsPath is TRUE a \a fileName starting with a | ||
343 | separator "/" will be returned without change. If \a acceptAbsPath | ||
344 | is FALSE an absolute path will be prepended to the fileName and | ||
345 | the resultant string returned. | ||
346 | |||
347 | \sa absFilePath(), isRelative(), canonicalPath() | ||
348 | */ | ||
349 | |||
350 | QString QDir::filePath( const QString &fileName, | ||
351 | bool acceptAbsPath ) const | ||
352 | { | ||
353 | if ( acceptAbsPath && !isRelativePath(fileName) ) | ||
354 | return QString(fileName); | ||
355 | |||
356 | QString tmp = dPath; | ||
357 | if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName && | ||
358 | fileName[0] != '/') ) | ||
359 | tmp += '/'; | ||
360 | tmp += fileName; | ||
361 | return tmp; | ||
362 | } | ||
363 | |||
364 | /*! | ||
365 | Returns the absolute path name of a file in the directory. Does \e | ||
366 | not check if the file actually exists in the directory. Redundant | ||
367 | multiple separators or "." and ".." directories in \a fileName | ||
368 | will not be removed (see cleanDirPath()). | ||
369 | |||
370 | If \a acceptAbsPath is TRUE a \a fileName starting with a | ||
371 | separator "/" will be returned without change. If \a acceptAbsPath | ||
372 | is FALSE an absolute path will be prepended to the fileName and | ||
373 | the resultant string returned. | ||
374 | |||
375 | \sa filePath() | ||
376 | */ | ||
377 | |||
378 | QString QDir::absFilePath( const QString &fileName, | ||
379 | bool acceptAbsPath ) const | ||
380 | { | ||
381 | if ( acceptAbsPath && !isRelativePath( fileName ) ) | ||
382 | return fileName; | ||
383 | |||
384 | QString tmp = absPath(); | ||
385 | if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName && | ||
386 | fileName[0] != '/') ) | ||
387 | tmp += '/'; | ||
388 | tmp += fileName; | ||
389 | return tmp; | ||
390 | } | ||
391 | |||
392 | |||
393 | /*! | ||
394 | Returns \a pathName with the '/' separators converted to | ||
395 | separators that are appropriate for the underlying operating | ||
396 | system. | ||
397 | |||
398 | On Windows, convertSeparators("c:/winnt/system32") returns | ||
399 | "c:\winnt\system32". | ||
400 | |||
401 | The returned string may be the same as the argument on some | ||
402 | operating systems, for example on Unix. | ||
403 | */ | ||
404 | |||
405 | QString QDir::convertSeparators( const QString &pathName ) | ||
406 | { | ||
407 | QString n( pathName ); | ||
408 | #if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX) | ||
409 | for ( int i=0; i<(int)n.length(); i++ ) { | ||
410 | if ( n[i] == '/' ) | ||
411 | n[i] = '\\'; | ||
412 | } | ||
413 | #elif defined(Q_OS_MAC9) | ||
414 | while(n.length() && n[0] == '/' ) n = n.right(n.length()-1); | ||
415 | for ( int i=0; i<(int)n.length(); i++ ) { | ||
416 | if ( n[i] == '/' ) | ||
417 | n[i] = ':'; | ||
418 | } | ||
419 | if(n.contains(':') && n.left(1) != ':') | ||
420 | n.prepend(':'); | ||
421 | #endif | ||
422 | return n; | ||
423 | } | ||
424 | |||
425 | |||
426 | /*! | ||
427 | Changes the QDir's directory to \a dirName. | ||
428 | |||
429 | If \a acceptAbsPath is TRUE a path starting with separator "/" | ||
430 | will cause the function to change to the absolute directory. If \a | ||
431 | acceptAbsPath is FALSE any number of separators at the beginning | ||
432 | of \a dirName will be removed and the function will descend into | ||
433 | \a dirName. | ||
434 | |||
435 | Returns TRUE if the new directory exists and is readable; | ||
436 | otherwise returns FALSE. Note that the logical cd() operation is | ||
437 | not performed if the new directory does not exist. | ||
438 | |||
439 | Calling cd( ".." ) is equivalent to calling cdUp(). | ||
440 | |||
441 | \sa cdUp(), isReadable(), exists(), path() | ||
442 | */ | ||
443 | |||
444 | bool QDir::cd( const QString &dirName, bool acceptAbsPath ) | ||
445 | { | ||
446 | if ( dirName.isEmpty() || dirName==QString::fromLatin1(".") ) | ||
447 | return TRUE; | ||
448 | QString old = dPath; | ||
449 | if ( acceptAbsPath && !isRelativePath(dirName) ) { | ||
450 | dPath = cleanDirPath( dirName ); | ||
451 | } else { | ||
452 | if ( !isRoot() ) { | ||
453 | dPath += '/'; | ||
454 | } else if ( dirName == ".." ) { | ||
455 | dPath = old; | ||
456 | return FALSE; | ||
457 | } | ||
458 | dPath += dirName; | ||
459 | if ( dirName.find('/') >= 0 | ||
460 | || old == QString::fromLatin1(".") | ||
461 | || dirName == QString::fromLatin1("..") ) | ||
462 | dPath = cleanDirPath( dPath ); | ||
463 | } | ||
464 | if ( !exists() ) { | ||
465 | dPath = old; // regret | ||
466 | return FALSE; | ||
467 | } | ||
468 | dirty = TRUE; | ||
469 | return TRUE; | ||
470 | } | ||
471 | |||
472 | /*! | ||
473 | Changes directory by moving one directory up from the QDir's | ||
474 | current directory. | ||
475 | |||
476 | Returns TRUE if the new directory exists and is readable; | ||
477 | otherwise returns FALSE. Note that the logical cdUp() operation is | ||
478 | not performed if the new directory does not exist. | ||
479 | |||
480 | \sa cd(), isReadable(), exists(), path() | ||
481 | */ | ||
482 | |||
483 | bool QDir::cdUp() | ||
484 | { | ||
485 | return cd( QString::fromLatin1("..") ); | ||
486 | } | ||
487 | |||
488 | /*! | ||
489 | \fn QString QDir::nameFilter() const | ||
490 | |||
491 | Returns the string set by setNameFilter() | ||
492 | */ | ||
493 | |||
494 | /*! | ||
495 | Sets the name filter used by entryList() and entryInfoList() to \a | ||
496 | nameFilter. | ||
497 | |||
498 | The \a nameFilter is a wildcard (globbing) filter that understands | ||
499 | "*" and "?" wildcards. (See \link qregexp.html#wildcard-matching | ||
500 | QRegExp wildcard matching\endlink.) You may specify several filter | ||
501 | entries all separated by a single space " " or by a semi-colon | ||
502 | ";". | ||
503 | |||
504 | For example, if you want entryList() and entryInfoList() to list | ||
505 | all files ending with either ".cpp" or ".h", you would use either | ||
506 | dir.setNameFilter("*.cpp *.h") or dir.setNameFilter("*.cpp;*.h"). | ||
507 | |||
508 | \sa nameFilter(), setFilter() | ||
509 | */ | ||
510 | |||
511 | void QDir::setNameFilter( const QString &nameFilter ) | ||
512 | { | ||
513 | nameFilt = nameFilter; | ||
514 | if ( nameFilt.isEmpty() ) | ||
515 | nameFilt = QString::fromLatin1("*"); | ||
516 | dirty = TRUE; | ||
517 | } | ||
518 | |||
519 | /*! | ||
520 | \fn QDir::FilterSpec QDir::filter() const | ||
521 | |||
522 | Returns the value set by setFilter() | ||
523 | */ | ||
524 | |||
525 | /*! | ||
526 | \enum QDir::FilterSpec | ||
527 | |||
528 | This enum describes the filtering options available to QDir, e.g. | ||
529 | for entryList() and entryInfoList(). The filter value is specified | ||
530 | by OR-ing together values from the following list: | ||
531 | |||
532 | \value Dirs List directories only. | ||
533 | \value Files List files only. | ||
534 | \value Drives List disk drives (ignored under Unix). | ||
535 | \value NoSymLinks Do not list symbolic links (ignored by operating | ||
536 | systems that don't support symbolic links). | ||
537 | \value All List directories, files, drives and symlinks (this does not list | ||
538 | broken symlinks unless you specify System). | ||
539 | \value TypeMask A mask for the the Dirs, Files, Drives and | ||
540 | NoSymLinks flags. | ||
541 | \value Readable List files for which the application has read access. | ||
542 | \value Writable List files for which the application has write access. | ||
543 | \value Executable List files for which the application has execute | ||
544 | access. Executables needs to be combined with Dirs or Files. | ||
545 | \value RWEMask A mask for the Readable, Writable and Executable flags. | ||
546 | \value Modified Only list files that have been modified (ignored | ||
547 | under Unix). | ||
548 | \value Hidden List hidden files (on Unix, files starting with a .). | ||
549 | \value System List system files (on Unix, FIFOs, sockets and | ||
550 | device files) | ||
551 | \value AccessMask A mask for the Readable, Writable, Executable | ||
552 | Modified, Hidden and System flags | ||
553 | \value DefaultFilter Internal flag. | ||
554 | |||
555 | If you do not set any of \c Readable, \c Writable or \c | ||
556 | Executable, QDir will set all three of them. This makes the | ||
557 | default easy to write and at the same time useful. | ||
558 | |||
559 | Examples: \c Readable|Writable means list all files for which the | ||
560 | application has read access, write access or both. \c Dirs|Drives | ||
561 | means list drives, directories, all files that the application can | ||
562 | read, write or execute, and also symlinks to such | ||
563 | files/directories. | ||
564 | */ | ||
565 | |||
566 | |||
567 | /*! | ||
568 | Sets the filter used by entryList() and entryInfoList() to \a | ||
569 | filterSpec. The filter is used to specify the kind of files that | ||
570 | should be returned by entryList() and entryInfoList(). See | ||
571 | \l{QDir::FilterSpec}. | ||
572 | |||
573 | \sa filter(), setNameFilter() | ||
574 | */ | ||
575 | |||
576 | void QDir::setFilter( int filterSpec ) | ||
577 | { | ||
578 | if ( filtS == (FilterSpec) filterSpec ) | ||
579 | return; | ||
580 | filtS = (FilterSpec) filterSpec; | ||
581 | dirty = TRUE; | ||
582 | } | ||
583 | |||
584 | /*! | ||
585 | \fn QDir::SortSpec QDir::sorting() const | ||
586 | |||
587 | Returns the value set by setSorting() | ||
588 | |||
589 | \sa setSorting() SortSpec | ||
590 | */ | ||
591 | |||
592 | /*! | ||
593 | \enum QDir::SortSpec | ||
594 | |||
595 | This enum describes the sort options available to QDir, e.g. for | ||
596 | entryList() and entryInfoList(). The sort value is specified by | ||
597 | OR-ing together values from the following list: | ||
598 | |||
599 | \value Name Sort by name. | ||
600 | \value Time Sort by time (modification time). | ||
601 | \value Size Sort by file size. | ||
602 | \value Unsorted Do not sort. | ||
603 | \value SortByMask A mask for Name, Time and Size. | ||
604 | |||
605 | \value DirsFirst Put the directories first, then the files. | ||
606 | \value Reversed Reverse the sort order. | ||
607 | \value IgnoreCase Sort case-insensitively. | ||
608 | \value DefaultSort Internal flag. | ||
609 | |||
610 | You can only specify one of the first four. | ||
611 | |||
612 | If you specify both \c DirsFirst and \c Reversed, directories are | ||
613 | still put first, but in reverse order; the files will be listed | ||
614 | after the directories, again in reverse order. | ||
615 | */ | ||
616 | |||
617 | // ### Unsorted+DirsFirst ? Unsorted+Reversed? | ||
618 | |||
619 | /*! | ||
620 | Sets the sort order used by entryList() and entryInfoList(). | ||
621 | |||
622 | The \a sortSpec is specified by OR-ing values from the enum | ||
623 | \l{QDir::SortSpec}. | ||
624 | |||
625 | \sa sorting() SortSpec | ||
626 | */ | ||
627 | |||
628 | void QDir::setSorting( int sortSpec ) | ||
629 | { | ||
630 | if ( sortS == (SortSpec) sortSpec ) | ||
631 | return; | ||
632 | sortS = (SortSpec) sortSpec; | ||
633 | dirty = TRUE; | ||
634 | } | ||
635 | |||
636 | /*! | ||
637 | \fn bool QDir::matchAllDirs() const | ||
638 | |||
639 | Returns the value set by setMatchAllDirs() | ||
640 | |||
641 | \sa setMatchAllDirs() | ||
642 | */ | ||
643 | |||
644 | /*! | ||
645 | If \a enable is TRUE then all directories are included (e.g. in | ||
646 | entryList()), and the nameFilter() is only applied to the files. | ||
647 | If \a enable is FALSE then the nameFilter() is applied to both | ||
648 | directories and files. | ||
649 | |||
650 | \sa matchAllDirs() | ||
651 | */ | ||
652 | |||
653 | void QDir::setMatchAllDirs( bool enable ) | ||
654 | { | ||
655 | if ( (bool)allDirs == enable ) | ||
656 | return; | ||
657 | allDirs = enable; | ||
658 | dirty = TRUE; | ||
659 | } | ||
660 | |||
661 | |||
662 | /*! | ||
663 | Returns the total number of directories and files that were found. | ||
664 | |||
665 | Equivalent to entryList().count(). | ||
666 | |||
667 | \sa operator[](), entryList() | ||
668 | */ | ||
669 | |||
670 | uint QDir::count() const | ||
671 | { | ||
672 | return (uint)entryList().count(); | ||
673 | } | ||
674 | |||
675 | /*! | ||
676 | Returns the file name at position \a index in the list of file | ||
677 | names. Equivalent to entryList().at(index). | ||
678 | |||
679 | Returns a QString::null if the \a index is out of range or if the | ||
680 | entryList() function failed. | ||
681 | |||
682 | \sa count(), entryList() | ||
683 | */ | ||
684 | |||
685 | QString QDir::operator[]( int index ) const | ||
686 | { | ||
687 | entryList(); | ||
688 | return fList && index >= 0 && index < (int)fList->count() ? | ||
689 | (*fList)[index] : QString::null; | ||
690 | } | ||
691 | |||
692 | |||
693 | /*! | ||
694 | \obsolete | ||
695 | This function is included to easy porting from Qt 1.x to Qt 2.0, | ||
696 | it is the same as entryList(), but encodes the filenames as 8-bit | ||
697 | strings using QFile::encodedName(). | ||
698 | |||
699 | It is more efficient to use entryList(). | ||
700 | */ | ||
701 | QStrList QDir::encodedEntryList( int filterSpec, int sortSpec ) const | ||
702 | { | ||
703 | QStrList r; | ||
704 | QStringList l = entryList(filterSpec,sortSpec); | ||
705 | for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) { | ||
706 | r.append( QFile::encodeName(*it) ); | ||
707 | } | ||
708 | return r; | ||
709 | } | ||
710 | |||
711 | /*! | ||
712 | \obsolete | ||
713 | \overload | ||
714 | This function is included to easy porting from Qt 1.x to Qt 2.0, | ||
715 | it is the same as entryList(), but encodes the filenames as 8-bit | ||
716 | strings using QFile::encodedName(). | ||
717 | |||
718 | It is more efficient to use entryList(). | ||
719 | */ | ||
720 | QStrList QDir::encodedEntryList( const QString &nameFilter, | ||
721 | int filterSpec, | ||
722 | int sortSpec ) const | ||
723 | { | ||
724 | QStrList r; | ||
725 | QStringList l = entryList(nameFilter,filterSpec,sortSpec); | ||
726 | for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) { | ||
727 | r.append( QFile::encodeName(*it) ); | ||
728 | } | ||
729 | return r; | ||
730 | } | ||
731 | |||
732 | |||
733 | |||
734 | /*! | ||
735 | \overload | ||
736 | |||
737 | Returns a list of the names of all the files and directories in | ||
738 | the directory, ordered in accordance with setSorting() and | ||
739 | filtered in accordance with setFilter() and setNameFilter(). | ||
740 | |||
741 | The filter and sorting specifications can be overridden using the | ||
742 | \a filterSpec and \a sortSpec arguments. | ||
743 | |||
744 | Returns an empty list if the directory is unreadable or does not | ||
745 | exist. | ||
746 | |||
747 | \sa entryInfoList(), setNameFilter(), setSorting(), setFilter() | ||
748 | */ | ||
749 | |||
750 | QStringList QDir::entryList( int filterSpec, int sortSpec ) const | ||
751 | { | ||
752 | if ( !dirty && filterSpec == (int)DefaultFilter && | ||
753 | sortSpec == (int)DefaultSort ) | ||
754 | return *fList; | ||
755 | return entryList( nameFilt, filterSpec, sortSpec ); | ||
756 | } | ||
757 | |||
758 | /*! | ||
759 | Returns a list of the names of all the files and directories in | ||
760 | the directory, ordered in accordance with setSorting() and | ||
761 | filtered in accordance with setFilter() and setNameFilter(). | ||
762 | |||
763 | The filter and sorting specifications can be overridden using the | ||
764 | \a nameFilter, \a filterSpec and \a sortSpec arguments. | ||
765 | |||
766 | Returns an empty list if the directory is unreadable or does not | ||
767 | exist. | ||
768 | |||
769 | \sa entryInfoList(), setNameFilter(), setSorting(), setFilter() | ||
770 | */ | ||
771 | |||
772 | QStringList QDir::entryList( const QString &nameFilter, | ||
773 | int filterSpec, int sortSpec ) const | ||
774 | { | ||
775 | if ( filterSpec == (int)DefaultFilter ) | ||
776 | filterSpec = filtS; | ||
777 | if ( sortSpec == (int)DefaultSort ) | ||
778 | sortSpec = sortS; | ||
779 | QDir *that = (QDir*)this; // mutable function | ||
780 | if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) ) { | ||
781 | if ( that->fList ) | ||
782 | return *that->fList; | ||
783 | } | ||
784 | return QStringList(); | ||
785 | } | ||
786 | |||
787 | /*! | ||
788 | \overload | ||
789 | |||
790 | Returns a list of QFileInfo objects for all the files and | ||
791 | directories in the directory, ordered in accordance with | ||
792 | setSorting() and filtered in accordance with setFilter() and | ||
793 | setNameFilter(). | ||
794 | |||
795 | The filter and sorting specifications can be overridden using the | ||
796 | \a filterSpec and \a sortSpec arguments. | ||
797 | |||
798 | Returns 0 if the directory is unreadable or does not exist. | ||
799 | |||
800 | The returned pointer is a const pointer to a QFileInfoList. The | ||
801 | list is owned by the QDir object and will be reused on the next | ||
802 | call to entryInfoList() for the same QDir instance. If you want to | ||
803 | keep the entries of the list after a subsequent call to this | ||
804 | function you must copy them. | ||
805 | |||
806 | \sa entryList(), setNameFilter(), setSorting(), setFilter() | ||
807 | */ | ||
808 | |||
809 | const QFileInfoList *QDir::entryInfoList( int filterSpec, int sortSpec ) const | ||
810 | { | ||
811 | if ( !dirty && filterSpec == (int)DefaultFilter && | ||
812 | sortSpec == (int)DefaultSort ) | ||
813 | return fiList; | ||
814 | return entryInfoList( nameFilt, filterSpec, sortSpec ); | ||
815 | } | ||
816 | |||
817 | /*! | ||
818 | Returns a list of QFileInfo objects for all the files and | ||
819 | directories in the directory, ordered in accordance with | ||
820 | setSorting() and filtered in accordance with setFilter() and | ||
821 | setNameFilter(). | ||
822 | |||
823 | The filter and sorting specifications can be overridden using the | ||
824 | \a nameFilter, \a filterSpec and \a sortSpec arguments. | ||
825 | |||
826 | Returns 0 if the directory is unreadable or does not exist. | ||
827 | |||
828 | The returned pointer is a const pointer to a QFileInfoList. The | ||
829 | list is owned by the QDir object and will be reused on the next | ||
830 | call to entryInfoList() for the same QDir instance. If you want to | ||
831 | keep the entries of the list after a subsequent call to this | ||
832 | function you must copy them. | ||
833 | |||
834 | \sa entryList(), setNameFilter(), setSorting(), setFilter() | ||
835 | */ | ||
836 | |||
837 | const QFileInfoList *QDir::entryInfoList( const QString &nameFilter, | ||
838 | int filterSpec, int sortSpec ) const | ||
839 | { | ||
840 | if ( filterSpec == (int)DefaultFilter ) | ||
841 | filterSpec = filtS; | ||
842 | if ( sortSpec == (int)DefaultSort ) | ||
843 | sortSpec = sortS; | ||
844 | QDir *that = (QDir*)this; // mutable function | ||
845 | if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) ) | ||
846 | return that->fiList; | ||
847 | else | ||
848 | return 0; | ||
849 | } | ||
850 | |||
851 | /*! | ||
852 | \overload | ||
853 | |||
854 | Returns TRUE if the \e directory exists; otherwise returns FALSE. | ||
855 | (If a file with the same name is found this function will return | ||
856 | FALSE). | ||
857 | |||
858 | \sa QFileInfo::exists(), QFile::exists() | ||
859 | */ | ||
860 | |||
861 | bool QDir::exists() const | ||
862 | { | ||
863 | QFileInfo fi( dPath ); | ||
864 | return fi.exists() && fi.isDir(); | ||
865 | } | ||
866 | |||
867 | /*! | ||
868 | Returns TRUE if the directory path is relative to the current | ||
869 | directory and returns FALSE if the path is absolute (e.g. under | ||
870 | UNIX a path is relative if it does not start with a "/"). | ||
871 | |||
872 | \sa convertToAbs() | ||
873 | */ | ||
874 | |||
875 | bool QDir::isRelative() const | ||
876 | { | ||
877 | return isRelativePath( dPath ); | ||
878 | } | ||
879 | |||
880 | /*! | ||
881 | Converts the directory path to an absolute path. If it is already | ||
882 | absolute nothing is done. | ||
883 | |||
884 | \sa isRelative() | ||
885 | */ | ||
886 | |||
887 | void QDir::convertToAbs() | ||
888 | { | ||
889 | dPath = absPath(); | ||
890 | } | ||
891 | |||
892 | /*! | ||
893 | Makes a copy of QDir \a d and assigns it to this QDir. | ||
894 | */ | ||
895 | |||
896 | QDir &QDir::operator=( const QDir &d ) | ||
897 | { | ||
898 | dPath = d.dPath; | ||
899 | delete fList; | ||
900 | fList = 0; | ||
901 | delete fiList; | ||
902 | fiList = 0; | ||
903 | nameFilt = d.nameFilt; | ||
904 | dirty = TRUE; | ||
905 | allDirs = d.allDirs; | ||
906 | filtS = d.filtS; | ||
907 | sortS = d.sortS; | ||
908 | return *this; | ||
909 | } | ||
910 | |||
911 | /*! | ||
912 | \overload | ||
913 | |||
914 | Sets the directory path to be the given \a path. | ||
915 | */ | ||
916 | |||
917 | QDir &QDir::operator=( const QString &path ) | ||
918 | { | ||
919 | dPath = cleanDirPath( path ); | ||
920 | dirty = TRUE; | ||
921 | return *this; | ||
922 | } | ||
923 | |||
924 | |||
925 | /*! | ||
926 | \fn bool QDir::operator!=( const QDir &d ) const | ||
927 | |||
928 | Returns TRUE if directory \a d and this directory have different | ||
929 | paths or different sort or filter settings; otherwise returns | ||
930 | FALSE. | ||
931 | |||
932 | Example: | ||
933 | \code | ||
934 | // The current directory is "/usr/local" | ||
935 | QDir d1( "/usr/local/bin" ); | ||
936 | QDir d2( "bin" ); | ||
937 | if ( d1 != d2 ) qDebug( "They differ\n" ); // This is printed | ||
938 | \endcode | ||
939 | */ | ||
940 | |||
941 | /*! | ||
942 | Returns TRUE if directory \a d and this directory have the same | ||
943 | path and their sort and filter settings are the same; otherwise | ||
944 | returns FALSE. | ||
945 | |||
946 | Example: | ||
947 | \code | ||
948 | // The current directory is "/usr/local" | ||
949 | QDir d1( "/usr/local/bin" ); | ||
950 | QDir d2( "bin" ); | ||
951 | d2.convertToAbs(); | ||
952 | if ( d1 == d2 ) qDebug( "They're the same\n" ); // This is printed | ||
953 | \endcode | ||
954 | */ | ||
955 | |||
956 | bool QDir::operator==( const QDir &d ) const | ||
957 | { | ||
958 | return dPath == d.dPath && | ||
959 | nameFilt == d.nameFilt && | ||
960 | allDirs == d.allDirs && | ||
961 | filtS == d.filtS && | ||
962 | sortS == d.sortS; | ||
963 | } | ||
964 | |||
965 | |||
966 | /*! | ||
967 | Removes the file, \a fileName. | ||
968 | |||
969 | If \a acceptAbsPath is TRUE a path starting with separator "/" | ||
970 | will remove the file with the absolute path. If \a acceptAbsPath | ||
971 | is FALSE any number of separators at the beginning of \a fileName | ||
972 | will be removed and the resultant file name will be removed. | ||
973 | |||
974 | Returns TRUE if the file is removed successfully; otherwise | ||
975 | returns FALSE. | ||
976 | */ | ||
977 | |||
978 | bool QDir::remove( const QString &fileName, bool acceptAbsPath ) | ||
979 | { | ||
980 | if ( fileName.isEmpty() ) { | ||
981 | #if defined(QT_CHECK_NULL) | ||
982 | qWarning( "QDir::remove: Empty or null file name" ); | ||
983 | #endif | ||
984 | return FALSE; | ||
985 | } | ||
986 | QString p = filePath( fileName, acceptAbsPath ); | ||
987 | return QFile::remove( p ); | ||
988 | } | ||
989 | |||
990 | /*! | ||
991 | Checks for the existence of the file \a name. | ||
992 | |||
993 | If \a acceptAbsPath is TRUE a path starting with separator "/" | ||
994 | will check the file with the absolute path. If \a acceptAbsPath is | ||
995 | FALSE any number of separators at the beginning of \a name will be | ||
996 | removed and the resultant file name will be checked. | ||
997 | |||
998 | Returns TRUE if the file exists; otherwise returns FALSE. | ||
999 | |||
1000 | \sa QFileInfo::exists(), QFile::exists() | ||
1001 | */ | ||
1002 | |||
1003 | bool QDir::exists( const QString &name, bool acceptAbsPath ) //### const in 4.0 | ||
1004 | { | ||
1005 | if ( name.isEmpty() ) { | ||
1006 | #if defined(QT_CHECK_NULL) | ||
1007 | qWarning( "QDir::exists: Empty or null file name" ); | ||
1008 | #endif | ||
1009 | return FALSE; | ||
1010 | } | ||
1011 | QString tmp = filePath( name, acceptAbsPath ); | ||
1012 | return QFile::exists( tmp ); | ||
1013 | } | ||
1014 | |||
1015 | /*! | ||
1016 | Returns the native directory separator; "/" under UNIX (including | ||
1017 | Mac OS X) and "\" under Windows. | ||
1018 | |||
1019 | You do not need to use this function to build file paths. If you | ||
1020 | always use "/", Qt will translate your paths to conform to the | ||
1021 | underlying operating system. | ||
1022 | */ | ||
1023 | |||
1024 | char QDir::separator() | ||
1025 | { | ||
1026 | #if defined(Q_OS_UNIX) | ||
1027 | return '/'; | ||
1028 | #elif defined (Q_FS_FAT) || defined(Q_WS_WIN) | ||
1029 | return '\\'; | ||
1030 | #elif defined (Q_OS_MAC) | ||
1031 | return ':'; | ||
1032 | #else | ||
1033 | return '/'; | ||
1034 | #endif | ||
1035 | } | ||
1036 | |||
1037 | /*! | ||
1038 | Returns the application's current directory. | ||
1039 | |||
1040 | Use path() to access a QDir object's path. | ||
1041 | |||
1042 | \sa currentDirPath(), QDir::QDir() | ||
1043 | */ | ||
1044 | |||
1045 | QDir QDir::current() | ||
1046 | { | ||
1047 | return QDir( currentDirPath() ); | ||
1048 | } | ||
1049 | |||
1050 | /*! | ||
1051 | Returns the home directory. | ||
1052 | |||
1053 | Under Windows the \c HOME environment variable is used. If this | ||
1054 | does not exist the \c USERPROFILE environment variable is used. If | ||
1055 | that does not exist the path is formed by concatenating the \c | ||
1056 | HOMEDRIVE and \c HOMEPATH environment variables. If they don't | ||
1057 | exist the rootDirPath() is used (this uses the \c SystemDrive | ||
1058 | environment variable). If none of these exist "C:\" is used. | ||
1059 | |||
1060 | Under non-Windows operating systems the \c HOME environment | ||
1061 | variable is used if it exists, otherwise rootDirPath() is used. | ||
1062 | |||
1063 | \sa homeDirPath() | ||
1064 | */ | ||
1065 | |||
1066 | QDir QDir::home() | ||
1067 | { | ||
1068 | return QDir( homeDirPath() ); | ||
1069 | } | ||
1070 | |||
1071 | /*! | ||
1072 | Returns the root directory. | ||
1073 | |||
1074 | \sa rootDirPath() drives() | ||
1075 | */ | ||
1076 | |||
1077 | QDir QDir::root() | ||
1078 | { | ||
1079 | return QDir( rootDirPath() ); | ||
1080 | } | ||
1081 | |||
1082 | /*! | ||
1083 | \fn QString QDir::homeDirPath() | ||
1084 | |||
1085 | Returns the absolute path of the user's home directory. | ||
1086 | |||
1087 | \sa home() | ||
1088 | */ | ||
1089 | |||
1090 | QStringList qt_makeFilterList( const QString &filter ) | ||
1091 | { | ||
1092 | if ( filter.isEmpty() ) | ||
1093 | return QStringList(); | ||
1094 | |||
1095 | QChar sep( ';' ); | ||
1096 | int i = filter.find( sep, 0 ); | ||
1097 | if ( i == -1 && filter.find( ' ', 0 ) != -1 ) | ||
1098 | sep = QChar( ' ' ); | ||
1099 | |||
1100 | QStringList list = QStringList::split( sep, filter ); | ||
1101 | QStringList::Iterator it = list.begin(); | ||
1102 | QStringList list2; | ||
1103 | |||
1104 | for ( ; it != list.end(); ++it ) { | ||
1105 | QString s = *it; | ||
1106 | list2 << s.stripWhiteSpace(); | ||
1107 | } | ||
1108 | return list2; | ||
1109 | } | ||
1110 | |||
1111 | /*! | ||
1112 | \overload | ||
1113 | |||
1114 | Returns TRUE if the \a fileName matches any of the wildcard (glob) | ||
1115 | patterns in the list of \a filters; otherwise returns FALSE. | ||
1116 | |||
1117 | (See \link qregexp.html#wildcard-matching QRegExp wildcard | ||
1118 | matching.\endlink) | ||
1119 | \sa QRegExp::match() | ||
1120 | */ | ||
1121 | |||
1122 | bool QDir::match( const QStringList &filters, const QString &fileName ) | ||
1123 | { | ||
1124 | QStringList::ConstIterator sit = filters.begin(); | ||
1125 | while ( sit != filters.end() ) { | ||
1126 | #if defined(Q_FS_FAT) && !defined(Q_OS_UNIX) | ||
1127 | QRegExp rx( *sit, FALSE, TRUE ); // The FAT FS is not case sensitive.. | ||
1128 | #else | ||
1129 | QRegExp rx( *sit, TRUE, TRUE ); // ..while others are. | ||
1130 | #endif | ||
1131 | if ( rx.exactMatch(fileName) ) | ||
1132 | return TRUE; | ||
1133 | ++sit; | ||
1134 | } | ||
1135 | return FALSE; | ||
1136 | } | ||
1137 | |||
1138 | /*! | ||
1139 | Returns TRUE if the \a fileName matches the wildcard (glob) | ||
1140 | pattern \a filter; otherwise returns FALSE. The \a filter may | ||
1141 | contain multiple patterns separated by spaces or semicolons. | ||
1142 | |||
1143 | (See \link qregexp.html#wildcard-matching QRegExp wildcard | ||
1144 | matching.\endlink) | ||
1145 | \sa QRegExp::match() | ||
1146 | */ | ||
1147 | |||
1148 | bool QDir::match( const QString &filter, const QString &fileName ) | ||
1149 | { | ||
1150 | QStringList lst = qt_makeFilterList( filter ); | ||
1151 | return match( lst, fileName ); | ||
1152 | } | ||
1153 | |||
1154 | |||
1155 | /*! | ||
1156 | Removes all multiple directory separators "/" and resolves any | ||
1157 | "."s or ".."s found in the path, \a filePath. | ||
1158 | |||
1159 | Symbolic links are kept. This function does not return the | ||
1160 | canonical path, but rather the simplest version of the input. | ||
1161 | For example, "./local" becomes "local", "local/../bin" becomes | ||
1162 | "bin" and "/local/usr/../bin" becomes "/local/bin". | ||
1163 | |||
1164 | \sa absPath() canonicalPath() | ||
1165 | */ | ||
1166 | |||
1167 | QString QDir::cleanDirPath( const QString &filePath ) | ||
1168 | { | ||
1169 | QString name = filePath; | ||
1170 | QString newPath; | ||
1171 | |||
1172 | if ( name.isEmpty() ) | ||
1173 | return name; | ||
1174 | |||
1175 | slashify( name ); | ||
1176 | |||
1177 | bool addedSeparator; | ||
1178 | if ( isRelativePath(name) ) { | ||
1179 | addedSeparator = TRUE; | ||
1180 | name.insert( 0, '/' ); | ||
1181 | } else { | ||
1182 | addedSeparator = FALSE; | ||
1183 | } | ||
1184 | |||
1185 | int ePos, pos, upLevel; | ||
1186 | |||
1187 | pos = ePos = name.length(); | ||
1188 | upLevel = 0; | ||
1189 | int len; | ||
1190 | |||
1191 | while ( pos && (pos = name.findRev('/',--pos)) != -1 ) { | ||
1192 | len = ePos - pos - 1; | ||
1193 | if ( len == 2 && name.at(pos + 1) == '.' | ||
1194 | && name.at(pos + 2) == '.' ) { | ||
1195 | upLevel++; | ||
1196 | } else { | ||
1197 | if ( len != 0 && (len != 1 || name.at(pos + 1) != '.') ) { | ||
1198 | if ( !upLevel ) | ||
1199 | newPath = QString::fromLatin1("/") | ||
1200 | + name.mid(pos + 1, len) + newPath; | ||
1201 | else | ||
1202 | upLevel--; | ||
1203 | } | ||
1204 | } | ||
1205 | ePos = pos; | ||
1206 | } | ||
1207 | if ( addedSeparator ) { | ||
1208 | while ( upLevel-- ) | ||
1209 | newPath.insert( 0, QString::fromLatin1("/..") ); | ||
1210 | if ( !newPath.isEmpty() ) | ||
1211 | newPath.remove( 0, 1 ); | ||
1212 | else | ||
1213 | newPath = QString::fromLatin1("."); | ||
1214 | } else { | ||
1215 | if ( newPath.isEmpty() ) | ||
1216 | newPath = QString::fromLatin1("/"); | ||
1217 | #if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX) | ||
1218 | if ( name[0] == '/' ) { | ||
1219 | if ( name[1] == '/' ) // "\\machine\x\ ..." | ||
1220 | newPath.insert( 0, '/' ); | ||
1221 | } else { | ||
1222 | newPath = name.left(2) + newPath; | ||
1223 | } | ||
1224 | #endif | ||
1225 | } | ||
1226 | return newPath; | ||
1227 | } | ||
1228 | |||
1229 | int qt_cmp_si_sortSpec; | ||
1230 | |||
1231 | #if defined(Q_C_CALLBACKS) | ||
1232 | extern "C" { | ||
1233 | #endif | ||
1234 | |||
1235 | #ifdef Q_OS_TEMP | ||
1236 | int __cdecl qt_cmp_si( const void *n1, const void *n2 ) | ||
1237 | #else | ||
1238 | int qt_cmp_si( const void *n1, const void *n2 ) | ||
1239 | #endif | ||
1240 | { | ||
1241 | if ( !n1 || !n2 ) | ||
1242 | return 0; | ||
1243 | |||
1244 | QDirSortItem* f1 = (QDirSortItem*)n1; | ||
1245 | QDirSortItem* f2 = (QDirSortItem*)n2; | ||
1246 | |||
1247 | if ( qt_cmp_si_sortSpec & QDir::DirsFirst ) | ||
1248 | if ( f1->item->isDir() != f2->item->isDir() ) | ||
1249 | return f1->item->isDir() ? -1 : 1; | ||
1250 | |||
1251 | int r = 0; | ||
1252 | int sortBy = qt_cmp_si_sortSpec & QDir::SortByMask; | ||
1253 | |||
1254 | switch ( sortBy ) { | ||
1255 | case QDir::Time: | ||
1256 | r = f1->item->lastModified().secsTo(f2->item->lastModified()); | ||
1257 | break; | ||
1258 | case QDir::Size: | ||
1259 | r = f2->item->size() - f1->item->size(); | ||
1260 | break; | ||
1261 | default: | ||
1262 | ; | ||
1263 | } | ||
1264 | |||
1265 | if ( r == 0 && sortBy != QDir::Unsorted ) { | ||
1266 | // Still not sorted - sort by name | ||
1267 | bool ic = qt_cmp_si_sortSpec & QDir::IgnoreCase; | ||
1268 | |||
1269 | if ( f1->filename_cache.isNull() ) | ||
1270 | f1->filename_cache = ic ? f1->item->fileName().lower() | ||
1271 | : f1->item->fileName(); | ||
1272 | if ( f2->filename_cache.isNull() ) | ||
1273 | f2->filename_cache = ic ? f2->item->fileName().lower() | ||
1274 | : f2->item->fileName(); | ||
1275 | |||
1276 | r = f1->filename_cache.compare(f2->filename_cache); | ||
1277 | } | ||
1278 | |||
1279 | if ( r == 0 ) { | ||
1280 | // Enforce an order - the order the items appear in the array | ||
1281 | r = (char*)n1 - (char*)n2; | ||
1282 | } | ||
1283 | |||
1284 | if ( qt_cmp_si_sortSpec & QDir::Reversed ) | ||
1285 | return -r; | ||
1286 | else | ||
1287 | return r; | ||
1288 | } | ||
1289 | |||
1290 | #if defined(Q_C_CALLBACKS) | ||
1291 | } | ||
1292 | #endif | ||
1293 | |||
1294 | #endif // QT_NO_DIR | ||