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