OSDN Git Service

Version: 0.4
[fontmanager/fontmanager.git] / fontconfigmanager.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Takumi Asaki
4 ** All rights reserved.
5 ** Contact: Takumi Asaki (takumi.asaki@gmail.com)
6 **
7 ** This file is part of the fontmanager application.
8 **
9 ** You may use this file under the terms of the BSD license as follows:
10 **
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
13 ** met:
14 **   * Redistributions of source code must retain the above copyright
15 **     notice, this list of conditions and the following disclaimer.
16 **   * Redistributions in binary form must reproduce the above copyright
17 **     notice, this list of conditions and the following disclaimer in
18 **     the documentation and/or other materials provided with the
19 **     distribution.
20 **   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
21 **     the names of its contributors may be used to endorse or promote
22 **     products derived from this software without specific prior written
23 **     permission.
24 **
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 **
37 ****************************************************************************/
38
39 #include "fontconfigmanager.h"
40
41 #include "fontconfigdefs.h"
42 #include "installedfontinfo.h"
43 #include "fontsconfigproperties.h"
44
45 #include "fontsconf.h"
46
47 #include <QProcess>
48 #include <QBuffer>
49 #include <QFile>
50 #include <QXmlStreamReader>
51 #include <QVariant>
52 #include <QFontInfo>
53 #include <QFontMetrics>
54
55 #include <QDebug>
56
57 #define FCBIN_PATH "/usr/bin/"
58 #define FCCACHE_COMMAND "fc-cache"
59 #define FCCACHE_OPTION "-v"
60 #define FCLIST_COMMAND "fc-list"
61 #define FCLIST_OPTION "-v"
62
63 //static QStringList configKeys;
64
65 FontConfigManager::FontConfigManager(QObject *parent) :
66     QObject(parent), mLang("en"), mLocalFontsConf(0)
67 {
68     connect(this, SIGNAL(localFontsConfPathChanged()), SIGNAL(localFontsConfExistsChanged()));
69     connect(this, SIGNAL(localFontsConfPathChanged()), SIGNAL(fontsConfUpdated()));
70
71     mLocalFontsConf = new FontsConf(this);
72     mSystemLocalConf = new FontsConf(this);
73
74     QStringList cjkConflicts;
75     cjkConflicts << "ja" << "ko" << "zh-cn" << "zh-hk" << "zh-mo" << "zh-sg" << "zh-tw";
76     mConflictFonts << cjkConflicts;
77
78     mSystemLocalConf->load("/etc/fonts/local.conf");
79
80 }
81
82 QString FontConfigManager::currentLanguage() const
83 {
84     return mLang;
85 }
86
87 void FontConfigManager::setCurrentLanguage(const QString &lang)
88 {
89     mLang = lang;
90 }
91
92 QString FontConfigManager::localFontPath() const
93 {
94     return mLocalFontPath;
95 }
96
97 void FontConfigManager::setLocalFontPath(const QString &path)
98 {
99     mLocalFontPath = path;
100 }
101
102 QString FontConfigManager::localFontsConfPath() const
103 {
104     return mLocalFontsConfPath;
105 }
106
107 void FontConfigManager::setLocalFontsConfPath(const QString &path)
108 {
109     if (mLocalFontsConfPath != path) {
110         mLocalFontsConfPath = path;
111         emit localFontsConfPathChanged();
112     }
113 }
114
115 bool FontConfigManager::localFontsConfExists() const
116 {
117     return QFile::exists(mLocalFontsConfPath);
118 }
119
120 bool FontConfigManager::hasUnknownConfig() const
121 {
122     if (!mLocalFontsConf)
123         return false;
124     return mLocalFontsConf->hasUnknownConfig();
125 }
126
127 bool FontConfigManager::fontsConfModified() const
128 {
129     if (!mLocalFontsConf)
130         return false;
131     return mLocalFontsConf->modified();
132 }
133
134 bool FontConfigManager::isEmptyLocalFontsConf() const
135 {
136     return !mLocalFontsConf || mLocalFontsConf->isEmpty();
137 }
138
139 QStringList FontConfigManager::fontCount(const QString &fontpath) const
140 {
141     QStringList fontList;
142     foreach (InstalledFontInfo *info, mFcListInfo) {
143         if (info->file() == fontpath)
144             fontList << info->localefamily();
145     }
146     return fontList;
147 }
148
149 InstalledFontInfo *FontConfigManager::fontInfo(const QString &family, const QString &fullname) const
150 {
151     InstalledFontInfo *info = 0;
152     foreach (info, mFcListInfo) {
153         if (info->family().contains(family)) {
154             if (fullname.isEmpty())
155                 return info;
156             if (info->fullname().contains(fullname))
157                 return info;
158         }
159     }
160     return 0;
161 }
162
163 InstalledFontInfo *FontConfigManager::fontInfo(int index) const
164 {
165     if (index >= 0 && index < mFcListInfo.count())
166         return mFcListInfo.at(index);
167     return 0;
168 }
169
170 int FontConfigManager::count() const
171 {
172     return mFcListInfo.count();
173 }
174
175 void FontConfigManager::appendFontProperty(FontsConfigProperties *prop, const QStringList &familyList)
176 {
177     if (!mLocalFontsConf)
178         return;
179
180     QStringList preferedFamilies(mLocalFontsConf->preferFamily());
181     preferedFamilies << prop->preferFamilies();
182     preferedFamilies.removeDuplicates();
183     foreach (const QString &family, preferedFamilies) {
184         if (prop->preferFamilies().contains(family)) {
185             mLocalFontsConf->appendPreferFamilyFor(family, prop->family());
186             foreach (const QString &f, familyList) {
187                 mLocalFontsConf->appendPreferFamilyFor(family, f);
188             }
189         } else {
190             mLocalFontsConf->removePreferFamilyFor(family, prop->family());
191             foreach (const QString &f, familyList) {
192                 mLocalFontsConf->removePreferFamilyFor(family, f);
193             }
194         }
195     }
196
197     QStringList keys = FontsConf::configKeys();
198     foreach (const QString &key, keys) {
199         if (prop->configValue(key) == FontsConfigProperties::Default) {
200             mLocalFontsConf->unsetMatchEditValueFor(key, prop->family());
201             foreach (const QString &f, familyList) {
202                 mLocalFontsConf->unsetMatchEditValueFor(key, f);
203             }
204         } else {
205             mLocalFontsConf->setMatchEditValueFor(key, prop->family(), (prop->configValue(key) == FontsConfigProperties::True));
206             foreach (const QString &f, familyList) {
207                 mLocalFontsConf->setMatchEditValueFor(key, f, (prop->configValue(key) == FontsConfigProperties::True));
208             }
209         }
210     }
211
212     emit fontsConfUpdated();
213 }
214
215 void FontConfigManager::appendFontProperty(InstalledFontInfo *fontInfo)
216 {
217     appendFontProperty(fontInfo->fontProperty(), fontInfo->family());
218 }
219
220 FontsConfigProperties *FontConfigManager::fontProperty(const QString &family, const QStringList &familyList) const
221 {
222     FontsConfigProperties *prop = new FontsConfigProperties(family);
223     QStringList families;
224     QStringList preferedFamilies = mLocalFontsConf->preferFamily();
225     foreach (const QString &key, preferedFamilies) {
226         families = mLocalFontsConf->preferFamilyFor(key);
227         if (families.contains(family))
228             prop->addPreferFamily(key);
229         foreach (const QString &f, familyList) {
230             if (families.contains(f))
231                 prop->addPreferFamily(key);
232         }
233     }
234
235     QStringList keys = FontsConf::configKeys();
236     foreach (const QString &key, keys) {
237         QString val = mLocalFontsConf->matchEditValueFor(key, prop->family());
238         if (!val.isEmpty()) {
239             prop->setConfigValue(key, (QVariant(val).toBool() ? FontsConfigProperties::True : FontsConfigProperties::False));
240             continue;
241         }
242         foreach (const QString &f, familyList) {
243             mLocalFontsConf->matchEditValueFor(key, f);
244             if (!val.isEmpty()) {
245                 prop->setConfigValue(key, (QVariant(val).toBool() ? FontsConfigProperties::True : FontsConfigProperties::False));
246                 break;
247             }
248         }
249     }
250
251     return prop;
252 }
253
254 FontsConfigProperties *FontConfigManager::fontProperty(InstalledFontInfo *fontInfo) const
255 {
256     return fontProperty(fontInfo->enfamily(), fontInfo->family());
257 }
258
259 QString FontConfigManager::localFontsConf() const
260 {
261     QFile fp(mLocalFontsConfPath);
262
263     if (!fp.exists())
264         return QString();
265
266     if (!fp.open(QIODevice::ReadOnly))
267         return QString();
268
269     QTextStream ts(&fp);
270     ts.setCodec("UTF-8");
271     QString buf = ts.readAll();
272
273     fp.close();
274
275     return buf;
276 }
277
278 QStringList FontConfigManager::preferFamilyFor(const QString &family) const
279 {
280     return mLocalFontsConf->preferFamilyFor(family);
281 }
282
283 QStringList FontConfigManager::acceptFamilyFor(const QString &family) const
284 {
285     return mLocalFontsConf->acceptFamilyFor(family);
286 }
287
288 QStringList FontConfigManager::prependFamilyFor(const QString &family) const
289 {
290     return mLocalFontsConf->prependFamilyFor(family);
291 }
292
293 QStringList FontConfigManager::appendFamilyFor(const QString &family) const
294 {
295     return mLocalFontsConf->appendFamilyFor(family);
296 }
297
298 bool FontConfigManager::isConflict(const QString &family, const QStringList &lang) const
299 {
300     InstalledFontInfo *info = fontInfo(family);
301     if (!info)
302         return false;
303
304     QList<int> confListIndex;
305     for (int i = 0; i < mConflictFonts.count(); i++) {
306         const QStringList list(mConflictFonts.at(i));
307         foreach (const QString &f, list) {
308             if (lang.contains(f)) {
309                 if (!confListIndex.contains(i))
310                     confListIndex << i;
311                 break;
312             }
313         }
314     }
315
316     if (confListIndex.isEmpty())
317         return false;
318
319     foreach (int i, confListIndex) {
320         QStringList confList = mConflictFonts.at(confListIndex.at(i));
321         foreach (const QString &f, confList) {
322             if (info->lang().contains(f)) {
323                 return true;
324             }
325         }
326     }
327
328     return false;
329 }
330
331 QStringList FontConfigManager::systemPreferFamilyFor(const QString &family) const
332 {
333     return mSystemLocalConf->preferFamilyFor(family);
334 }
335
336 void FontConfigManager::importSystemSettings(const QString &family)
337 {
338     QStringList systemFamilyList = systemPreferFamilyFor(family);
339
340     QStringList installedFontLang;
341     foreach (InstalledFontInfo *info, mFcListInfo) {
342         if (info->systemFont())
343             continue;
344         installedFontLang << info->lang();
345     }
346     installedFontLang.sort();
347     installedFontLang.removeDuplicates();
348
349     emit startUpdateFontsConfig();
350     foreach (const QString &f, systemFamilyList) {
351         InstalledFontInfo *info = fontInfo(f);
352         if (!info)
353             continue;
354
355         if (isConflict(f, installedFontLang))
356             mLocalFontsConf->appendAcceptFamilyFor(family, f);
357         else
358             mLocalFontsConf->appendPrependFamilyFor(family, f);
359     }
360     emit endUpdateFontsConfig();
361
362     if (mLocalFontsConf->modified()) {
363         emit fontsConfUpdated();
364     }
365 }
366
367 void FontConfigManager::createRecommendedSettings()
368 {
369     QList<InstalledFontInfo*> sansSerifFonts;
370     QList<InstalledFontInfo*> serifFonts;
371     QList<InstalledFontInfo*> monospaceFonts;
372     QList<InstalledFontInfo*> monospaceSansSerifFonts;
373     QList<InstalledFontInfo*> monospaceSerifFonts;
374     QList<InstalledFontInfo*> unknownFonts;
375
376     foreach (InstalledFontInfo *info, mFcListInfo) {
377         if (info->systemFont())
378             continue;
379         if (maybeMonospaceFont(info)) {
380             if (maybeSansSerifFont(info))
381                 monospaceSansSerifFonts << info;
382             else if (maybeSerifFont(info))
383                 monospaceSerifFonts << info;
384             else
385                 monospaceFonts << info;
386         } else if (maybeSansSerifFont(info))
387             sansSerifFonts << info;
388         else if (maybeSerifFont(info))
389             serifFonts << info;
390         else
391             unknownFonts << info;
392     }
393
394     emit startUpdateFontsConfig();
395     resetFontsConf();
396
397 #if 0
398     QStringList f;
399     foreach (InstalledFontInfo *info, monospaceFonts)
400         f << info->localefamily();
401     qDebug() << "Mono:" << f;
402     f.clear();
403     foreach (InstalledFontInfo *info, monospaceSansSerifFonts)
404         f << info->localefamily();
405     qDebug() << "Mono(Sans Serif):" << f;
406     f.clear();
407     foreach (InstalledFontInfo *info, monospaceSerifFonts)
408         f << info->localefamily();
409     qDebug() << "Mono(Serif):" << f;
410     f.clear();
411     foreach (InstalledFontInfo *info, sansSerifFonts)
412         f << info->localefamily();
413     qDebug() << "Sans Serif:" << f;
414     f.clear();
415     foreach (InstalledFontInfo *info, serifFonts)
416         f << info->localefamily();
417     qDebug() << "Serif:" << f;
418     f.clear();
419     foreach (InstalledFontInfo *info, unknownFonts)
420         f << info->localefamily();
421     qDebug() << "Unknown:" << f;
422 #endif
423
424     if (monospaceFonts.count())
425         foreach (InstalledFontInfo *info, monospaceFonts) {
426             addPreferFamily(MONOSPACE_DEF, info->enfamily());
427             addPreferFamily(MONOSPACE_DEF, info->localefamily());
428         }
429     else if (monospaceSansSerifFonts.count())
430         foreach (InstalledFontInfo *info, monospaceSansSerifFonts) {
431             addPreferFamily(MONOSPACE_DEF, info->enfamily());
432             addPreferFamily(MONOSPACE_DEF, info->localefamily());
433         }
434     else if (monospaceSerifFonts.count())
435         foreach (InstalledFontInfo *info, monospaceSerifFonts) {
436             addPreferFamily(MONOSPACE_DEF, info->enfamily());
437             addPreferFamily(MONOSPACE_DEF, info->localefamily());
438         }
439
440     if (sansSerifFonts.count())
441         foreach (InstalledFontInfo *info, sansSerifFonts) {
442             addPreferFamily(SANSSERIF_DEF, info->enfamily());
443             addPreferFamily(SANSSERIF_DEF, info->localefamily());
444         }
445     else if (monospaceSansSerifFonts.count())
446         foreach (InstalledFontInfo *info, monospaceSansSerifFonts) {
447             addPreferFamily(SANSSERIF_DEF, info->enfamily());
448             addPreferFamily(SANSSERIF_DEF, info->localefamily());
449         }
450     else if (unknownFonts.count())
451         foreach (InstalledFontInfo *info, unknownFonts) {
452             addPreferFamily(SANSSERIF_DEF, info->enfamily());
453             addPreferFamily(SANSSERIF_DEF, info->localefamily());
454         }
455     else if (monospaceFonts.count())
456         foreach (InstalledFontInfo *info, monospaceFonts) {
457             addPreferFamily(SANSSERIF_DEF, info->enfamily());
458             addPreferFamily(SANSSERIF_DEF, info->localefamily());
459         }
460
461     if (serifFonts.count())
462         foreach (InstalledFontInfo *info, serifFonts) {
463             addPreferFamily(SERIF_DEF, info->enfamily());
464             addPreferFamily(SERIF_DEF, info->localefamily());
465         }
466     else if (monospaceSerifFonts.count())
467         foreach (InstalledFontInfo *info, monospaceSerifFonts) {
468             addPreferFamily(SANSSERIF_DEF, info->enfamily());
469             addPreferFamily(SANSSERIF_DEF, info->localefamily());
470         }
471     else if (unknownFonts.count())
472         foreach (InstalledFontInfo *info, unknownFonts) {
473             addPreferFamily(SERIF_DEF, info->enfamily());
474             addPreferFamily(SERIF_DEF, info->localefamily());
475         }
476     else if (monospaceFonts.count())
477         foreach (InstalledFontInfo *info, monospaceFonts) {
478             addPreferFamily(SERIF_DEF, info->enfamily());
479             addPreferFamily(SERIF_DEF, info->localefamily());
480         }
481
482     foreach (const QString &f, FontsConf::genericFamilies())
483         importSystemSettings(f);
484     emit endUpdateFontsConfig();
485
486     emit fontsConfUpdated();
487 }
488
489 QStringList FontConfigManager::installableFamily(const QString &family, bool localOnly)
490 {
491     QStringList installedFont;
492     installedFont << prependFamilyFor(family);
493     installedFont << appendFamilyFor(family);
494     installedFont << preferFamilyFor(family);
495     installedFont << acceptFamilyFor(family);
496
497     QStringList familyList;
498     foreach (InstalledFontInfo *info, mFcListInfo) {
499         if (localOnly && info->systemFont())
500             continue;
501         bool check = false;
502         foreach (const QString &f, info->family()) {
503             if (installedFont.contains(f)) {
504                 check = true;
505                 break;
506             }
507         }
508         if (!check)
509             familyList << info->localefamily();
510     }
511     familyList.sort();
512     familyList.removeDuplicates();
513
514     return familyList;
515 }
516
517 bool FontConfigManager::maybeSansSerifFont(InstalledFontInfo *info) const
518 {
519     foreach (const QString &f, info->family()) {
520         if (f.contains("gothic", Qt::CaseInsensitive) ||
521                 f.contains("arial", Qt::CaseInsensitive) ||
522                 f.contains("helvetica", Qt::CaseInsensitive) ||
523                 f.contains("verdana", Qt::CaseInsensitive) ||
524                 f.contains("sans", Qt::CaseInsensitive))
525             return true;
526     }
527     return false;
528 }
529
530 bool FontConfigManager::maybeSerifFont(InstalledFontInfo *info) const
531 {
532     foreach (const QString &f, info->family()) {
533         if (f.contains("mincho", Qt::CaseInsensitive) ||
534                 f.contains("times", Qt::CaseInsensitive) ||
535                 (f.contains("serif", Qt::CaseInsensitive) && !f.contains("sans", Qt::CaseInsensitive)))
536             return true;
537     }
538     return false;
539 }
540
541 bool FontConfigManager::maybeMonospaceFont(InstalledFontInfo *info) const
542 {
543     QFont font(info->enfamily());
544     if (font.exactMatch()) {
545         QFontInfo fi(font);
546         if (fi.fixedPitch())
547             return true;
548         QFontMetrics fm(font);
549         int w = fm.width(QLatin1Char('A'));
550         if (fm.width(QLatin1Char('i')) == w && fm.width(QLatin1Char('X')) == w)
551             return true;
552     }
553     foreach (const QString &f, info->family()) {
554         if (f.contains("courier", Qt::CaseInsensitive) ||
555                 f.contains("mono", Qt::CaseInsensitive))
556             return true;
557     }
558     return false;
559 }
560
561 void FontConfigManager::runFcCache()
562 {
563     QProcess *proc = new QProcess(this);
564     connect(proc, SIGNAL(finished(int)), SIGNAL(fcCacheFinished()));
565     connect(proc, SIGNAL(finished(int)), proc, SLOT(deleteLater()));
566     proc->start(FCBIN_PATH FCCACHE_COMMAND, QStringList() << FCCACHE_OPTION);
567 }
568
569 void FontConfigManager::readFcList()
570 {
571     QProcess *proc = new QProcess(this);
572     proc->start(FCBIN_PATH FCLIST_COMMAND, QStringList() << FCLIST_OPTION);
573     if (!proc->waitForStarted())
574         return;
575
576     if (!proc->waitForFinished())
577         return;
578
579     qDeleteAll(mFcListInfo);
580     mFcListInfo.clear();
581
582     QByteArray buf = proc->readAllStandardOutput();
583     QByteArray errbuf = proc->readAllStandardError();
584     if (!errbuf.isEmpty())
585         qWarning() << errbuf;
586     Q_ASSERT(errbuf.isEmpty());
587
588     static QByteArray emptyLine("\n");
589     QBuffer buffer(&buf);
590     QByteArray fibuf;
591     buffer.open(QIODevice::ReadOnly);
592     Q_ASSERT(buffer.isOpen());
593     while (!buffer.atEnd()) {
594         QByteArray linebuf = buffer.readLine();
595         if (linebuf.isEmpty() || linebuf == emptyLine) {
596             if (!fibuf.isEmpty()) {
597                 InstalledFontInfo *info = new InstalledFontInfo(fibuf, mLocalFontPath, this);
598                 info->setLocale(mLang);
599                 if (info->isValid())
600                     mFcListInfo.append(info);
601                 else
602                     delete info;
603                 info->setFontProperty(fontProperty(info));
604                 fibuf.clear();
605             }
606         } else {
607             fibuf += linebuf;
608         }
609     }
610     Q_ASSERT(fibuf.isEmpty());
611     buffer.close();
612
613     qSort(mFcListInfo.begin(), mFcListInfo.end(), InstalledFontInfo::compare);
614
615     emit fontListUpdated();
616
617     delete proc;
618 }
619
620 void FontConfigManager::readFontsConf()
621 {
622     mLocalFontsConf->load(mLocalFontsConfPath);
623     emit fontsConfUpdated();
624 }
625
626 void FontConfigManager::saveFontsConf()
627 {
628     if (!mLocalFontsConf || mLocalFontsConfPath.isEmpty())
629         return;
630
631     bool check = localFontsConfExists();
632     if (isEmptyLocalFontsConf()) {
633         if (check) {
634             QFile::remove(mLocalFontsConfPath);
635             emit localFontsConfExistsChanged();
636         }
637     } else {
638         mLocalFontsConf->save(mLocalFontsConfPath);
639         if (!check) {
640             emit localFontsConfExistsChanged();
641         }
642     }
643 }
644
645 void FontConfigManager::resetFontsConf()
646 {
647     if (!mLocalFontsConf)
648         return;
649     mLocalFontsConf->initFontsConf();
650     emit fontsConfUpdated();
651 }
652
653 void FontConfigManager::addPreferFamily(const QString &family, const QString &value)
654 {
655     mLocalFontsConf->appendPreferFamilyFor(family, value);
656     emit fontsConfUpdated();
657 }
658
659 void FontConfigManager::addAcceptFamily(const QString &family, const QString &value)
660 {
661     mLocalFontsConf->appendAcceptFamilyFor(family, value);
662     emit fontsConfUpdated();
663 }
664
665 void FontConfigManager::addPrependFamily(const QString &family, const QString &value)
666 {
667     mLocalFontsConf->appendPrependFamilyFor(family, value);
668     emit fontsConfUpdated();
669 }
670
671 void FontConfigManager::addAppendFamily(const QString &family, const QString &value)
672 {
673     mLocalFontsConf->appendAppendFamilyFor(family, value);
674     emit fontsConfUpdated();
675 }
676
677 void FontConfigManager::removePreferFamily(const QString &family, const QString &value)
678 {
679     mLocalFontsConf->removePreferFamilyFor(family, value);
680     emit fontsConfUpdated();
681 }
682
683 void FontConfigManager::removeAcceptFamily(const QString &family, const QString &value)
684 {
685     mLocalFontsConf->removeAcceptFamilyFor(family, value);
686     emit fontsConfUpdated();
687 }
688
689 void FontConfigManager::removePrependFamily(const QString &family, const QString &value)
690 {
691     mLocalFontsConf->removePrependFamilyFor(family, value);
692     emit fontsConfUpdated();
693 }
694
695 void FontConfigManager::removeAppendFamily(const QString &family, const QString &value)
696 {
697     mLocalFontsConf->removeAppendFamilyFor(family, value);
698     emit fontsConfUpdated();
699 }