?? qdir.cpp
字號:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the QtCore module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qplatformdefs.h"#include "qdir.h"#include "qabstractfileengine.h"#ifndef QT_NO_DEBUG#include "qdebug.h"#endif#include "qfsfileengine.h"#include "qdatetime.h"#include "qstring.h"#include "qregexp.h"#include "qvector.h"#ifdef QT_BUILD_CORE_LIB# include "qresource.h"#endif#include <stdlib.h>static QString driveSpec(const QString &path){#ifdef Q_OS_WIN if (path.size() < 2) return QString(); char c = path.at(0).toAscii(); if (c < 'a' && c > 'z' && c < 'A' && c > 'Z') return QString(); if (path.at(1).toAscii() != ':') return QString(); return path.mid(0, 2);#else Q_UNUSED(path); return QString();#endif}//************* QDirPrivateclass QDirPrivate{ QDir *q_ptr; Q_DECLARE_PUBLIC(QDir)protected: QDirPrivate(QDir*, const QDir *copy=0); ~QDirPrivate(); void initFileEngine(const QString &file); void updateFileLists() const; void sortFileList(QDir::SortFlags, QStringList &, QStringList *, QFileInfoList *) const;private:#ifdef QT3_SUPPORT QChar filterSepChar; bool matchAllDirs;#endif static inline QChar getFilterSepChar(const QString &nameFilter) { QChar sep(QLatin1Char(';')); int i = nameFilter.indexOf(sep, 0); if (i == -1 && nameFilter.indexOf(QLatin1Char(' '), 0) != -1) sep = QChar(QLatin1Char(' ')); return sep; } static inline QStringList splitFilters(const QString &nameFilter, QChar sep=0) { if(sep == 0) sep = getFilterSepChar(nameFilter); QStringList ret = nameFilter.split(sep); for(int i = 0; i < ret.count(); i++) ret[i] = ret[i].trimmed(); return ret; } struct Data { inline Data() : ref(1), fileEngine(0) { clear(); } inline Data(const Data ©) : ref(1), path(copy.path), nameFilters(copy.nameFilters), sort(copy.sort), filters(copy.filters), fileEngine(0) { clear(); } inline ~Data() { delete fileEngine; } inline void clear() { listsDirty = 1; } mutable QAtomic ref; QString path; QStringList nameFilters; QDir::SortFlags sort; QDir::Filters filters; mutable QAbstractFileEngine *fileEngine; mutable uint listsDirty : 1; mutable QStringList files; mutable QFileInfoList fileInfos; } *data; inline void setPath(const QString &p) { detach(false); QString path = p; if ((path.endsWith(QLatin1Char('/')) || path.endsWith(QLatin1Char('\\'))) && path.length() > 1) {#ifdef Q_OS_WIN if (!(path.length() == 3 && path.at(1) == ':'))#endif path.truncate(path.length() - 1); } if(!data->fileEngine || !QDir::isRelativePath(path)) initFileEngine(path); data->fileEngine->setFileName(path); // set the path to be the qt friendly version so then we can operate on it using just / data->path = data->fileEngine->fileName(QAbstractFileEngine::DefaultName); data->clear(); } inline void reset() { detach(); data->clear(); } void detach(bool createFileEngine = true);};QDirPrivate::QDirPrivate(QDir *qq, const QDir *copy) : q_ptr(qq)#ifdef QT3_SUPPORT , filterSepChar(0) , matchAllDirs(false)#endif{ if(copy) { copy->d_func()->data->ref.ref(); data = copy->d_func()->data; } else { data = new QDirPrivate::Data; data->clear(); }}QDirPrivate::~QDirPrivate(){ if (!data->ref.deref()) delete data; data = 0; q_ptr = 0;}/* For sorting */struct QDirSortItem { QString filename_cache; QString suffix_cache; QFileInfo item;};static int qt_cmp_si_sort_flags;#if defined(Q_C_CALLBACKS)extern "C" {#endif#ifdef Q_OS_TEMPstatic int __cdecl qt_cmp_si(const void *n1, const void *n2)#elsestatic int qt_cmp_si(const void *n1, const void *n2)#endif{ if (!n1 || !n2) return 0; QDirSortItem* f1 = (QDirSortItem*)n1; QDirSortItem* f2 = (QDirSortItem*)n2; if ((qt_cmp_si_sort_flags & QDir::DirsFirst) && (f1->item.isDir() != f2->item.isDir())) return f1->item.isDir() ? -1 : 1; if ((qt_cmp_si_sort_flags & QDir::DirsLast) && (f1->item.isDir() != f2->item.isDir())) return f1->item.isDir() ? 1 : -1; int r = 0; int sortBy = (qt_cmp_si_sort_flags & QDir::SortByMask) | (qt_cmp_si_sort_flags & QDir::Type); switch (sortBy) { case QDir::Time: r = f1->item.lastModified().secsTo(f2->item.lastModified()); break; case QDir::Size: r = f2->item.size() - f1->item.size(); break; case QDir::Type: { bool ic = qt_cmp_si_sort_flags & QDir::IgnoreCase; if (f1->suffix_cache.isNull()) f1->suffix_cache = ic ? f1->item.suffix().toLower() : f1->item.suffix(); if (f2->suffix_cache.isNull()) f2->suffix_cache = ic ? f2->item.suffix().toLower() : f2->item.suffix(); r = qt_cmp_si_sort_flags & QDir::LocaleAware ? f1->suffix_cache.localeAwareCompare(f2->suffix_cache) : f1->suffix_cache.compare(f2->suffix_cache); } break; default: ; } if (r == 0 && sortBy != QDir::Unsorted) { // Still not sorted - sort by name bool ic = qt_cmp_si_sort_flags & QDir::IgnoreCase; if (f1->filename_cache.isNull()) f1->filename_cache = ic ? f1->item.fileName().toLower() : f1->item.fileName(); if (f2->filename_cache.isNull()) f2->filename_cache = ic ? f2->item.fileName().toLower() : f2->item.fileName(); r = qt_cmp_si_sort_flags & QDir::LocaleAware ? f1->filename_cache.localeAwareCompare(f2->filename_cache) : f1->filename_cache.compare(f2->filename_cache); } if (r == 0) // Enforce an order - the order the items appear in the array r = (char*)n1 - (char*)n2; if (qt_cmp_si_sort_flags & QDir::Reversed) return -r; return r;}#if defined(Q_C_CALLBACKS)}#endifinline void QDirPrivate::sortFileList(QDir::SortFlags sort, QStringList &l, QStringList *names, QFileInfoList *infos) const{ if(names) names->clear(); if(infos) infos->clear(); if(!l.isEmpty()) { QDirSortItem *si= new QDirSortItem[l.count()]; int i; for (i = 0; i < l.size(); ++i) { QString path = data->path; if (!path.isEmpty() && !path.endsWith(QLatin1Char('/'))) path += QLatin1Char('/'); si[i].item = QFileInfo(path + l.at(i)); } qt_cmp_si_sort_flags = sort; qsort(si, i, sizeof(si[0]), qt_cmp_si); // put them back in the list(s) for (int j = 0; j<i; j++) { if(infos) infos->append(si[j].item); if(names) names->append(si[j].item.fileName()); } delete [] si; }}inline void QDirPrivate::updateFileLists() const{ if(data->listsDirty) { QStringList l = data->fileEngine->entryList(data->filters, data->nameFilters); sortFileList(data->sort, l, &data->files, &data->fileInfos); data->listsDirty = 0; }}void QDirPrivate::initFileEngine(const QString &path){ detach(false); delete data->fileEngine; data->fileEngine = 0; data->clear(); data->fileEngine = QAbstractFileEngine::create(path);}void QDirPrivate::detach(bool createFileEngine){ qAtomicDetach(data); if (createFileEngine) { delete data->fileEngine; data->fileEngine = QAbstractFileEngine::create(data->path); }}/*! \class QDir \brief The QDir class provides access to directory structures and their contents. \ingroup io \ingroup shared \reentrant \mainclass A QDir is used to manipulate path names, access information regarding paths and files, and manipulate the underlying file system. It can also be used to access Qt's \l{resource system}. Qt uses "/" as a universal directory separator in the same way that "/" is used as a path separator in URLs. If you always use "/" as a directory separator, Qt will translate your paths to conform to the underlying operating system. A QDir can point to a file using either a relative or an absolute path. Absolute paths begin with the directory separator (optionally preceded by a drive specification under Windows). Relative file names begin with a directory name or a file name and specify a path relative to the current directory. Examples of absolute paths: \code QDir("/home/user/Documents") QDir("C:/Documents and Settings") \endcode On Windows, the second of the examples above will be translated to \c{C:\My Documents} when used to access files. Examples of relative paths: \code QDir("images/landscape.png") \endcode You can use the isRelative() or isAbsolute() functions to check if a QDir is using a relative or an absolute file path. Call makeAbsolute() to convert a relative QDir to an absolute one. \section1 Navigation and Directory Operations A directory's path can be obtained with the path() function, and a new path set with the setPath() function. The absolute path to a directory is found by calling absolutePath(). The name of a directory is found using the dirName() function. This typically returns the last element in the absolute path that specifies the location of the directory. However, it can also return "." if the QDir represents the current directory. \code QDir("Documents/Letters/Applications").dirName() // "Applications" QDir().dirName() // "." \endcode The path for a directory can also be changed with the cd() and cdUp() functions, both of which operate like familiar shell commands. When cd() is called with the name of an existing directory, the QDir object changes directory so that it represents that directory instead. The cdUp() function changes the directory of the QDir object so that it refers to its parent directory; i.e. cd("..") is equivalent to cdUp(). Directories can be created with mkdir(), renamed with rename(), and removed with rmdir(). You can test for the presence of a directory with a given name by using exists(), and the properties of a directory can be tested with isReadable(), isAbsolute(), isRelative(), and isRoot(). The refresh() function re-reads the directory's data from disk. \section1 Files and Directory Contents Directories contain a number of entries, representing files, directories, and symbolic links. The number of entries in a directory is returned by count(). A string list of the names of all the entries in a directory can be obtained with entryList(). If you need information about each entry, use entryInfoList() to obtain a list of QFileInfo objects. Paths to files and directories within a directory can be constructed using filePath() and absoluteFilePath(). The filePath() function returns a path to the specified file or directory relative to the path of the QDir object; absoluteFilePath() returns an absolute path to the specified file or directory. Neither of these functions checks for the existence of files or directory; they only construct paths. \code QDir directory("Documents/Letters"); QString path = directory.filePath("contents.txt"); QString absolutePath = directory.absoluteFilePath("contents.txt"); \endcode Files can be removed by using the remove() function. Directories cannot be removed in the same way as files; use rmdir() to remove them instead. It is possible to reduce the number of entries returned by entryList() and entryInfoList() by applying filters to a QDir object. You can apply a name filter to specify a pattern with wildcards that file names need to match, an attribute filter that selects properties of entries and can distinguish between files and directories, and a sort order. Name filters are lists of strings that are passed to setNameFilters(). Attribute filters consist of a bitwise OR combination of Filters, and these are specified when calling setFilter(). The sort order is specified using setSorting() with a bitwise OR combination of SortFlags. You can test to see if a filename matches a filter using the match() function. Filter and sort order flags may also be specified when calling entryList() and entryInfoList() in order to override previously defined behavior. \section1 The Current Directory and Other Special Paths Access to some common directories is provided with a number of static functions that return QDir objects. There are also corresponding functions for these that return strings: \table \header \o QDir \o QString \o Return Value \row \o current() \o currentPath() \o The application's working directory \row \o home() \o homePath() \o The user's home directory \row \o root() \o rootPath() \o The root directory \row \o temp() \o tempPath() \o The system's temporary directory \endtable The setCurrent() static function can also be used to set the application's working directory. If you want to find the directory containing the application's executable, see \l{QCoreApplication::applicationDirPath()}.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -