Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

qdir.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** $Id: qdir.cpp,v 1.2 2003/07/10 02:40:11 llornkcor Exp $
00003 **
00004 ** Implementation of QDir class
00005 **
00006 ** Created : 950427
00007 **
00008 ** Copyright (C) 1992-2003 Trolltech AS.  All rights reserved.
00009 **
00010 ** This file is part of the tools module of the Qt GUI Toolkit.
00011 **
00012 ** This file may be distributed under the terms of the Q Public License
00013 ** as defined by Trolltech AS of Norway and appearing in the file
00014 ** LICENSE.QPL included in the packaging of this file.
00015 **
00016 ** This file may be distributed and/or modified under the terms of the
00017 ** GNU General Public License version 2 as published by the Free Software
00018 ** Foundation and appearing in the file LICENSE.GPL included in the
00019 ** packaging of this file.
00020 **
00021 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
00022 ** licenses may use this file in accordance with the Qt Commercial License
00023 ** Agreement provided with the Software.
00024 **
00025 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00026 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00027 **
00028 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
00029 **   information about Qt Commercial License Agreements.
00030 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
00031 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00032 **
00033 ** Contact info@trolltech.com if any conditions of this licensing are
00034 ** not clear to you.
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;                    // regret
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 // ### Unsorted+DirsFirst ? Unsorted+Reversed?
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;                   // mutable function
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;                   // mutable function
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 ) //### const in 4.0
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] == '/' )               // "\\machine\x\ ..."
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         // Still not sorted - sort by name
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         // Enforce an order - the order the items appear in the array
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

Generated on Sat Nov 5 16:18:30 2005 for OPIE by  doxygen 1.4.2