OSDN Git Service

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