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 &regexp,			    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 &regexp,			 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 + -
显示快捷键?