00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "qplatformdefs.h"
00039 #include "qdir.h"
00040
00041 #ifndef QT_NO_DIR
00042 #include <private/qdir_p.h>
00043 #include "qfileinfo.h"
00044 #include "qregexp.h"
00045 #include "qstringlist.h"
00046 #include <limits.h>
00047
00048 #if defined(Q_FS_FAT) && !defined(Q_OS_UNIX)
00049 const bool CaseSensitiveFS = FALSE;
00050 #else
00051 const bool CaseSensitiveFS = TRUE;
00052 #endif
00053
00054
00174 QDir::QDir()
00175 {
00176 dPath = QString::fromLatin1(".");
00177 init();
00178 }
00179
00206 QDir::QDir( const QString &path, const QString &nameFilter,
00207 int sortSpec, int filterSpec )
00208 {
00209 init();
00210 dPath = cleanDirPath( path );
00211 if ( dPath.isEmpty() )
00212 dPath = QString::fromLatin1(".");
00213 nameFilt = nameFilter;
00214 if ( nameFilt.isEmpty() )
00215 nameFilt = QString::fromLatin1("*");
00216 filtS = (FilterSpec)filterSpec;
00217 sortS = (SortSpec)sortSpec;
00218 }
00219
00226 QDir::QDir( const QDir &d )
00227 {
00228 dPath = d.dPath;
00229 fList = 0;
00230 fiList = 0;
00231 nameFilt = d.nameFilt;
00232 dirty = TRUE;
00233 allDirs = d.allDirs;
00234 filtS = d.filtS;
00235 sortS = d.sortS;
00236 }
00237
00241 void QDir::refresh() const
00242 {
00243 QDir* that = (QDir*) this;
00244 that->dirty = TRUE;
00245 }
00246
00247 void QDir::init()
00248 {
00249 fList = 0;
00250 fiList = 0;
00251 nameFilt = QString::fromLatin1("*");
00252 dirty = TRUE;
00253 allDirs = FALSE;
00254 filtS = All;
00255 sortS = SortSpec(Name | IgnoreCase);
00256 }
00257
00262 QDir::~QDir()
00263 {
00264 delete fList;
00265 delete fiList;
00266 }
00267
00268
00285 void QDir::setPath( const QString &path )
00286 {
00287 dPath = cleanDirPath( path );
00288 if ( dPath.isEmpty() )
00289 dPath = QString::fromLatin1(".");
00290 dirty = TRUE;
00291 }
00292
00315 QString QDir::absPath() const
00316 {
00317 if ( QDir::isRelativePath(dPath) ) {
00318 QString tmp = currentDirPath();
00319 if ( tmp.right(1) != QString::fromLatin1("/") )
00320 tmp += '/';
00321 tmp += dPath;
00322 return cleanDirPath( tmp );
00323 } else {
00324 return cleanDirPath( dPath );
00325 }
00326 }
00327
00340 QString QDir::dirName() const
00341 {
00342 int pos = dPath.findRev( '/' );
00343 if ( pos == -1 )
00344 return dPath;
00345 return dPath.right( dPath.length() - pos - 1 );
00346 }
00347
00363 QString QDir::filePath( const QString &fileName,
00364 bool acceptAbsPath ) const
00365 {
00366 if ( acceptAbsPath && !isRelativePath(fileName) )
00367 return QString(fileName);
00368
00369 QString tmp = dPath;
00370 if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
00371 fileName[0] != '/') )
00372 tmp += '/';
00373 tmp += fileName;
00374 return tmp;
00375 }
00376
00391 QString QDir::absFilePath( const QString &fileName,
00392 bool acceptAbsPath ) const
00393 {
00394 if ( acceptAbsPath && !isRelativePath( fileName ) )
00395 return fileName;
00396
00397 QString tmp = absPath();
00398 #ifdef Q_OS_WIN32
00399 if ( fileName[0].isLetter() && fileName[1] == ':' ) {
00400 int drv = fileName.upper()[0].latin1() - 'A' + 1;
00401 if ( _getdrive() != drv ) {
00402 if ( qt_winunicode ) {
00403 TCHAR buf[PATH_MAX];
00404 ::_tgetdcwd( drv, buf, PATH_MAX );
00405 tmp.setUnicodeCodes( (ushort*)buf, ::_tcslen(buf) );
00406 } else {
00407 char buf[PATH_MAX];
00408 ::_getdcwd( drv, buf, PATH_MAX );
00409 tmp = buf;
00410 }
00411 if ( !tmp.endsWith("\\") )
00412 tmp += "\\";
00413 tmp += fileName.right( fileName.length() - 2 );
00414 int x;
00415 for ( x = 0; x < (int) tmp.length(); x++ ) {
00416 if ( tmp[x] == '\\' )
00417 tmp[x] = '/';
00418 }
00419 }
00420 } else
00421 #endif
00422 {
00423 if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
00424 fileName[0] != '/') )
00425 tmp += '/';
00426 tmp += fileName;
00427 }
00428 return tmp;
00429 }
00430
00431
00444 QString QDir::convertSeparators( const QString &pathName )
00445 {
00446 QString n( pathName );
00447 #if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX)
00448 for ( int i=0; i<(int)n.length(); i++ ) {
00449 if ( n[i] == '/' )
00450 n[i] = '\\';
00451 }
00452 #elif defined(Q_OS_MAC9)
00453 while(n.length() && n[0] == '/' ) n = n.right(n.length()-1);
00454 for ( int i=0; i<(int)n.length(); i++ ) {
00455 if ( n[i] == '/' )
00456 n[i] = ':';
00457 }
00458 if(n.contains(':') && n.left(1) != ':')
00459 n.prepend(':');
00460 #endif
00461 return n;
00462 }
00463
00464
00483 bool QDir::cd( const QString &dirName, bool acceptAbsPath )
00484 {
00485 if ( dirName.isEmpty() || dirName==QString::fromLatin1(".") )
00486 return TRUE;
00487 QString old = dPath;
00488 if ( acceptAbsPath && !isRelativePath(dirName) ) {
00489 dPath = cleanDirPath( dirName );
00490 } else {
00491 if ( !isRoot() ) {
00492 dPath += '/';
00493 } else if ( dirName == ".." ) {
00494 dPath = old;
00495 return FALSE;
00496 }
00497 dPath += dirName;
00498 if ( dirName.find('/') >= 0
00499 || old == QString::fromLatin1(".")
00500 || dirName == QString::fromLatin1("..") )
00501 dPath = cleanDirPath( dPath );
00502 }
00503 if ( !exists() ) {
00504 dPath = old;
00505 return FALSE;
00506 }
00507 dirty = TRUE;
00508 return TRUE;
00509 }
00510
00522 bool QDir::cdUp()
00523 {
00524 return cd( QString::fromLatin1("..") );
00525 }
00526
00550 void QDir::setNameFilter( const QString &nameFilter )
00551 {
00552 nameFilt = nameFilter;
00553 if ( nameFilt.isEmpty() )
00554 nameFilt = QString::fromLatin1("*");
00555 dirty = TRUE;
00556 }
00557
00615 void QDir::setFilter( int filterSpec )
00616 {
00617 if ( filtS == (FilterSpec) filterSpec )
00618 return;
00619 filtS = (FilterSpec) filterSpec;
00620 dirty = TRUE;
00621 }
00622
00656
00657
00667 void QDir::setSorting( int sortSpec )
00668 {
00669 if ( sortS == (SortSpec) sortSpec )
00670 return;
00671 sortS = (SortSpec) sortSpec;
00672 dirty = TRUE;
00673 }
00674
00692 void QDir::setMatchAllDirs( bool enable )
00693 {
00694 if ( (bool)allDirs == enable )
00695 return;
00696 allDirs = enable;
00697 dirty = TRUE;
00698 }
00699
00700
00709 uint QDir::count() const
00710 {
00711 return (uint)entryList().count();
00712 }
00713
00724 QString QDir::operator[]( int index ) const
00725 {
00726 entryList();
00727 return fList && index >= 0 && index < (int)fList->count() ?
00728 (*fList)[index] : QString::null;
00729 }
00730
00731
00740 QStrList QDir::encodedEntryList( int filterSpec, int sortSpec ) const
00741 {
00742 QStrList r;
00743 QStringList l = entryList(filterSpec,sortSpec);
00744 for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
00745 r.append( QFile::encodeName(*it) );
00746 }
00747 return r;
00748 }
00749
00759 QStrList QDir::encodedEntryList( const QString &nameFilter,
00760 int filterSpec,
00761 int sortSpec ) const
00762 {
00763 QStrList r;
00764 QStringList l = entryList(nameFilter,filterSpec,sortSpec);
00765 for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
00766 r.append( QFile::encodeName(*it) );
00767 }
00768 return r;
00769 }
00770
00771
00772
00789 QStringList QDir::entryList( int filterSpec, int sortSpec ) const
00790 {
00791 if ( !dirty && filterSpec == (int)DefaultFilter &&
00792 sortSpec == (int)DefaultSort )
00793 return *fList;
00794 return entryList( nameFilt, filterSpec, sortSpec );
00795 }
00796
00811 QStringList QDir::entryList( const QString &nameFilter,
00812 int filterSpec, int sortSpec ) const
00813 {
00814 if ( filterSpec == (int)DefaultFilter )
00815 filterSpec = filtS;
00816 if ( sortSpec == (int)DefaultSort )
00817 sortSpec = sortS;
00818 QDir *that = (QDir*)this;
00819 if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) ) {
00820 if ( that->fList )
00821 return *that->fList;
00822 }
00823 return QStringList();
00824 }
00825
00848 const QFileInfoList *QDir::entryInfoList( int filterSpec, int sortSpec ) const
00849 {
00850 if ( !dirty && filterSpec == (int)DefaultFilter &&
00851 sortSpec == (int)DefaultSort )
00852 return fiList;
00853 return entryInfoList( nameFilt, filterSpec, sortSpec );
00854 }
00855
00876 const QFileInfoList *QDir::entryInfoList( const QString &nameFilter,
00877 int filterSpec, int sortSpec ) const
00878 {
00879 if ( filterSpec == (int)DefaultFilter )
00880 filterSpec = filtS;
00881 if ( sortSpec == (int)DefaultSort )
00882 sortSpec = sortS;
00883 QDir *that = (QDir*)this;
00884 if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) )
00885 return that->fiList;
00886 else
00887 return 0;
00888 }
00889
00900 bool QDir::exists() const
00901 {
00902 QFileInfo fi( dPath );
00903 return fi.exists() && fi.isDir();
00904 }
00905
00914 bool QDir::isRelative() const
00915 {
00916 return isRelativePath( dPath );
00917 }
00918
00926 void QDir::convertToAbs()
00927 {
00928 dPath = absPath();
00929 }
00930
00935 QDir &QDir::operator=( const QDir &d )
00936 {
00937 dPath = d.dPath;
00938 delete fList;
00939 fList = 0;
00940 delete fiList;
00941 fiList = 0;
00942 nameFilt = d.nameFilt;
00943 dirty = TRUE;
00944 allDirs = d.allDirs;
00945 filtS = d.filtS;
00946 sortS = d.sortS;
00947 return *this;
00948 }
00949
00956 QDir &QDir::operator=( const QString &path )
00957 {
00958 dPath = cleanDirPath( path );
00959 dirty = TRUE;
00960 return *this;
00961 }
00962
00963
00997 bool QDir::operator==( const QDir &d ) const
00998 {
00999 return dPath == d.dPath &&
01000 nameFilt == d.nameFilt &&
01001 allDirs == d.allDirs &&
01002 filtS == d.filtS &&
01003 sortS == d.sortS;
01004 }
01005
01006
01019 bool QDir::remove( const QString &fileName, bool acceptAbsPath )
01020 {
01021 if ( fileName.isEmpty() ) {
01022 #if defined(QT_CHECK_NULL)
01023 qWarning( "QDir::remove: Empty or null file name" );
01024 #endif
01025 return FALSE;
01026 }
01027 QString p = filePath( fileName, acceptAbsPath );
01028 return QFile::remove( p );
01029 }
01030
01044 bool QDir::exists( const QString &name, bool acceptAbsPath )
01045 {
01046 if ( name.isEmpty() ) {
01047 #if defined(QT_CHECK_NULL)
01048 qWarning( "QDir::exists: Empty or null file name" );
01049 #endif
01050 return FALSE;
01051 }
01052 QString tmp = filePath( name, acceptAbsPath );
01053 return QFile::exists( tmp );
01054 }
01055
01065 char QDir::separator()
01066 {
01067 #if defined(Q_OS_UNIX)
01068 return '/';
01069 #elif defined (Q_FS_FAT) || defined(Q_WS_WIN)
01070 return '\\';
01071 #elif defined (Q_OS_MAC)
01072 return ':';
01073 #else
01074 return '/';
01075 #endif
01076 }
01077
01086 QDir QDir::current()
01087 {
01088 return QDir( currentDirPath() );
01089 }
01090
01107 QDir QDir::home()
01108 {
01109 return QDir( homeDirPath() );
01110 }
01111
01118 QDir QDir::root()
01119 {
01120 return QDir( rootDirPath() );
01121 }
01122
01131 QValueList<QRegExp> qt_makeFilterList( const QString &filter )
01132 {
01133 QValueList<QRegExp> regExps;
01134 if ( filter.isEmpty() )
01135 return regExps;
01136
01137 QChar sep( ';' );
01138 int i = filter.find( sep, 0 );
01139 if ( i == -1 && filter.find( ' ', 0 ) != -1 )
01140 sep = QChar( ' ' );
01141
01142 QStringList list = QStringList::split( sep, filter );
01143 QStringList::Iterator it = list.begin();
01144 while ( it != list.end() ) {
01145 regExps << QRegExp( (*it).stripWhiteSpace(), CaseSensitiveFS, TRUE );
01146 ++it;
01147 }
01148 return regExps;
01149 }
01150
01151 bool qt_matchFilterList( const QValueList<QRegExp>& filters,
01152 const QString &fileName )
01153 {
01154 QValueList<QRegExp>::ConstIterator rit = filters.begin();
01155 while ( rit != filters.end() ) {
01156 if ( (*rit).exactMatch(fileName) )
01157 return TRUE;
01158 ++rit;
01159 }
01160 return FALSE;
01161 }
01162
01163
01175 bool QDir::match( const QStringList &filters, const QString &fileName )
01176 {
01177 QStringList::ConstIterator sit = filters.begin();
01178 while ( sit != filters.end() ) {
01179 QRegExp rx( *sit, CaseSensitiveFS, TRUE );
01180 if ( rx.exactMatch(fileName) )
01181 return TRUE;
01182 ++sit;
01183 }
01184 return FALSE;
01185 }
01186
01197 bool QDir::match( const QString &filter, const QString &fileName )
01198 {
01199 return qt_matchFilterList( qt_makeFilterList(filter), fileName );
01200 }
01201
01202
01215 QString QDir::cleanDirPath( const QString &filePath )
01216 {
01217 QString name = filePath;
01218 QString newPath;
01219
01220 if ( name.isEmpty() )
01221 return name;
01222
01223 slashify( name );
01224
01225 bool addedSeparator;
01226 if ( isRelativePath(name) ) {
01227 addedSeparator = TRUE;
01228 name.insert( 0, '/' );
01229 } else {
01230 addedSeparator = FALSE;
01231 }
01232
01233 int ePos, pos, upLevel;
01234
01235 pos = ePos = name.length();
01236 upLevel = 0;
01237 int len;
01238
01239 while ( pos && (pos = name.findRev('/',--pos)) != -1 ) {
01240 len = ePos - pos - 1;
01241 if ( len == 2 && name.at(pos + 1) == '.'
01242 && name.at(pos + 2) == '.' ) {
01243 upLevel++;
01244 } else {
01245 if ( len != 0 && (len != 1 || name.at(pos + 1) != '.') ) {
01246 if ( !upLevel )
01247 newPath = QString::fromLatin1("/")
01248 + name.mid(pos + 1, len) + newPath;
01249 else
01250 upLevel--;
01251 }
01252 }
01253 ePos = pos;
01254 }
01255 if ( addedSeparator ) {
01256 while ( upLevel-- )
01257 newPath.insert( 0, QString::fromLatin1("/..") );
01258 if ( !newPath.isEmpty() )
01259 newPath.remove( 0, 1 );
01260 else
01261 newPath = QString::fromLatin1(".");
01262 } else {
01263 if ( newPath.isEmpty() )
01264 newPath = QString::fromLatin1("/");
01265 #if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX)
01266 if ( name[0] == '/' ) {
01267 if ( name[1] == '/' )
01268 newPath.insert( 0, '/' );
01269 } else {
01270 newPath = name.left(2) + newPath;
01271 }
01272 #endif
01273 }
01274 return newPath;
01275 }
01276
01277 int qt_cmp_si_sortSpec;
01278
01279 #if defined(Q_C_CALLBACKS)
01280 extern "C" {
01281 #endif
01282
01283 #ifdef Q_OS_TEMP
01284 int __cdecl qt_cmp_si( const void *n1, const void *n2 )
01285 #else
01286 int qt_cmp_si( const void *n1, const void *n2 )
01287 #endif
01288 {
01289 if ( !n1 || !n2 )
01290 return 0;
01291
01292 QDirSortItem* f1 = (QDirSortItem*)n1;
01293 QDirSortItem* f2 = (QDirSortItem*)n2;
01294
01295 if ( qt_cmp_si_sortSpec & QDir::DirsFirst )
01296 if ( f1->item->isDir() != f2->item->isDir() )
01297 return f1->item->isDir() ? -1 : 1;
01298
01299 int r = 0;
01300 int sortBy = qt_cmp_si_sortSpec & QDir::SortByMask;
01301
01302 switch ( sortBy ) {
01303 case QDir::Time:
01304 r = f1->item->lastModified().secsTo(f2->item->lastModified());
01305 break;
01306 case QDir::Size:
01307 r = f2->item->size() - f1->item->size();
01308 break;
01309 default:
01310 ;
01311 }
01312
01313 if ( r == 0 && sortBy != QDir::Unsorted ) {
01314
01315 bool ic = qt_cmp_si_sortSpec & QDir::IgnoreCase;
01316
01317 if ( f1->filename_cache.isNull() )
01318 f1->filename_cache = ic ? f1->item->fileName().lower()
01319 : f1->item->fileName();
01320 if ( f2->filename_cache.isNull() )
01321 f2->filename_cache = ic ? f2->item->fileName().lower()
01322 : f2->item->fileName();
01323
01324 r = f1->filename_cache.compare(f2->filename_cache);
01325 }
01326
01327 if ( r == 0 ) {
01328
01329 r = (char*)n1 - (char*)n2;
01330 }
01331
01332 if ( qt_cmp_si_sortSpec & QDir::Reversed )
01333 return -r;
01334 else
01335 return r;
01336 }
01337
01338 #if defined(Q_C_CALLBACKS)
01339 }
01340 #endif
01341
01342 #endif // QT_NO_DIR