~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to kcontrol/kfontinst/lib/Misc.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * KFontInst - KDE Font Installer
 
3
 *
 
4
 * Copyright 2003-2007 Craig Drummond <craig@kde.org>
 
5
 *
 
6
 * ----
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation; either version 2 of the License, or
 
11
 * (at your option) any later version.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
 * General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License
 
19
 * along with this program; see the file COPYING.  If not, write to
 
20
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
21
 * Boston, MA 02110-1301, USA.
 
22
 */
 
23
 
 
24
#include "Misc.h"
 
25
#include <QtCore/QSet>
 
26
#include <QtCore/QMap>
 
27
#include <QtCore/QVector>
 
28
#include <QtCore/QDir>
 
29
#include <QtCore/QFile>
 
30
#include <QtCore/QByteArray>
 
31
#include <QtCore/QTextCodec>
 
32
#include <QtCore/QTextStream>
 
33
#include <QtCore/QProcess>
 
34
#include <QtCore/QTemporaryFile>
 
35
#include <KDE/KStandardDirs>
 
36
#include <kde_file.h>
 
37
#include <unistd.h>
 
38
#include <ctype.h>
 
39
 
 
40
namespace KFI
 
41
{
 
42
 
 
43
namespace Misc
 
44
{
 
45
 
 
46
QString prettyUrl(const KUrl &url)
 
47
{
 
48
    QString u(url.prettyUrl());
 
49
 
 
50
    u.replace("%20", " ");
 
51
    return u;
 
52
}
 
53
 
 
54
QString dirSyntax(const QString &d)
 
55
{
 
56
    if(!d.isEmpty())
 
57
    {
 
58
        QString ds(d);
 
59
 
 
60
        ds.replace("//", "/");
 
61
 
 
62
        int slashPos(ds.lastIndexOf('/'));
 
63
 
 
64
        if(slashPos!=(((int)ds.length())-1))
 
65
            ds.append('/');
 
66
 
 
67
        return ds;
 
68
    }
 
69
 
 
70
    return d;
 
71
}
 
72
 
 
73
QString fileSyntax(const QString &d)
 
74
{
 
75
    if(!d.isEmpty())
 
76
    {
 
77
        QString ds(d);
 
78
 
 
79
        ds.replace("//", "/");
 
80
 
 
81
        int slashPos(ds.lastIndexOf('/'));
 
82
 
 
83
        if(slashPos==(((int)ds.length())-1))
 
84
            ds.remove(slashPos, 1);
 
85
        return ds;
 
86
    }
 
87
 
 
88
    return d;
 
89
}
 
90
 
 
91
QString getDir(const QString &f)
 
92
{
 
93
    QString d(f);
 
94
 
 
95
    int slashPos(d.lastIndexOf('/'));
 
96
 
 
97
    if(slashPos!=-1)
 
98
        d.remove(slashPos+1, d.length());
 
99
 
 
100
    return dirSyntax(d);
 
101
}
 
102
 
 
103
QString getFile(const QString &f)
 
104
{
 
105
    QString d(f);
 
106
 
 
107
    int slashPos=d.lastIndexOf('/');
 
108
 
 
109
    if(slashPos!=-1)
 
110
        d.remove(0, slashPos+1);
 
111
 
 
112
    return d;
 
113
}
 
114
 
 
115
bool createDir(const QString &dir)
 
116
{
 
117
    //
 
118
    // Clear any umask before dir is created
 
119
    mode_t oldMask(umask(0000));
 
120
    bool   status(KStandardDirs::makeDir(dir, DIR_PERMS));
 
121
    // Reset umask
 
122
    ::umask(oldMask);
 
123
    return status;
 
124
}
 
125
 
 
126
void setFilePerms(const QByteArray &f)
 
127
{
 
128
    //
 
129
    // Clear any umask before setting file perms
 
130
    mode_t oldMask(umask(0000));
 
131
    ::chmod(f.constData(), FILE_PERMS);
 
132
    // Reset umask
 
133
    ::umask(oldMask);
 
134
}
 
135
 
 
136
bool doCmd(const QString &cmd, const QString &p1, const QString &p2, const QString &p3)
 
137
{
 
138
    QStringList args;
 
139
 
 
140
    if(!p1.isEmpty())
 
141
        args << p1;
 
142
    if(!p2.isEmpty())
 
143
        args << p2;
 
144
    if(!p3.isEmpty())
 
145
        args << p3;
 
146
 
 
147
    return 0==QProcess::execute(cmd, args);
 
148
}
 
149
 
 
150
QString changeExt(const QString &f, const QString &newExt)
 
151
{
 
152
    QString newStr(f);
 
153
    int     dotPos(newStr.lastIndexOf('.'));
 
154
 
 
155
    if(-1==dotPos)
 
156
        newStr+=QChar('.')+newExt;
 
157
    else
 
158
    {
 
159
        newStr.remove(dotPos+1, newStr.length());
 
160
        newStr+=newExt;
 
161
    }
 
162
    return newStr;
 
163
}
 
164
 
 
165
//
 
166
// Get a list of files associated with a file, e.g.:
 
167
//
 
168
//    File: /home/a/courier.pfa
 
169
//
 
170
//    Associated: /home/a/courier.afm /home/a/courier.pfm
 
171
//
 
172
void getAssociatedFiles(const QString &path, QStringList &files, bool afmAndPfm)
 
173
{
 
174
    QString ext(path);
 
175
    int     dotPos(ext.lastIndexOf('.'));
 
176
    bool    check(false);
 
177
 
 
178
    if(-1==dotPos) // Hmm, no extension - check anyway...
 
179
        check=true;
 
180
    else           // Cool, got an extension - see if it is a Type1 font...
 
181
    {
 
182
        ext=ext.mid(dotPos+1);
 
183
        check=0==ext.compare("pfa", Qt::CaseInsensitive) ||
 
184
              0==ext.compare("pfb", Qt::CaseInsensitive);
 
185
    }
 
186
 
 
187
    if(check)
 
188
    {
 
189
        const char *afm[]={"afm", "AFM", "Afm", NULL},
 
190
                   *pfm[]={"pfm", "PFM", "Pfm", NULL};
 
191
        bool       gotAfm(false);
 
192
        int        e;
 
193
 
 
194
        for(e=0; afm[e]; ++e)
 
195
        {
 
196
            QString statFile(changeExt(path, afm[e]));
 
197
 
 
198
            if(fExists(statFile))
 
199
            {
 
200
                files.append(statFile);
 
201
                gotAfm=true;
 
202
                break;
 
203
            }
 
204
        }
 
205
 
 
206
        if(afmAndPfm || !gotAfm)
 
207
            for(e=0; pfm[e]; ++e)
 
208
            {
 
209
                QString statFile(changeExt(path, pfm[e]));
 
210
 
 
211
                if(fExists(statFile))
 
212
                {
 
213
                    files.append(statFile);
 
214
                    break;
 
215
                }
 
216
            }
 
217
    }
 
218
}
 
219
 
 
220
time_t getTimeStamp(const QString &item)
 
221
{
 
222
    KDE_struct_stat info;
 
223
 
 
224
    return !item.isEmpty() && 0==KDE_lstat(QFile::encodeName(item), &info) ? info.st_mtime : 0;
 
225
}
 
226
 
 
227
 
 
228
bool check(const QString &path, bool file, bool checkW)
 
229
 
230
    KDE_struct_stat info;
 
231
    QByteArray      pathC(QFile::encodeName(path));
 
232
 
 
233
    return 0==KDE_lstat(pathC, &info) &&
 
234
           (file ? (S_ISREG(info.st_mode) || S_ISLNK(info.st_mode))
 
235
                 : S_ISDIR(info.st_mode)) &&
 
236
           (!checkW || 0==::access(pathC, W_OK));
 
237
}
 
238
 
 
239
QString getFolder(const QString &defaultDir, const QString &root, QStringList &dirs)
 
240
{
 
241
    if(dirs.contains(defaultDir))
 
242
        return defaultDir;
 
243
    else
 
244
    {
 
245
        QStringList::const_iterator it,
 
246
                              end=dirs.constEnd();
 
247
        bool                  found=false;
 
248
 
 
249
        for(it=dirs.constBegin(); it!=end && !found; ++it)
 
250
            if(0==(*it).indexOf(root))
 
251
                return *it;
 
252
    }
 
253
 
 
254
    return defaultDir;
 
255
}
 
256
 
 
257
bool checkExt(const QString &fname, const QString &ext)
 
258
{
 
259
    QString extension('.'+ext);
 
260
 
 
261
    return fname.length()>extension.length()
 
262
            ? 0==fname.mid(fname.length()-extension.length()).compare(extension, Qt::CaseInsensitive)
 
263
            : false;
 
264
}
 
265
 
 
266
bool isBitmap(const QString &str)
 
267
{
 
268
    return checkExt(str, "pcf") || checkExt(str, "bdf") || checkExt(str, "pcf.gz") || checkExt(str, "bdf.gz");
 
269
}
 
270
 
 
271
bool isMetrics(const QString &str)
 
272
{
 
273
    return checkExt(str, "afm") || checkExt(str, "pfm");
 
274
}
 
275
 
 
276
int getIntQueryVal(const KUrl &url, const char *key, int defVal)
 
277
{
 
278
    QString item(url.queryItem(key));
 
279
    int     val(defVal);
 
280
 
 
281
    if(!item.isNull())
 
282
        val=item.toInt();
 
283
 
 
284
    return val;
 
285
}
 
286
 
 
287
bool printable(const QString &mime)
 
288
{
 
289
    return "application/x-font-type1"==mime || "application/x-font-ttf"==mime ||
 
290
           "application/x-font-otf"==mime || "application/x-font-type1"==mime;
 
291
}
 
292
 
 
293
uint qHash(const KFI::Misc::TFont &key)
 
294
{
 
295
    //return qHash(QString(key.family+'%'+QString().setNum(key.styleInfo, 16)));
 
296
    const QChar *p = key.family.unicode();
 
297
    int         n = key.family.size();
 
298
    uint        h = 0,
 
299
                g;
 
300
 
 
301
    h = (h << 4) + key.styleInfo;
 
302
    if ((g = (h & 0xf0000000)) != 0)
 
303
        h ^= g >> 23;
 
304
    h &= ~g;
 
305
 
 
306
    while (n--)
 
307
    {
 
308
        h = (h << 4) + (*p++).unicode();
 
309
        if ((g = (h & 0xf0000000)) != 0)
 
310
            h ^= g >> 23;
 
311
        h &= ~g;
 
312
    }
 
313
    return h;
 
314
}
 
315
 
 
316
// Taken from qdom.cpp
 
317
QString encodeText(const QString &str, QTextStream &s)
 
318
{
 
319
    const QTextCodec *const codec = s.codec();
 
320
 
 
321
    Q_ASSERT(codec);
 
322
 
 
323
    QString retval(str);
 
324
    int     len = retval.length(),
 
325
            i = 0;
 
326
 
 
327
    while (i < len)
 
328
    {
 
329
        const QChar ati(retval.at(i));
 
330
 
 
331
        if (ati == QLatin1Char('<'))
 
332
        {
 
333
            retval.replace(i, 1, QLatin1String("&lt;"));
 
334
            len += 3;
 
335
            i += 4;
 
336
        }
 
337
        else if (ati == QLatin1Char('"'))
 
338
        {
 
339
            retval.replace(i, 1, QLatin1String("&quot;"));
 
340
            len += 5;
 
341
            i += 6;
 
342
        }
 
343
        else if (ati == QLatin1Char('&'))
 
344
        {
 
345
            retval.replace(i, 1, QLatin1String("&amp;"));
 
346
            len += 4;
 
347
            i += 5;
 
348
        }
 
349
        else if (ati == QLatin1Char('>') && i >= 2 && retval[i - 1] == QLatin1Char(']') && retval[i - 2] == QLatin1Char(']'))
 
350
        {
 
351
            retval.replace(i, 1, QLatin1String("&gt;"));
 
352
            len += 3;
 
353
            i += 4;
 
354
        }
 
355
        else
 
356
        {
 
357
            if(codec->canEncode(ati))
 
358
                ++i;
 
359
            else
 
360
            {
 
361
                // We have to use a character reference to get it through.
 
362
                const ushort codepoint(ati.unicode());
 
363
                const QString replacement(QLatin1String("&#x") + QString::number(codepoint, 16) + QLatin1Char(';'));
 
364
                retval.replace(i, 1, replacement);
 
365
                i += replacement.length();
 
366
                len += replacement.length() - 1;
 
367
            }
 
368
        }
 
369
    }
 
370
 
 
371
    return retval;
 
372
}
 
373
 
 
374
QString contractHome(QString path)
 
375
{
 
376
    if (!path.isEmpty() && '/'==path[0])
 
377
    {
 
378
        QString home(QDir::homePath());
 
379
 
 
380
        if(path.startsWith(home))
 
381
        {
 
382
            int len = home.length();
 
383
 
 
384
            if(len>1 && (path.length() == len || path[len] == '/'))
 
385
                return path.replace(0, len, QString::fromLatin1("~"));
 
386
        }
 
387
    }
 
388
 
 
389
    return path;
 
390
}
 
391
 
 
392
QString expandHome(QString path)
 
393
{
 
394
    if(!path.isEmpty() && '~'==path[0])
 
395
        return 1==path.length() ? QDir::homePath() : path.replace(0, 1, QDir::homePath());
 
396
 
 
397
    return path;
 
398
}
 
399
 
 
400
QMap<QString, QString> getFontFileMap(const QSet<QString> &files)
 
401
{
 
402
    QMap<QString, QString>        map;
 
403
    QSet<QString>::ConstIterator  it=files.constBegin(),
 
404
                                  end=files.constEnd();
 
405
    QMap<QString, QSet<QString> > fontsFiles;
 
406
 
 
407
    for(;it!=end; ++it)
 
408
        fontsFiles[unhide(getFile(*it))].insert(getDir(*it));
 
409
 
 
410
    QMap<QString, QSet<QString> >::ConstIterator fIt(fontsFiles.constBegin()),
 
411
                                                 fEnd(fontsFiles.constEnd());
 
412
 
 
413
    for(; fIt!=fEnd; ++fIt)
 
414
        if(fIt.value().count()>1)
 
415
        {
 
416
            QVector<QString>             orig(fIt.value().count()),
 
417
                                         modified(fIt.value().count());
 
418
            QSet<QString>::ConstIterator oIt(fIt.value().constBegin()),
 
419
                                         oEnd(fIt.value().constEnd());
 
420
            bool                         good=true;
 
421
            int                          count=fIt.value().count();
 
422
 
 
423
            for(int i=0;  i<count && good; ++i, ++oIt)
 
424
                orig[i]=modified[i]=*oIt;
 
425
            
 
426
            while(good)
 
427
            {
 
428
                int end=modified[0].indexOf('/', 1);
 
429
                
 
430
                if(-1!=end)
 
431
                {
 
432
                    QString dir=modified[0].left(end);
 
433
                
 
434
                    for(int i=1;  i<count && good; ++i)
 
435
                        if(0!=modified[i].indexOf(dir))
 
436
                            good=false;
 
437
                    if(good)
 
438
                        for(int i=0;  i<count && good; ++i)
 
439
                            modified[i]=modified[i].remove(0, dir.length());
 
440
                }
 
441
                else
 
442
                    good=false;
 
443
            }
 
444
            for(int i=0;  i<count; ++i)
 
445
                map[getDir(modified[i]).mid(1)+fIt.key()]=fExists(orig[i]+fIt.key())
 
446
                                                                    ? orig[i]+fIt.key()
 
447
                                                                    : orig[i]+hide(fIt.key());
 
448
        }
 
449
        else // Only 1 entry! :-)
 
450
            map[unhide(fIt.key())]=fExists((*fIt.value().begin())+fIt.key())
 
451
                                    ? (*fIt.value().begin())+fIt.key()
 
452
                                    : (*fIt.value().begin())+hide(fIt.key());
 
453
 
 
454
    return map;
 
455
}
 
456
 
 
457
} // Misc::
 
458
 
 
459
} // KFI::