kstandarddirs.cpp
来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 1,677 行 · 第 1/3 页
CPP
1,677 行
/* This file is part of the KDE libraries Copyright (C) 1999 Sirtaj Singh Kang <taj@kde.org> Copyright (C) 1999 Stephan Kulow <coolo@kde.org> Copyright (C) 1999 Waldo Bastian <bastian@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*//* * Author: Stephan Kulow <coolo@kde.org> and Sirtaj Singh Kang <taj@kde.org> * Version: $Id: kstandarddirs.cpp 465272 2005-09-29 09:47:40Z mueller $ * Generated: Thu Mar 5 16:05:28 EST 1998 */#include "config.h"#include <stdlib.h>#include <assert.h>#include <errno.h>#ifdef HAVE_SYS_STAT_H#include <sys/stat.h>#endif#include <sys/param.h>#include <sys/types.h>#include <dirent.h>#include <pwd.h>#include <grp.h>#include <qregexp.h>#include <qasciidict.h>#include <qdict.h>#include <qdir.h>#include <qfileinfo.h>#include <qstring.h>#include <qstringlist.h>#include "kstandarddirs.h"#include "kconfig.h"#include "kdebug.h"#include "kinstance.h"#include "kshell.h"#include "ksimpleconfig.h"#include "kuser.h"#include "kstaticdeleter.h"#include <kde_file.h>template class QDict<QStringList>;class KStandardDirs::KStandardDirsPrivate{public: KStandardDirsPrivate() : restrictionsActive(false), dataRestrictionActive(false), checkRestrictions(true) { } bool restrictionsActive; bool dataRestrictionActive; bool checkRestrictions; QAsciiDict<bool> restrictions; QStringList xdgdata_prefixes; QStringList xdgconf_prefixes;};// Singleton, with data shared by all kstandarddirs instances.// Used in static methods like findExe()class KStandardDirsSingleton{public: QString defaultprefix; QString defaultbindir; static KStandardDirsSingleton* self();private: static KStandardDirsSingleton* s_self;};static KStaticDeleter<KStandardDirsSingleton> kstds_sd;KStandardDirsSingleton* KStandardDirsSingleton::s_self = 0;KStandardDirsSingleton* KStandardDirsSingleton::self() { if ( !s_self ) kstds_sd.setObject( s_self, new KStandardDirsSingleton ); return s_self;}static const char* const types[] = {"html", "icon", "apps", "sound", "data", "locale", "services", "mime", "servicetypes", "config", "exe", "wallpaper", "lib", "pixmap", "templates", "module", "qtplugins", "xdgdata-apps", "xdgdata-dirs", "xdgconf-menu", "kcfg", "emoticons", 0 };static int tokenize( QStringList& token, const QString& str, const QString& delim );KStandardDirs::KStandardDirs( ) : addedCustoms(false){ d = new KStandardDirsPrivate; dircache.setAutoDelete(true); relatives.setAutoDelete(true); absolutes.setAutoDelete(true); savelocations.setAutoDelete(true); addKDEDefaults();}KStandardDirs::~KStandardDirs(){ delete d;}bool KStandardDirs::isRestrictedResource(const char *type, const QString& relPath) const{ if (!d || !d->restrictionsActive) return false; if (d->restrictions[type]) return true; if (strcmp(type, "data")==0) { applyDataRestrictions(relPath); if (d->dataRestrictionActive) { d->dataRestrictionActive = false; return true; } } return false;}void KStandardDirs::applyDataRestrictions(const QString &relPath) const{ QString key; int i = relPath.find('/'); if (i != -1) key = "data_"+relPath.left(i); else key = "data_"+relPath; if (d && d->restrictions[key.latin1()]) d->dataRestrictionActive = true;}QStringList KStandardDirs::allTypes() const{ QStringList list; for (int i = 0; types[i] != 0; ++i) list.append(QString::fromLatin1(types[i])); return list;}static void priorityAdd(QStringList &prefixes, const QString& dir, bool priority){ if (priority && !prefixes.isEmpty()) { // Add in front but behind $KDEHOME QStringList::iterator it = prefixes.begin(); it++; prefixes.insert(it, 1, dir); } else { prefixes.append(dir); }}void KStandardDirs::addPrefix( const QString& _dir ){ addPrefix(_dir, false);}void KStandardDirs::addPrefix( const QString& _dir, bool priority ){ if (_dir.isEmpty()) return; QString dir = _dir; if (dir.at(dir.length() - 1) != '/') dir += '/'; if (!prefixes.contains(dir)) { priorityAdd(prefixes, dir, priority); dircache.clear(); }}void KStandardDirs::addXdgConfigPrefix( const QString& _dir ){ addXdgConfigPrefix(_dir, false);}void KStandardDirs::addXdgConfigPrefix( const QString& _dir, bool priority ){ if (_dir.isEmpty()) return; QString dir = _dir; if (dir.at(dir.length() - 1) != '/') dir += '/'; if (!d->xdgconf_prefixes.contains(dir)) { priorityAdd(d->xdgconf_prefixes, dir, priority); dircache.clear(); }}void KStandardDirs::addXdgDataPrefix( const QString& _dir ){ addXdgDataPrefix(_dir, false);}void KStandardDirs::addXdgDataPrefix( const QString& _dir, bool priority ){ if (_dir.isEmpty()) return; QString dir = _dir; if (dir.at(dir.length() - 1) != '/') dir += '/'; if (!d->xdgdata_prefixes.contains(dir)) { priorityAdd(d->xdgdata_prefixes, dir, priority); dircache.clear(); }}QString KStandardDirs::kfsstnd_prefixes(){ return prefixes.join(QChar(KPATH_SEPARATOR));}QString KStandardDirs::kfsstnd_xdg_conf_prefixes(){ return d->xdgconf_prefixes.join(QChar(KPATH_SEPARATOR));}QString KStandardDirs::kfsstnd_xdg_data_prefixes(){ return d->xdgdata_prefixes.join(QChar(KPATH_SEPARATOR));}bool KStandardDirs::addResourceType( const char *type, const QString& relativename ){ return addResourceType(type, relativename, true);}bool KStandardDirs::addResourceType( const char *type, const QString& relativename, bool priority ){ if (relativename.isEmpty()) return false; QStringList *rels = relatives.find(type); if (!rels) { rels = new QStringList(); relatives.insert(type, rels); } QString copy = relativename; if (copy.at(copy.length() - 1) != '/') copy += '/'; if (!rels->contains(copy)) { if (priority) rels->prepend(copy); else rels->append(copy); dircache.remove(type); // clean the cache return true; } return false;}bool KStandardDirs::addResourceDir( const char *type, const QString& absdir){ // KDE4: change priority to bring in line with addResourceType return addResourceDir(type, absdir, false);}bool KStandardDirs::addResourceDir( const char *type, const QString& absdir, bool priority){ QStringList *paths = absolutes.find(type); if (!paths) { paths = new QStringList(); absolutes.insert(type, paths); } QString copy = absdir; if (copy.at(copy.length() - 1) != '/') copy += '/'; if (!paths->contains(copy)) { if (priority) paths->prepend(copy); else paths->append(copy); dircache.remove(type); // clean the cache return true; } return false;}QString KStandardDirs::findResource( const char *type, const QString& filename ) const{ if (!QDir::isRelativePath(filename)) return filename; // absolute dirs are absolute dirs, right? :-/#if 0kdDebug() << "Find resource: " << type << endl;for (QStringList::ConstIterator pit = prefixes.begin(); pit != prefixes.end(); pit++){ kdDebug() << "Prefix: " << *pit << endl;}#endif QString dir = findResourceDir(type, filename); if (dir.isEmpty()) return dir; else return dir + filename;}static Q_UINT32 updateHash(const QString &file, Q_UINT32 hash){ QCString cFile = QFile::encodeName(file); KDE_struct_stat buff; if ((access(cFile, R_OK) == 0) && (KDE_stat( cFile, &buff ) == 0) && (S_ISREG( buff.st_mode ))) { hash = hash + (Q_UINT32) buff.st_ctime; } return hash;}Q_UINT32 KStandardDirs::calcResourceHash( const char *type, const QString& filename, bool deep) const{ Q_UINT32 hash = 0; if (!QDir::isRelativePath(filename)) { // absolute dirs are absolute dirs, right? :-/ return updateHash(filename, hash); } if (d && d->restrictionsActive && (strcmp(type, "data")==0)) applyDataRestrictions(filename); QStringList candidates = resourceDirs(type); QString fullPath; for (QStringList::ConstIterator it = candidates.begin(); it != candidates.end(); ++it) { hash = updateHash(*it + filename, hash); if (!deep && hash) return hash; } return hash;}QStringList KStandardDirs::findDirs( const char *type, const QString& reldir ) const{ QDir testdir; QStringList list; if (!QDir::isRelativePath(reldir)) { testdir.setPath(reldir); if (testdir.exists()) { if (reldir.endsWith("/")) list.append(reldir); else list.append(reldir+'/'); } return list; } checkConfig(); if (d && d->restrictionsActive && (strcmp(type, "data")==0)) applyDataRestrictions(reldir); QStringList candidates = resourceDirs(type); for (QStringList::ConstIterator it = candidates.begin(); it != candidates.end(); ++it) { testdir.setPath(*it + reldir); if (testdir.exists()) list.append(testdir.absPath() + '/'); } return list;}QString KStandardDirs::findResourceDir( const char *type, const QString& filename) const{#ifndef NDEBUG if (filename.isEmpty()) { kdWarning() << "filename for type " << type << " in KStandardDirs::findResourceDir is not supposed to be empty!!" << endl; return QString::null; }#endif if (d && d->restrictionsActive && (strcmp(type, "data")==0)) applyDataRestrictions(filename); QStringList candidates = resourceDirs(type); QString fullPath; for (QStringList::ConstIterator it = candidates.begin(); it != candidates.end(); ++it) { if (exists(*it + filename)) {#ifdef Q_WS_WIN //this ensures we're using installed .la files if ((*it).isEmpty() && filename.right(3)==".la") {#ifndef NDEBUG kdDebug() << "KStandardDirs::findResourceDir() found .la in cwd: skipping. (fname=" << filename << ")" << endl;#endif continue; }#endif //Q_WS_WIN return *it; } }#ifndef NDEBUG if(false && type != "locale") kdDebug() << "KStdDirs::findResDir(): can't find \"" << filename << "\" in type \"" << type << "\"." << endl;#endif return QString::null;}bool KStandardDirs::exists(const QString &fullPath){ KDE_struct_stat buff; if (access(QFile::encodeName(fullPath), R_OK) == 0 && KDE_stat( QFile::encodeName(fullPath), &buff ) == 0) if (fullPath.at(fullPath.length() - 1) != '/') { if (S_ISREG( buff.st_mode )) return true; } else if (S_ISDIR( buff.st_mode )) return true; return false;}static void lookupDirectory(const QString& path, const QString &relPart, const QRegExp ®exp, QStringList& list, QStringList& relList, bool recursive, bool unique){ QString pattern = regexp.pattern(); if (recursive || pattern.contains('?') || pattern.contains('*')) { if (path.isEmpty()) //for sanity return; // We look for a set of files. DIR *dp = opendir( QFile::encodeName(path)); if (!dp) return;#ifdef Q_WS_WIN assert(path.at(path.length() - 1) == '/' || path.at(path.length() - 1) == '\\');#else assert(path.at(path.length() - 1) == '/');#endif struct dirent *ep; KDE_struct_stat buff; QString _dot("."); QString _dotdot(".."); while( ( ep = readdir( dp ) ) != 0L ) { QString fn( QFile::decodeName(ep->d_name)); if (fn == _dot || fn == _dotdot || fn.at(fn.length() - 1).latin1() == '~') continue; if (!recursive && !regexp.exactMatch(fn)) continue; // No match QString pathfn = path + fn; if ( KDE_stat( QFile::encodeName(pathfn), &buff ) != 0 ) { kdDebug() << "Error stat'ing " << pathfn << " : " << perror << endl; continue; // Couldn't stat (e.g. no read permissions) } if ( recursive ) { if ( S_ISDIR( buff.st_mode )) { lookupDirectory(pathfn + '/', relPart + fn + '/', regexp, list, relList, recursive, unique); } if (!regexp.exactMatch(fn)) continue; // No match } if ( S_ISREG( buff.st_mode)) { if (!unique || !relList.contains(relPart + fn)) { list.append( pathfn ); relList.append( relPart + fn ); } } } closedir( dp ); } else { // We look for a single file. QString fn = pattern; QString pathfn = path + fn; KDE_struct_stat buff; if ( KDE_stat( QFile::encodeName(pathfn), &buff ) != 0 ) return; // File not found if ( S_ISREG( buff.st_mode)) { if (!unique || !relList.contains(relPart + fn)) { list.append( pathfn ); relList.append( relPart + fn ); } } }}static void lookupPrefix(const QString& prefix, const QString& relpath, const QString& relPart, const QRegExp ®exp, QStringList& list, QStringList& relList, bool recursive, bool unique){ if (relpath.isEmpty()) { lookupDirectory(prefix, relPart, regexp, list, relList, recursive, unique); return; } QString path; QString rest; if (relpath.length()) { int slash = relpath.find('/');
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?