2
* KFontInst - KDE Font Installer
4
* Copyright 2003-2009 Craig Drummond <craig@kde.org>
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.
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.
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.
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>
36
#include <fontconfig/fontconfig.h>
40
#include "KfiConstants.h"
41
#include "XmlStrings.h"
44
#include "config-fontinst.h"
46
#define DISABLED_FONTS "disabledfonts"
47
#define KFI_DBUG kDebug() << time(0L)
52
bool Folder::CfgFile::modified()
54
return timestamp!=Misc::getTimeStamp(name);
57
void Folder::CfgFile::updateTimeStamp()
59
timestamp=Misc::getTimeStamp(name);
67
void Folder::init(bool system, bool systemBus)
72
FcStrList *list=FcConfigGetFontDirs(FcInitLoadConfigAndFonts());
76
while((fcDir=FcStrListNext(list)))
77
dirs.append(Misc::dirSyntax((const char *)fcDir));
79
itsLocation=Misc::getFolder(Misc::dirSyntax(QDir::homePath()+"/.fonts/"), Misc::dirSyntax(QDir::homePath()), dirs);
82
itsLocation=KFI_DEFAULT_SYS_FONTS_FOLDER;
84
if((!system && !systemBus) || (system && systemBus))
85
FcConfig::addDir(itsLocation, system);
87
itsDisabledCfg.dirty=false;
88
if(itsDisabledCfg.name.isEmpty())
90
QString fileName("/"DISABLED_FONTS".xml");
93
itsDisabledCfg.name=QString::fromLatin1(KFI_ROOT_CFG_DIR)+fileName;
96
QString path=KGlobal::dirs()->localxdgconfdir();
98
if(!Misc::dExists(path))
99
Misc::createDir(path);
100
itsDisabledCfg.name=path+fileName;
102
itsDisabledCfg.timestamp=0;
106
bool Folder::allowToggling() const
108
return Misc::fExists(itsDisabledCfg.name)
109
? Misc::fWritable(itsDisabledCfg.name)
110
: Misc::dWritable(Misc::getDir(itsDisabledCfg.name));
113
void Folder::loadDisabled()
115
if(itsDisabledCfg.dirty)
118
QFile f(itsDisabledCfg.name);
120
KFI_DBUG << itsDisabledCfg.name;
121
itsDisabledCfg.dirty=false;
122
if(f.open(QIODevice::ReadOnly))
126
if(doc.setContent(&f))
127
for(QDomNode n=doc.documentElement().firstChild(); !n.isNull(); n=n.nextSibling())
129
QDomElement e=n.toElement();
131
if(FONT_TAG==e.tagName())
133
Family fam(e, false);
135
if(!fam.name().isEmpty())
137
Style style(e, false);
139
if(KFI_NO_STYLE_INFO!=style.value())
143
if(e.hasAttribute(PATH_ATTR))
147
if(!file.path().isEmpty())
150
itsDisabledCfg.dirty=true;
154
for(QDomNode n=e.firstChild(); !n.isNull(); n=n.nextSibling())
156
QDomElement ent=n.toElement();
158
if(FILE_TAG==ent.tagName())
160
File file(ent, true);
162
if(!file.path().isEmpty())
166
KFI_DBUG << "Set dirty from load";
167
itsDisabledCfg.dirty=true;
175
QList<File>::ConstIterator it(files.begin()),
178
FamilyCont::ConstIterator f(itsFonts.insert(fam));
179
StyleCont::ConstIterator s((*f).add(style));
190
itsDisabledCfg.updateTimeStamp();
196
void Folder::saveDisabled()
198
if(itsDisabledCfg.dirty)
200
if(!itsIsSystem || Misc::root())
202
KFI_DBUG << itsDisabledCfg.name;
206
file.setFileName(itsDisabledCfg.name);
210
KFI_DBUG << "Exit - cant open save file";
214
QTextStream str(&file);
216
str << "<"DISABLED_FONTS">" << endl;
218
FamilyCont::ConstIterator it(itsFonts.begin()),
222
(*it).toXml(true, str);
223
str << "</"DISABLED_FONTS">" << endl;
228
KFI_DBUG << "Exit - cant finalize save file";
232
itsDisabledCfg.updateTimeStamp();
233
itsDisabledCfg.dirty=false;
237
QStringList Folder::toXml(int max)
240
FamilyCont::ConstIterator it(itsFonts.begin()),
243
QTextStream str(&string);
245
for(int i=0; it!=end; ++it, ++i)
251
str << "</"FONTLIST_TAG">" << endl;
255
str << "<"FONTLIST_TAG" " << SYSTEM_ATTR"=\"" << (itsIsSystem ? "true" : "false") << "\">" << endl;
258
(*it).toXml(false, str);
261
if(!string.isEmpty())
263
str << "</"FONTLIST_TAG">" << endl;
269
Families Folder::list()
271
Families fam(itsIsSystem);
272
FamilyCont::ConstIterator it(itsFonts.begin()),
275
for(int i=0; it!=end; ++it, ++i)
276
fam.items.insert(*it);
281
bool Folder::contains(const QString &family, quint32 style)
283
FamilyCont::ConstIterator fam=itsFonts.find(Family(family));
285
if(fam==itsFonts.end())
288
StyleCont::ConstIterator st=(*fam).styles().find(Style(style));
290
return st!=(*fam).styles().end();
293
void Folder::add(const Family &family)
295
FamilyCont::ConstIterator existingFamily=itsFonts.find(family);
297
if(existingFamily==itsFonts.end())
298
itsFonts.insert(family);
301
StyleCont::ConstIterator it(family.styles().begin()),
302
end(family.styles().end());
306
StyleCont::ConstIterator existingStyle=(*existingFamily).styles().find(*it);
308
if(existingStyle==(*existingFamily).styles().end())
309
(*existingFamily).add(*it);
312
FileCont::ConstIterator fit((*it).files().begin()),
313
fend((*it).files().end());
315
for(; fit!=fend; ++fit)
317
FileCont::ConstIterator f=(*existingStyle).files().find(*fit);
319
if(f==(*existingStyle).files().end())
320
(*existingStyle).add(*fit);
323
(*existingStyle).setWritingSystems((*existingStyle).writingSystems()|(*it).writingSystems());
324
if(!(*existingStyle).scalable() && (*it).scalable())
325
(*existingStyle).setScalable(true);
331
void Folder::configure()
333
KFI_DBUG << "EMPTY MODIFIED " << itsModifiedDirs.isEmpty();
335
if(!itsModifiedDirs.isEmpty())
339
QSet<QString>::ConstIterator it(itsModifiedDirs.constBegin()),
340
end(itsModifiedDirs.constEnd());
344
if(Misc::fExists((*it)+"fonts.dir"))
345
dirs.insert(KShell::quoteArg(*it));
348
QProcess::startDetached(QLatin1String(KFONTINST_LIB_EXEC_DIR"/fontinst_x11"), dirs.toList());
350
itsModifiedDirs.clear();
352
KFI_DBUG << "RUN FC";
353
Misc::doCmd("fc-cache");
358
Folder::Flat Folder::flatten() const
360
FamilyCont::ConstIterator fam=itsFonts.begin(),
361
famEnd=itsFonts.end();
364
for(; fam!=famEnd; ++fam)
366
StyleCont::ConstIterator style((*fam).styles().begin()),
367
styleEnd((*fam).styles().end());
369
for(; style!=styleEnd; ++style)
371
FileCont::ConstIterator file((*style).files().begin()),
372
fileEnd((*style).files().end());
374
for(; file!=fileEnd; ++file)
375
rv.insert(FlatFont(*fam, *style, *file));
382
Families Folder::Flat::build(bool system) const
384
ConstIterator it(begin()),
386
Families families(system);
390
Family f((*it).family);
391
Style s((*it).styleInfo, (*it).scalable, (*it).writingSystems);
392
FamilyCont::ConstIterator fam=families.items.constFind(f);
394
if(families.items.constEnd()==fam)
398
families.items.insert(f);
402
StyleCont::ConstIterator st=(*fam).styles().constFind(s);
404
if((*fam).styles().constEnd()==st)
410
(*st).add((*it).file);