OSDN Git Service

Version 0.5
[fontmanager/fontmanager.git] / applicationcontroller.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 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 "applicationcontroller.h"
40
41 #include "fontconfigdefs.h"
42 #include "fontconfigmanager.h"
43 #include "installedfontinfo.h"
44 #include "fontsconfeditorcontroller.h"
45 #include "fontsconf.h"
46
47 #include <QtCore>
48
49 #define VERSION_STRING "0.5"
50
51 ApplicationController::ApplicationController(QObject *parent) :
52     QObject(parent), mFontDirExists(false), mShowSystemFont(false),
53     mUpdating(0),
54     mWorking(false), mIgnoreUpdate(false),
55     mFontConfig(0)
56 {
57
58 }
59
60 void ApplicationController::init()
61 {
62     mFontConfig = new FontConfigManager(this);
63     setFontDir(QDir::homePath() + QLatin1String("/.fonts"));
64
65     QLocale curLocale;
66     mLang = curLocale.name();
67     int idx = mLang.indexOf(QLatin1Char('_'));
68     if (idx > 0)
69         mLang = mLang.left(idx);
70     mFontConfig->setCurrentLanguage(mLang);
71
72     connect(mFontConfig, SIGNAL(fcCacheFinished()), mFontConfig, SLOT(readFcList()));
73     connect(mFontConfig, SIGNAL(fontListUpdated()), SLOT(readFcListFinished()));
74     connect(mFontConfig, SIGNAL(fontListUpdated()), SLOT(syncInstalledFonts()));
75
76     connect(mFontConfig, SIGNAL(localFontsConfPathChanged()), SIGNAL(localFontsConfPathChanged()));
77     connect(mFontConfig, SIGNAL(localFontsConfExistsChanged()), SIGNAL(localFontsConfExistsChanged()));
78
79     connect(mFontConfig, SIGNAL(startUpdateFontsConfig()), SLOT(startUpdateLocalFontsConf()));
80     connect(mFontConfig, SIGNAL(fontsConfUpdated()), SLOT(localFontsConfUpdated()));
81     connect(mFontConfig, SIGNAL(endUpdateFontsConfig()), SLOT(endUpdateLocalFontsConf()));
82
83     connect(this, SIGNAL(localFontsConfChanged()), SLOT(updateAllEditorController()));
84     connect(this, SIGNAL(localFontsConfChanged()), SLOT(saveFontsConf()));
85
86     connect(mFontConfig, SIGNAL(warning(QString)), SIGNAL(alertDialog(QString)));
87
88     mFontConfig->setLocalFontsConfPath(QDir::homePath() + QLatin1String("/.fonts.conf"));
89
90     mFontConfig->readFontsConf();
91     mFontConfig->readFcList();
92
93     foreach (const QString &f, FontsConf::genericFamilies()) {
94         updateEditorController(f);
95     }
96
97 }
98
99 QString ApplicationController::version() const
100 {
101     return QLatin1String(VERSION_STRING);
102 }
103
104 QString ApplicationController::currentLanguage() const
105 {
106     return mLang;
107 }
108
109 QString ApplicationController::fontDir() const
110 {
111     return mFontDirPath;
112 }
113
114 void ApplicationController::setFontDir(const QString &dirpath)
115 {
116     if (mFontDirPath != dirpath) {
117         mFontDirPath = dirpath;
118         emit fontDirChanged(mFontDirPath);
119         QDir fontDir(dirpath);
120         mFontDirExists = fontDir.exists();
121         emit fontDirExistsChanged();
122         if (mFontConfig)
123             mFontConfig->setLocalFontPath(dirpath);
124     }
125 }
126
127 bool ApplicationController::fontDirExists() const
128 {
129     return mFontDirExists;
130 }
131
132 bool ApplicationController::showSystemFont() const
133 {
134     return mShowSystemFont;
135 }
136
137 void ApplicationController::setShowSystemFont(bool show)
138 {
139     if (mShowSystemFont != show) {
140         mShowSystemFont = show;
141         emit showSystemFontChanged();
142     }
143 }
144
145 FontInfo *ApplicationController::checkFontInfo(const QUrl &path)
146 {
147     FontInfo *fInfo = new FontInfo(path.toLocalFile(), mFontConfig, this);
148     return fInfo;
149 }
150
151 InstalledFontInfo *ApplicationController::fontInfo(const QString &family, const QString &fullname) const
152 {
153     return mFontConfig->fontInfo(family, fullname);
154 }
155
156 QStringList ApplicationController::fontCount(const QString &fontpath) const
157 {
158     return mFontConfig->fontCount(fontpath);
159 }
160
161 QString ApplicationController::localeFamily(const QString &family) const
162 {
163     return mFontConfig->localeFamily(family);
164 }
165
166 bool ApplicationController::fontExists(FontInfo *fontinfo)
167 {
168     QFileInfo srcfont(fontinfo->fontPath());
169     QFileInfo dstfont(mFontDirPath + QLatin1String("/") + srcfont.fileName());
170     return dstfont.exists();
171 }
172
173 FontsConfEditorController *ApplicationController::editorController(const QString &family)
174 {
175     FontsConfEditorController *controller = mEditorController.value(family, 0);
176     if (!controller) {
177         controller = new FontsConfEditorController(family, this);
178         mEditorController.insert(family, controller);
179         connect(controller, SIGNAL(appendFamilyToConfig(QString,QString,QString)), SLOT(appendFamilyToConfig(QString,QString,QString)));
180         connect(controller, SIGNAL(insertFamilyToConfig(QString,QString,QString,int)), SLOT(insertFamilyToConfig(QString,QString,QString,int)));
181         connect(controller, SIGNAL(removeFamilyFromList(QString,QString,QString)), SLOT(removeFamilyFromConfig(QString,QString,QString)));
182         updateEditorController(family);
183     }
184     return controller;
185 }
186
187 void ApplicationController::updateEditorController(const QString &family)
188 {
189     FontsConfEditorController *controller = editorController(family);
190
191     QStringList familyList;
192
193     controller->clear();
194
195     familyList = mFontConfig->prependFamilyFor(family);
196     foreach (const QString &f, familyList) {
197         InstalledFontInfo *info = fontInfo(f);
198         controller->appendFontsInfo(f, PREPEND_DEF, info);
199     }
200
201     familyList = mFontConfig->preferFamilyFor(family);
202     foreach (const QString &f, familyList) {
203         InstalledFontInfo *info = fontInfo(f);
204         controller->appendFontsInfo(f, PREFER_DEF, info);
205     }
206
207     familyList = mFontConfig->acceptFamilyFor(family);
208     foreach (const QString &f, familyList) {
209         InstalledFontInfo *info = fontInfo(f);
210         controller->appendFontsInfo(f, ACCEPT_DEF, info);
211     }
212
213     controller->syncFamilyList();
214 }
215
216 QUrl ApplicationController::backupDir() const
217 {
218     return QUrl(QDir::homePath() + QLatin1String("/MyDocs/Documents"));
219 }
220
221 QString ApplicationController::defaultBackupFilename() const
222 {
223     QString backupdir = backupDir().toString();
224     QString backupfile = backupdir + QLatin1String("/fonts.conf");
225     int idx = 0;
226     while (QFile::exists(backupfile)) {
227         backupfile = backupdir + QString::fromAscii("/fonts-%1.conf").arg(++idx);
228     }
229     return backupfile;
230 }
231
232 QString ApplicationController::url2path(const QUrl &url) const
233 {
234     QString path = url.toLocalFile();
235     return path;
236 }
237
238 QString ApplicationController::path4display(const QString &path) const
239 {
240     QString str(path);
241     if (str.startsWith(QDir::homePath()))
242         str.replace(0, QDir::homePath().length(), QLatin1String("~"));
243 //    str.replace(QLatin1Char('/'), "/<wbr>");
244     return str;
245 }
246
247 QStringList ApplicationController::installedFonts() const
248 {
249     return mInstalledFonts;
250 }
251
252 void ApplicationController::updateAllEditorController()
253 {
254     if (!mFontConfig->fontsConfModified() || mIgnoreUpdate) {
255         mIgnoreUpdate = false;
256         return;
257     }
258     foreach (const QString &f, mEditorController.keys()) {
259         updateEditorController(f);
260     }
261 }
262
263 bool ApplicationController::localFontsConfExists() const
264 {
265     if (!mFontConfig)
266         return false;
267     return QFile::exists(mFontConfig->localFontsConfPath());
268 }
269
270 QString ApplicationController::localFontsConfPath() const
271 {
272     if (!mFontConfig)
273         return QString();
274     return mFontConfig->localFontsConfPath();
275 }
276
277 QString ApplicationController::localFontsConf() const
278 {
279     if (!mFontConfig)
280         return QString();
281     return mFontConfig->localFontsConf();
282 }
283
284 bool ApplicationController::isEmptyFontsConf() const
285 {
286     if (!localFontsConfExists())
287         return true;
288     return !mFontConfig || mFontConfig->isEmptyLocalFontsConf();
289 }
290
291 bool ApplicationController::working() const
292 {
293     return mWorking;
294 }
295
296
297 void ApplicationController::startUpdateLocalFontsConf()
298 {
299     mUpdating++;
300 }
301
302 void ApplicationController::endUpdateLocalFontsConf()
303 {
304     mUpdating--;
305     Q_ASSERT(mUpdating >= 0);
306 }
307
308 void ApplicationController::localFontsConfUpdated()
309 {
310     if (mUpdating == 0)
311         emit localFontsConfChanged();
312 }
313
314 void ApplicationController::resetLocalFontsConf()
315 {
316     if (!mFontConfig)
317         return;
318     mFontConfig->resetFontsConf();
319 }
320
321 void ApplicationController::importSystemSettings(const QString &family)
322 {
323     mFontConfig->importSystemSettings(family);
324     if (mFontConfig->fontsConfModified())
325         updateEditorController(family);
326 }
327
328 void ApplicationController::createRecommendedSettings()
329 {
330     mFontConfig->createRecommendedSettings();
331 }
332
333 void ApplicationController::backupConfig(const QString &filename)
334 {
335     mFontConfig->backupFontsConf(filename);
336     emit backupConfigFinished(filename);
337 }
338
339 void ApplicationController::restoreConfig(const QString &filename)
340 {
341     mFontConfig->restoreFontsConf(filename);
342     emit restoreConfigFinished(filename);
343 }
344
345 void ApplicationController::restoreConfig(const QUrl &filename)
346 {
347     restoreConfig(filename.toLocalFile());
348 }
349
350 void ApplicationController::createFontDir()
351 {
352     QDir fontDir(mFontDirPath);
353     if (!fontDir.exists()) {
354         fontDir.mkpath(mFontDirPath);
355         mFontDirExists = fontDir.exists();
356         emit fontDirExistsChanged();
357     }
358 }
359
360 void ApplicationController::installFont(FontInfo *fontinfo)
361 {
362     QFileInfo srcfont(fontinfo->fontPath());
363     QFileInfo dstfont(mFontDirPath + QLatin1String("/") + srcfont.fileName());
364
365     QFile::copy(srcfont.absoluteFilePath(), dstfont.absoluteFilePath());
366
367     foreach (const QString &family, fontinfo->families()) {
368         FontsConfigProperties *prop = fontinfo->fontProperty(family);
369         mFontConfig->appendFontProperty(prop);
370     }
371
372     if (!mInstalledFonts.contains(dstfont.absoluteFilePath())) {
373         mInstalledFonts.append(dstfont.absoluteFilePath());
374         emit installedFontsChanged();
375     }
376
377     emit installFinished(srcfont.fileName());
378
379     mWorking = true;
380     emit workingChanged();
381
382     mFontConfig->runFcCache();
383 }
384
385 void ApplicationController::updateFontsConf(InstalledFontInfo *fontInfo)
386 {
387     mFontConfig->appendFontProperty(fontInfo);
388 }
389
390 void ApplicationController::uninstallFont(const QString &fontpath)
391 {
392     bool check = QFile::remove(fontpath);
393
394     if (mInstalledFonts.contains(fontpath)) {
395         mInstalledFonts.removeOne(fontpath);
396         emit installedFontsChanged();
397     }
398
399     if (check) {
400         emit uninstallFinished(fontpath);
401
402         mWorking = true;
403         emit workingChanged();
404
405         mFontConfig->runFcCache();
406     } else
407         emit alertDialog(tr("Could not remove Font '%1'").arg(fontpath));
408 }
409
410 void ApplicationController::syncInstalledFonts()
411 {
412     if (!mFontConfig)
413         return;
414     emit clearInstalledFontList();
415     for (int i = 0; i < mFontConfig->count(); i++) {
416         InstalledFontInfo *info = mFontConfig->fontInfo(i);
417         if (mShowSystemFont || !info->systemFont())
418             emit appendInstalledFont(info->localefamily(), info->localefullname());
419     }
420 }
421
422 void ApplicationController::syncInstallableFamilyFor(const QString &family)
423 {
424     if (!mFontConfig)
425         return;
426     emit clearInstallableFamilyListFor(family);
427     QStringList familyList = mFontConfig->installableFamily(family);
428     foreach (const QString &f, familyList) {
429         InstalledFontInfo *info = mFontConfig->fontInfo(f);
430         emit appendInstallableFamily(info->enfamily(), info->localefamily(), info->systemFont());
431     }
432 }
433
434 void ApplicationController::saveFontsConf()
435 {
436     if (!mFontConfig->fontsConfModified()) {
437         emit localFontsConfFileUpdated();
438         return;
439     }
440
441     mFontConfig->saveFontsConf();
442     emit localFontsConfFileUpdated();
443 }
444
445 void ApplicationController::appendFamilyToConfig(const QString &family, const QString &value, const QString &priority)
446 {
447     FontsConfEditorController *controller = qobject_cast<FontsConfEditorController*>(sender());
448     if (controller)
449         mIgnoreUpdate = true;
450     if (priority == PREPEND_DEF)
451         mFontConfig->addPrependFamily(family, value);
452     else if (priority == APPEND_DEF)
453         mFontConfig->addAppendFamily(family, value);
454     else if (priority == PREFER_DEF)
455         mFontConfig->addPreferFamily(family, value);
456     else if (priority == ACCEPT_DEF)
457         mFontConfig->addAcceptFamily(family, value);
458 }
459
460 void ApplicationController::insertFamilyToConfig(const QString &family, const QString &value, const QString &priority, int index)
461 {
462     FontsConfEditorController *controller = qobject_cast<FontsConfEditorController*>(sender());
463     if (controller)
464         mIgnoreUpdate = true;
465     if (priority == PREPEND_DEF)
466         mFontConfig->insertPrependFamily(family, value, index);
467     else if (priority == APPEND_DEF)
468         mFontConfig->insertAppendFamily(family, value, index);
469     else if (priority == PREFER_DEF)
470         mFontConfig->insertPreferFamily(family, value, index);
471     else if (priority == ACCEPT_DEF)
472         mFontConfig->insertAcceptFamily(family, value, index);
473 }
474
475 void ApplicationController::removeFamilyFromConfig(const QString &family, const QString &value, const QString &priority)
476 {
477     FontsConfEditorController *controller = qobject_cast<FontsConfEditorController*>(sender());
478     if (controller)
479         mIgnoreUpdate = true;
480     if (priority == PREPEND_DEF)
481         mFontConfig->removePrependFamily(family, value);
482     else if (priority == APPEND_DEF)
483         mFontConfig->removeAppendFamily(family, value);
484     else if (priority == PREFER_DEF)
485         mFontConfig->removePreferFamily(family, value);
486     else if (priority == ACCEPT_DEF)
487         mFontConfig->removeAcceptFamily(family, value);
488 }
489
490 void ApplicationController::readFcListFinished()
491 {
492     mWorking = false;
493     emit workingChanged();
494 }