📄 kstddirs.cpp
字号:
/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*//* * Author: Stephan Kulow <coolo@kde.org> and Sirtaj Singh Kang <taj@kde.org> * Version: $Id: kstddirs.cpp,v 1.124.4.1 2001/09/21 18:10:47 waba Exp $ * 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/types.h>#include <dirent.h>#include <pwd.h>#include <qregexp.h>#include <qdict.h>#include <qdir.h>#include <qfileinfo.h>#include <qstring.h>#include <qstringlist.h>#include "kstddirs.h"#include "kconfig.h"#include "kdebug.h"#include "kinstance.h"#include <sys/param.h>#include <unistd.h>template class QDict<QStringList>;static const char* types[] = {"html", "icon", "apps", "sound", "data", "locale", "services", "mime", "servicetypes", "config", "exe", "wallpaper", "lib", "pixmap", "templates", "module", 0 };static int tokenize( QStringList& token, const QString& str, const QString& delim );KStandardDirs::KStandardDirs( ) : addedCustoms(false){ dircache.setAutoDelete(true); relatives.setAutoDelete(true); absolutes.setAutoDelete(true); addKDEDefaults();}KStandardDirs::~KStandardDirs(){}QStringList KStandardDirs::allTypes() const{ QStringList list; for (int i = 0; types[i] != 0; ++i) list.append(QString::fromLatin1(types[i])); return list;}void KStandardDirs::addPrefix( const QString& _dir ){ if (_dir.isNull()) return; QString dir = _dir; if (dir.at(dir.length() - 1) != '/') dir += '/'; if (!prefixes.contains(dir)) { prefixes.append(dir); dircache.clear(); }}QString KStandardDirs::kfsstnd_prefixes(){ return prefixes.join(":");}bool KStandardDirs::addResourceType( const char *type, const QString& relativename ){ if (relativename.isNull()) 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)) { rels->prepend(copy); dircache.remove(type); // clean the cache return true; } return false;}bool KStandardDirs::addResourceDir( const char *type, const QString& absdir){ 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)) { paths->append(copy); dircache.remove(type); // clean the cache return true; } return false;}QString KStandardDirs::findResource( const char *type, const QString& filename ) const{ if (filename.at(0) == '/') 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.isNull()) return dir; else return dir + filename;}static Q_UINT32 updateHash(const QString &file, Q_UINT32 hash){ QCString cFile = QFile::encodeName(file); struct stat buff; if ((access(cFile, R_OK) == 0) && (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 (filename.at(0) == '/') { // absolute dirs are absolute dirs, right? :-/ return updateHash(filename, hash); } 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{ QStringList list; checkConfig(); QStringList candidates = resourceDirs(type); QDir testdir; 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 QStringList candidates = resourceDirs(type); QString fullPath; for (QStringList::ConstIterator it = candidates.begin(); it != candidates.end(); it++) if (exists(*it + filename)) 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){ struct stat buff; if (access(QFile::encodeName(fullPath), R_OK) == 0 && 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 uniq){ QString pattern = regexp.pattern(); if (recursive || pattern.contains('?') || pattern.contains('*')) { // We look for a set of files. DIR *dp = opendir( QFile::encodeName(path)); if (!dp) return; assert(path.at(path.length() - 1) == '/'); struct dirent *ep; 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.match(fn) == -1)) continue; // No match QString pathfn = path + fn; if ( stat( QFile::encodeName(pathfn), &buff ) != 0 ) { kdDebug() << "Error stat'ing " << pathfn << perror << endl; continue; // Couldn't stat (Why not?) } if ( recursive ) { if ( S_ISDIR( buff.st_mode )) { lookupDirectory(pathfn + '/', relPart + fn + '/', regexp, list, relList, recursive, uniq); } if (regexp.match(fn) == -1) continue; // No match } if ( S_ISREG( buff.st_mode)) { if (!uniq || !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; struct stat buff; if ( stat( QFile::encodeName(pathfn), &buff ) != 0 ) return; // File not found if ( S_ISREG( buff.st_mode)) { if (!uniq || !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 uniq){ if (relpath.isNull()) { lookupDirectory(prefix, relPart, regexp, list, relList, recursive, uniq); return; } QString path; QString rest; if (relpath.length()) { int slash = relpath.find('/'); if (slash < 0) rest = relpath.left(relpath.length() - 1); else { path = relpath.left(slash); rest = relpath.mid(slash + 1); } } assert(prefix.at(prefix.length() - 1) == '/'); struct stat buff; if (path.contains('*') || path.contains('?')) { QRegExp pathExp(path, true, true); DIR *dp = opendir( QFile::encodeName(prefix) ); if (!dp) { return; } struct dirent *ep; while( ( ep = readdir( dp ) ) != 0L ) { QString fn( QFile::decodeName(ep->d_name)); if (fn == "." || fn == ".." || fn.at(fn.length() - 1) == '~') continue; if (pathExp.match(fn) == -1) continue; // No match QString rfn = relPart+fn; fn = prefix + fn; if ( stat( QFile::encodeName(fn), &buff ) != 0 ) { kdDebug() << "Error statting " << fn << perror << endl; continue; // Couldn't stat (Why not?) } if ( S_ISDIR( buff.st_mode )) lookupPrefix(fn + '/', rest, rfn + '/', regexp, list, relList, recursive, uniq); } closedir( dp ); } else { // Don't stat, if the dir doesn't exist we will find out // when we try to open it. lookupPrefix(prefix + path + '/', rest, relPart + path + '/', regexp, list, relList, recursive, uniq); }}QStringListKStandardDirs::findAllResources( const char *type, const QString& filter, bool recursive, bool uniq, QStringList &relList) const{ QStringList list; if (filter.at(0) == '/') // absolute paths we return { list.append( filter); return list; } QString filterPath; QString filterFile; if (filter.length()) { int slash = filter.findRev('/'); if (slash < 0) filterFile = filter; else { filterPath = filter.left(slash + 1); filterFile = filter.mid(slash + 1); } } checkConfig(); QStringList candidates = resourceDirs(type); if (filterFile.isEmpty()) filterFile = "*"; if (filterFile.find('*') || filterPath.find('*')) { QRegExp regExp(filterFile, true, true); for (QStringList::ConstIterator it = candidates.begin(); it != candidates.end(); it++) lookupPrefix(*it, filterPath, "", regExp, list, relList, recursive, uniq); } else { for (QStringList::ConstIterator it = candidates.begin(); it != candidates.end(); it++) { QString fullpath = *it + filter; if (exists(fullpath)) list.append(fullpath); } } return list;}QStringListKStandardDirs::findAllResources( const char *type, const QString& filter, bool recursive, bool uniq) const{ QStringList relList; return findAllResources(type, filter, recursive, uniq, relList);}static QString realPath(const QString &dirname){ static char realpath_buffer[MAXPATHLEN + 1]; /* If the path contains symlinks, get the real name */ if (realpath( QFile::encodeName(dirname), realpath_buffer) != 0) { // succes, use result from realpath int len = strlen(realpath_buffer); realpath_buffer[len] = '/'; realpath_buffer[len+1] = 0; return QFile::decodeName(realpath_buffer); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -