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

« back to all changes in this revision

Viewing changes to kcontrol/kfontinst/dbus/Folder.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-2009 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 <QtCore/QDir>
 
25
#include <QtCore/QFile>
 
26
#include <QtCore/QCoreApplication>
 
27
#include <QtCore/QTextStream>
 
28
#include <QtCore/QProcess>
 
29
#include <QtXml/QDomDocument>
 
30
#include <QtXml/QDomElement>
 
31
#include <QtXml/QDomNode>
 
32
#include <KDE/KStandardDirs>
 
33
#include <KDE/KSaveFile>
 
34
#include <KDE/KShell>
 
35
#include <KDE/KDebug>
 
36
#include <fontconfig/fontconfig.h>
 
37
#include "Folder.h"
 
38
#include "FcConfig.h"
 
39
#include "Misc.h"
 
40
#include "KfiConstants.h"
 
41
#include "XmlStrings.h"
 
42
#include "Style.h"
 
43
#include "File.h"
 
44
#include "config-fontinst.h"
 
45
 
 
46
#define DISABLED_FONTS "disabledfonts"
 
47
#define KFI_DBUG kDebug() << time(0L)
 
48
 
 
49
namespace KFI
 
50
{
 
51
 
 
52
bool Folder::CfgFile::modified()
 
53
{
 
54
    return timestamp!=Misc::getTimeStamp(name);
 
55
}
 
56
 
 
57
void Folder::CfgFile::updateTimeStamp()
 
58
{
 
59
    timestamp=Misc::getTimeStamp(name);
 
60
}
 
61
 
 
62
Folder::~Folder()
 
63
{
 
64
    saveDisabled();
 
65
}
 
66
 
 
67
void Folder::init(bool system, bool systemBus)
 
68
{
 
69
    itsIsSystem=system;
 
70
    if(!system)
 
71
    {
 
72
        FcStrList   *list=FcConfigGetFontDirs(FcInitLoadConfigAndFonts());
 
73
        QStringList dirs;
 
74
        FcChar8     *fcDir;
 
75
 
 
76
        while((fcDir=FcStrListNext(list)))
 
77
            dirs.append(Misc::dirSyntax((const char *)fcDir));
 
78
    
 
79
        itsLocation=Misc::getFolder(Misc::dirSyntax(QDir::homePath()+"/.fonts/"), Misc::dirSyntax(QDir::homePath()), dirs);
 
80
    }
 
81
    else
 
82
        itsLocation=KFI_DEFAULT_SYS_FONTS_FOLDER;
 
83
 
 
84
    if((!system && !systemBus) || (system && systemBus))
 
85
        FcConfig::addDir(itsLocation, system);
 
86
 
 
87
    itsDisabledCfg.dirty=false;
 
88
    if(itsDisabledCfg.name.isEmpty())
 
89
    {
 
90
        QString fileName("/"DISABLED_FONTS".xml");
 
91
 
 
92
        if(system)
 
93
            itsDisabledCfg.name=QString::fromLatin1(KFI_ROOT_CFG_DIR)+fileName;
 
94
        else
 
95
        {
 
96
            QString path=KGlobal::dirs()->localxdgconfdir();
 
97
 
 
98
            if(!Misc::dExists(path))
 
99
                Misc::createDir(path);
 
100
            itsDisabledCfg.name=path+fileName;
 
101
        }
 
102
        itsDisabledCfg.timestamp=0;
 
103
    }
 
104
}
 
105
 
 
106
bool Folder::allowToggling() const
 
107
{
 
108
    return Misc::fExists(itsDisabledCfg.name)
 
109
            ? Misc::fWritable(itsDisabledCfg.name)
 
110
            : Misc::dWritable(Misc::getDir(itsDisabledCfg.name));
 
111
}
 
112
 
 
113
void Folder::loadDisabled()
 
114
{
 
115
    if(itsDisabledCfg.dirty)
 
116
        saveDisabled();
 
117
 
 
118
    QFile f(itsDisabledCfg.name);
 
119
 
 
120
    KFI_DBUG << itsDisabledCfg.name;
 
121
    itsDisabledCfg.dirty=false;
 
122
    if(f.open(QIODevice::ReadOnly))
 
123
    {
 
124
        QDomDocument doc;
 
125
 
 
126
        if(doc.setContent(&f))
 
127
            for(QDomNode n=doc.documentElement().firstChild(); !n.isNull(); n=n.nextSibling())
 
128
            {
 
129
                QDomElement e=n.toElement();
 
130
 
 
131
                if(FONT_TAG==e.tagName())
 
132
                {
 
133
                    Family fam(e, false);
 
134
 
 
135
                    if(!fam.name().isEmpty())
 
136
                    {
 
137
                        Style style(e, false);
 
138
 
 
139
                        if(KFI_NO_STYLE_INFO!=style.value())
 
140
                        {
 
141
                            QList<File> files;
 
142
 
 
143
                            if(e.hasAttribute(PATH_ATTR))
 
144
                            {
 
145
                                File file(e, true);
 
146
 
 
147
                                if(!file.path().isEmpty())
 
148
                                    files.append(file);
 
149
                                else
 
150
                                    itsDisabledCfg.dirty=true;
 
151
                            }
 
152
                            else
 
153
                            {
 
154
                                for(QDomNode n=e.firstChild(); !n.isNull(); n=n.nextSibling())
 
155
                                {
 
156
                                    QDomElement ent=n.toElement();
 
157
 
 
158
                                    if(FILE_TAG==ent.tagName())
 
159
                                    {
 
160
                                        File file(ent, true);
 
161
 
 
162
                                        if(!file.path().isEmpty())
 
163
                                            files.append(file);
 
164
                                        else
 
165
                                        {
 
166
                                            KFI_DBUG << "Set dirty from load";
 
167
                                            itsDisabledCfg.dirty=true;
 
168
                                        }
 
169
                                    }
 
170
                                }
 
171
                            }
 
172
 
 
173
                            if(files.count()>0)
 
174
                            {
 
175
                                QList<File>::ConstIterator it(files.begin()),
 
176
                                                           end(files.end());
 
177
 
 
178
                                FamilyCont::ConstIterator f(itsFonts.insert(fam));
 
179
                                StyleCont::ConstIterator  s((*f).add(style));
 
180
 
 
181
                                for(; it!=end; ++it)
 
182
                                    (*s).add(*it);
 
183
                            }
 
184
                        }
 
185
                    }
 
186
                }
 
187
            }
 
188
 
 
189
        f.close();
 
190
        itsDisabledCfg.updateTimeStamp();
 
191
    }
 
192
 
 
193
    saveDisabled();
 
194
}
 
195
 
 
196
void Folder::saveDisabled()
 
197
{
 
198
    if(itsDisabledCfg.dirty)
 
199
    {
 
200
        if(!itsIsSystem || Misc::root())
 
201
        {
 
202
            KFI_DBUG << itsDisabledCfg.name;
 
203
 
 
204
            KSaveFile file;
 
205
 
 
206
            file.setFileName(itsDisabledCfg.name);
 
207
 
 
208
            if(!file.open())
 
209
            {
 
210
                KFI_DBUG << "Exit - cant open save file";
 
211
                qApp->exit(0);
 
212
            }
 
213
 
 
214
            QTextStream str(&file);
 
215
 
 
216
            str << "<"DISABLED_FONTS">" << endl;
 
217
 
 
218
            FamilyCont::ConstIterator it(itsFonts.begin()),
 
219
                                      end(itsFonts.end());
 
220
 
 
221
            for(; it!=end; ++it)
 
222
                (*it).toXml(true, str);
 
223
            str << "</"DISABLED_FONTS">" << endl;
 
224
            str.flush();
 
225
 
 
226
            if(!file.finalize())
 
227
            {
 
228
                KFI_DBUG << "Exit - cant finalize save file";
 
229
                qApp->exit(0);
 
230
            }
 
231
        }
 
232
        itsDisabledCfg.updateTimeStamp();
 
233
        itsDisabledCfg.dirty=false;
 
234
    }
 
235
}
 
236
 
 
237
QStringList Folder::toXml(int max)
 
238
{
 
239
    QStringList               rv;
 
240
    FamilyCont::ConstIterator it(itsFonts.begin()),
 
241
                              end(itsFonts.end());
 
242
    QString                   string;
 
243
    QTextStream               str(&string);
 
244
 
 
245
    for(int i=0; it!=end; ++it, ++i)
 
246
    {
 
247
        if(0==(i%max))
 
248
        {
 
249
            if(i)
 
250
            {
 
251
                str << "</"FONTLIST_TAG">" << endl;
 
252
                rv.append(string);
 
253
                string=QString();
 
254
            }
 
255
            str << "<"FONTLIST_TAG" " << SYSTEM_ATTR"=\"" << (itsIsSystem ? "true" : "false") << "\">" << endl;
 
256
        }
 
257
 
 
258
        (*it).toXml(false, str);
 
259
    }
 
260
 
 
261
    if(!string.isEmpty())
 
262
    {
 
263
        str << "</"FONTLIST_TAG">" << endl;
 
264
        rv.append(string);
 
265
    }
 
266
    return rv;
 
267
}
 
268
 
 
269
Families Folder::list()
 
270
{
 
271
    Families                  fam(itsIsSystem);
 
272
    FamilyCont::ConstIterator it(itsFonts.begin()),
 
273
                              end(itsFonts.end());
 
274
 
 
275
    for(int i=0; it!=end; ++it, ++i)
 
276
        fam.items.insert(*it);
 
277
 
 
278
    return fam;
 
279
}
 
280
 
 
281
bool Folder::contains(const QString &family, quint32 style)
 
282
{
 
283
    FamilyCont::ConstIterator fam=itsFonts.find(Family(family));
 
284
 
 
285
    if(fam==itsFonts.end())
 
286
        return false;
 
287
 
 
288
    StyleCont::ConstIterator st=(*fam).styles().find(Style(style));
 
289
 
 
290
    return st!=(*fam).styles().end();
 
291
}
 
292
 
 
293
void Folder::add(const Family &family)
 
294
{
 
295
    FamilyCont::ConstIterator existingFamily=itsFonts.find(family);
 
296
 
 
297
    if(existingFamily==itsFonts.end())
 
298
        itsFonts.insert(family);
 
299
    else
 
300
    {
 
301
        StyleCont::ConstIterator it(family.styles().begin()),
 
302
                                 end(family.styles().end());
 
303
 
 
304
        for(; it!=end; ++it)
 
305
        {
 
306
            StyleCont::ConstIterator existingStyle=(*existingFamily).styles().find(*it);
 
307
 
 
308
            if(existingStyle==(*existingFamily).styles().end())
 
309
                (*existingFamily).add(*it);
 
310
            else
 
311
            {
 
312
                FileCont::ConstIterator fit((*it).files().begin()),
 
313
                                        fend((*it).files().end());
 
314
 
 
315
                for(; fit!=fend; ++fit)
 
316
                {
 
317
                    FileCont::ConstIterator f=(*existingStyle).files().find(*fit);
 
318
 
 
319
                    if(f==(*existingStyle).files().end())
 
320
                        (*existingStyle).add(*fit);
 
321
                }
 
322
 
 
323
                (*existingStyle).setWritingSystems((*existingStyle).writingSystems()|(*it).writingSystems());
 
324
                if(!(*existingStyle).scalable() && (*it).scalable())
 
325
                    (*existingStyle).setScalable(true);
 
326
            }
 
327
        }
 
328
    }
 
329
}
 
330
    
 
331
void Folder::configure()
 
332
{
 
333
KFI_DBUG << "EMPTY MODIFIED " << itsModifiedDirs.isEmpty();
 
334
 
 
335
    if(!itsModifiedDirs.isEmpty())
 
336
    {
 
337
        saveDisabled();
 
338
 
 
339
        QSet<QString>::ConstIterator it(itsModifiedDirs.constBegin()),
 
340
                                     end(itsModifiedDirs.constEnd());
 
341
        QSet<QString>                dirs;
 
342
 
 
343
        for(; it!=end; ++it)
 
344
            if(Misc::fExists((*it)+"fonts.dir"))
 
345
                dirs.insert(KShell::quoteArg(*it));
 
346
 
 
347
        if(!dirs.isEmpty())
 
348
            QProcess::startDetached(QLatin1String(KFONTINST_LIB_EXEC_DIR"/fontinst_x11"), dirs.toList());
 
349
 
 
350
        itsModifiedDirs.clear();
 
351
 
 
352
KFI_DBUG << "RUN FC";
 
353
        Misc::doCmd("fc-cache");
 
354
KFI_DBUG << "DONE";
 
355
    }
 
356
}
 
357
 
 
358
Folder::Flat Folder::flatten() const
 
359
{
 
360
    FamilyCont::ConstIterator fam=itsFonts.begin(),
 
361
                              famEnd=itsFonts.end();
 
362
    Flat                      rv;
 
363
 
 
364
    for(; fam!=famEnd; ++fam)
 
365
    {
 
366
        StyleCont::ConstIterator style((*fam).styles().begin()),
 
367
                                 styleEnd((*fam).styles().end());
 
368
 
 
369
        for(; style!=styleEnd; ++style)
 
370
        {
 
371
            FileCont::ConstIterator file((*style).files().begin()),
 
372
                                    fileEnd((*style).files().end());
 
373
 
 
374
            for(; file!=fileEnd; ++file)
 
375
                rv.insert(FlatFont(*fam, *style, *file));
 
376
        }
 
377
    }
 
378
 
 
379
    return rv;
 
380
}
 
381
 
 
382
Families Folder::Flat::build(bool system) const
 
383
{
 
384
    ConstIterator it(begin()),
 
385
                  e(end());
 
386
    Families      families(system);
 
387
 
 
388
    for(; it!=e; ++it)
 
389
    {
 
390
        Family                    f((*it).family);
 
391
        Style                     s((*it).styleInfo, (*it).scalable, (*it).writingSystems);
 
392
        FamilyCont::ConstIterator fam=families.items.constFind(f);
 
393
 
 
394
        if(families.items.constEnd()==fam)
 
395
        {
 
396
            s.add((*it).file);
 
397
            f.add(s);
 
398
            families.items.insert(f);
 
399
        }
 
400
        else
 
401
        {
 
402
            StyleCont::ConstIterator st=(*fam).styles().constFind(s);
 
403
 
 
404
            if((*fam).styles().constEnd()==st)
 
405
            {
 
406
                s.add((*it).file);
 
407
                (*fam).add(s);
 
408
            }
 
409
            else
 
410
                (*st).add((*it).file);
 
411
        }
 
412
    }
 
413
 
 
414
    return families;
 
415
}
 
416
 
 
417
}