/* * KFontInst - KDE Font Installer * * Copyright 2003-2007 Craig Drummond * * ---- * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "Misc.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace KFI { namespace Misc { QString prettyUrl(const KUrl &url) { QString u(url.prettyUrl()); u.replace("%20", " "); return u; } QString dirSyntax(const QString &d) { if(!d.isEmpty()) { QString ds(d); ds.replace("//", "/"); int slashPos(ds.lastIndexOf('/')); if(slashPos!=(((int)ds.length())-1)) ds.append('/'); return ds; } return d; } QString fileSyntax(const QString &d) { if(!d.isEmpty()) { QString ds(d); ds.replace("//", "/"); int slashPos(ds.lastIndexOf('/')); if(slashPos==(((int)ds.length())-1)) ds.remove(slashPos, 1); return ds; } return d; } QString getDir(const QString &f) { QString d(f); int slashPos(d.lastIndexOf('/')); if(slashPos!=-1) d.remove(slashPos+1, d.length()); return dirSyntax(d); } QString getFile(const QString &f) { QString d(f); int slashPos=d.lastIndexOf('/'); if(slashPos!=-1) d.remove(0, slashPos+1); return d; } bool createDir(const QString &dir) { // // Clear any umask before dir is created mode_t oldMask(umask(0000)); bool status(KStandardDirs::makeDir(dir, DIR_PERMS)); // Reset umask ::umask(oldMask); return status; } void setFilePerms(const QByteArray &f) { // // Clear any umask before setting file perms mode_t oldMask(umask(0000)); ::chmod(f.constData(), FILE_PERMS); // Reset umask ::umask(oldMask); } bool doCmd(const QString &cmd, const QString &p1, const QString &p2, const QString &p3) { QStringList args; if(!p1.isEmpty()) args << p1; if(!p2.isEmpty()) args << p2; if(!p3.isEmpty()) args << p3; return 0==QProcess::execute(cmd, args); } QString changeExt(const QString &f, const QString &newExt) { QString newStr(f); int dotPos(newStr.lastIndexOf('.')); if(-1==dotPos) newStr+=QChar('.')+newExt; else { newStr.remove(dotPos+1, newStr.length()); newStr+=newExt; } return newStr; } // // Get a list of files associated with a file, e.g.: // // File: /home/a/courier.pfa // // Associated: /home/a/courier.afm /home/a/courier.pfm // void getAssociatedFiles(const QString &path, QStringList &files, bool afmAndPfm) { QString ext(path); int dotPos(ext.lastIndexOf('.')); bool check(false); if(-1==dotPos) // Hmm, no extension - check anyway... check=true; else // Cool, got an extension - see if it is a Type1 font... { ext=ext.mid(dotPos+1); check=0==ext.compare("pfa", Qt::CaseInsensitive) || 0==ext.compare("pfb", Qt::CaseInsensitive); } if(check) { const char *afm[]={"afm", "AFM", "Afm", NULL}, *pfm[]={"pfm", "PFM", "Pfm", NULL}; bool gotAfm(false); int e; for(e=0; afm[e]; ++e) { QString statFile(changeExt(path, afm[e])); if(fExists(statFile)) { files.append(statFile); gotAfm=true; break; } } if(afmAndPfm || !gotAfm) for(e=0; pfm[e]; ++e) { QString statFile(changeExt(path, pfm[e])); if(fExists(statFile)) { files.append(statFile); break; } } } } time_t getTimeStamp(const QString &item) { KDE_struct_stat info; return !item.isEmpty() && 0==KDE_lstat(QFile::encodeName(item), &info) ? info.st_mtime : 0; } bool check(const QString &path, bool file, bool checkW) { KDE_struct_stat info; QByteArray pathC(QFile::encodeName(path)); return 0==KDE_lstat(pathC, &info) && (file ? (S_ISREG(info.st_mode) || S_ISLNK(info.st_mode)) : S_ISDIR(info.st_mode)) && (!checkW || 0==::access(pathC, W_OK)); } QString getFolder(const QString &defaultDir, const QString &root, QStringList &dirs) { if(dirs.contains(defaultDir)) return defaultDir; else { QStringList::const_iterator it, end=dirs.constEnd(); bool found=false; for(it=dirs.constBegin(); it!=end && !found; ++it) if(0==(*it).indexOf(root)) return *it; } return defaultDir; } bool checkExt(const QString &fname, const QString &ext) { QString extension('.'+ext); return fname.length()>extension.length() ? 0==fname.mid(fname.length()-extension.length()).compare(extension, Qt::CaseInsensitive) : false; } bool isBitmap(const QString &str) { return checkExt(str, "pcf") || checkExt(str, "bdf") || checkExt(str, "pcf.gz") || checkExt(str, "bdf.gz"); } bool isMetrics(const QString &str) { return checkExt(str, "afm") || checkExt(str, "pfm"); } int getIntQueryVal(const KUrl &url, const char *key, int defVal) { QString item(url.queryItem(key)); int val(defVal); if(!item.isNull()) val=item.toInt(); return val; } bool printable(const QString &mime) { return "application/x-font-type1"==mime || "application/x-font-ttf"==mime || "application/x-font-otf"==mime || "application/x-font-type1"==mime; } uint qHash(const KFI::Misc::TFont &key) { //return qHash(QString(key.family+'%'+QString().setNum(key.styleInfo, 16))); const QChar *p = key.family.unicode(); int n = key.family.size(); uint h = 0, g; h = (h << 4) + key.styleInfo; if ((g = (h & 0xf0000000)) != 0) h ^= g >> 23; h &= ~g; while (n--) { h = (h << 4) + (*p++).unicode(); if ((g = (h & 0xf0000000)) != 0) h ^= g >> 23; h &= ~g; } return h; } // Taken from qdom.cpp QString encodeText(const QString &str, QTextStream &s) { const QTextCodec *const codec = s.codec(); Q_ASSERT(codec); QString retval(str); int len = retval.length(), i = 0; while (i < len) { const QChar ati(retval.at(i)); if (ati == QLatin1Char('<')) { retval.replace(i, 1, QLatin1String("<")); len += 3; i += 4; } else if (ati == QLatin1Char('"')) { retval.replace(i, 1, QLatin1String(""")); len += 5; i += 6; } else if (ati == QLatin1Char('&')) { retval.replace(i, 1, QLatin1String("&")); len += 4; i += 5; } else if (ati == QLatin1Char('>') && i >= 2 && retval[i - 1] == QLatin1Char(']') && retval[i - 2] == QLatin1Char(']')) { retval.replace(i, 1, QLatin1String(">")); len += 3; i += 4; } else { if(codec->canEncode(ati)) ++i; else { // We have to use a character reference to get it through. const ushort codepoint(ati.unicode()); const QString replacement(QLatin1String("&#x") + QString::number(codepoint, 16) + QLatin1Char(';')); retval.replace(i, 1, replacement); i += replacement.length(); len += replacement.length() - 1; } } } return retval; } QString contractHome(QString path) { if (!path.isEmpty() && '/'==path[0]) { QString home(QDir::homePath()); if(path.startsWith(home)) { int len = home.length(); if(len>1 && (path.length() == len || path[len] == '/')) return path.replace(0, len, QString::fromLatin1("~")); } } return path; } QString expandHome(QString path) { if(!path.isEmpty() && '~'==path[0]) return 1==path.length() ? QDir::homePath() : path.replace(0, 1, QDir::homePath()); return path; } QMap getFontFileMap(const QSet &files) { QMap map; QSet::ConstIterator it=files.constBegin(), end=files.constEnd(); QMap > fontsFiles; for(;it!=end; ++it) fontsFiles[unhide(getFile(*it))].insert(getDir(*it)); QMap >::ConstIterator fIt(fontsFiles.constBegin()), fEnd(fontsFiles.constEnd()); for(; fIt!=fEnd; ++fIt) if(fIt.value().count()>1) { QVector orig(fIt.value().count()), modified(fIt.value().count()); QSet::ConstIterator oIt(fIt.value().constBegin()), oEnd(fIt.value().constEnd()); bool good=true; int count=fIt.value().count(); for(int i=0; i apps; if(!apps.contains(name)) apps[name]=KStandardDirs::findExe(name, path ? KStandardDirs::installPath(path) : QString()); return apps[name]; } } // Misc:: } // KFI::