diff --git a/kcms/kfontinst/apps/installfont.desktop b/kcms/kfontinst/apps/installfont.desktop
index 97afdcc31..e16506890 100644
--- a/kcms/kfontinst/apps/installfont.desktop
+++ b/kcms/kfontinst/apps/installfont.desktop
@@ -1,95 +1,95 @@
[Desktop Entry]
-X-KDE-ServiceTypes=KonqPopupMenu/Plugin,application/x-font-ttf,application/x-font-type1,application/x-font-bdf,application/x-font-pcf,application/x-font-otf,application/x-font-afm,fonts/package
+X-KDE-ServiceTypes=KonqPopupMenu/Plugin,application/x-font-ttf,application/x-font-type1,application/x-font-bdf,application/x-font-pcf,application/x-font-otf,application/x-font-afm,fonts/package,font/ttf,font/otf
Actions=installFont;
Type=Service
[Desktop Action installFont]
Name=Install...
Name[af]=Installeer...
Name[ar]=ثبّت...
Name[as]=সংস্থাপন কৰক...
Name[be]=Устанавіць...
Name[be@latin]=Zainstaluj...
Name[bg]=Инсталиране...
Name[bn]=ইনস্টল...
Name[bn_IN]=ইনস্টল করুন...
Name[bs]=Instaliraj...
Name[ca]=Instal·la...
Name[ca@valencia]=Instal·la...
Name[cs]=Instalovat...
Name[csb]=Instalëjë...
Name[da]=Installér...
Name[de]=Installieren ...
Name[el]=Εγκατάσταση...
Name[en_GB]=Install...
Name[eo]=Instali...
Name[es]=Instalar...
Name[et]=Paigalda...
Name[eu]=Instalatu...
Name[fa]=نصب...
Name[fi]=Asenna…
Name[fr]=Installer...
Name[fy]=Ynstallearje...
Name[ga]=Suiteáil...
Name[gl]=Instalar…
Name[gu]=સ્થાપન...
Name[he]=התקנה...
Name[hi]=संस्थापित करें...
Name[hne]=इंस्टाल करव...
Name[hr]=Instaliraj…
Name[hsb]=instalować...
Name[hu]=Telepítés...
Name[ia]=Installa ...
Name[id]=Pasang...
Name[is]=Setja upp...
Name[it]=Installa...
Name[ja]=インストール...
Name[kk]=Орнату...
Name[km]=ដំឡើង...
Name[kn]=ಅನುಸ್ಢಾಪಿಸು...
Name[ko]=설치...
Name[ku]=Sazkirin...
Name[lt]=Įdiegti...
Name[lv]=Instalēt...
Name[mai]=संस्थापित करू...
Name[mk]=Инсталирање...
Name[ml]=ഇന്സ്റ്റോള് ചെയ്യുക...
Name[mr]=प्रतिष्ठापन...
Name[nb]=Installer …
Name[nds]=Installeren...
Name[ne]=स्थापना गर्नुहोस्
Name[nl]=Installeren...
Name[nn]=Installer …
Name[oc]=Installar...
Name[or]=ସ୍ଥାପନ କରନ୍ତୁ...
Name[pa]=ਇੰਸਟਾਲ...
Name[pl]=Wgraj...
Name[pt]=Instalar...
Name[pt_BR]=Instalar...
Name[ro]=Instalare...
Name[ru]=Установить...
Name[se]=Sajáiduhte …
Name[si]=ස්ථාපනය...
Name[sk]=Inštalovať...
Name[sl]=Namesti ...
Name[sr]=Инсталирај...
Name[sr@ijekavian]=Инсталирај...
Name[sr@ijekavianlatin]=Instaliraj...
Name[sr@latin]=Instaliraj...
Name[sv]=Installera...
Name[ta]=நிறுவுக...
Name[te]=సంస్థాపించు...
Name[tg]=Коргузорӣ...
Name[th]=ติดตั้ง...
Name[tr]=Yükle...
Name[ug]=ئورنات…
Name[uk]=Встановити...
Name[uz]=Oʻrnatish...
Name[uz@cyrillic]=Ўрнатиш...
Name[vi]=Cài đặt...
Name[wa]=Astaler...
Name[x-test]=xxInstall...xx
Name[zh_CN]=安装...
Name[zh_TW]=安裝...
Icon=preferences-desktop-font-installer
Exec=kfontinst %U
diff --git a/kcms/kfontinst/apps/org.kde.kfontview.desktop b/kcms/kfontinst/apps/org.kde.kfontview.desktop
index aa001a6b5..3d43913e0 100755
--- a/kcms/kfontinst/apps/org.kde.kfontview.desktop
+++ b/kcms/kfontinst/apps/org.kde.kfontview.desktop
@@ -1,191 +1,191 @@
[Desktop Entry]
Name=KFontView
Name[af]=KFontView
Name[ar]=عارض خطوطك
Name[be]=Прагляд шрыфтоў
Name[be@latin]=KFontView
Name[bg]=KFontView
Name[bn]=কে-ফন্ট-ভিউ
Name[bn_IN]=KFontView
Name[br]=KFontView
Name[bs]=K‑prikazivač-fontova
Name[ca]=KFontView
Name[ca@valencia]=KFontView
Name[cs]=Prohlížeč písem
Name[csb]=KFontView
Name[cy]=KFontView
Name[da]=KFontView
Name[de]=KFontView
Name[el]=KFontView
Name[en_GB]=KFontView
Name[eo]=KFontView
Name[es]=KFontView
Name[et]=KFontView
Name[eu]=KFontWiew
Name[fi]=KFontView
Name[fr]=KFontView
Name[fy]=KFontView
Name[ga]=KFontView
Name[gl]=KFontView
Name[gu]=KFontView
Name[he]=KFontView
Name[hi]=के-फ़ॉन्ट-व्यू
Name[hne]=के-फोंट-व्यू
Name[hr]=KFontView
Name[hsb]=KFontView
Name[hu]=KFontView
Name[ia]=KFontView
Name[id]=KFontView
Name[is]=KFontView
Name[it]=KFontView
Name[ja]=KFontView
Name[ka]=KFontView
Name[kk]=KFontView
Name[km]=KFontView
Name[kn]=ಕೆಫಾಂಟ್ ವ್ಯೂ
Name[ko]=KFontView
Name[ku]=KFontView
Name[lt]=KFontView
Name[lv]=KFontView
Name[mai]=के-फान्ट-व्यू
Name[mk]=КФонтПреглед
Name[ml]=കെഫോണ്ട്വ്യൂ
Name[mr]=केफॉन्टव्यू
Name[ms]=KFontView
Name[nb]=KFontView
Name[nds]=KFontView
Name[ne]=केडीई फन्ट दृश्य
Name[nl]=KFontView
Name[nn]=KFontView
Name[oc]=KFontView
Name[or]=KFontView
Name[pa]=KFontView
Name[pl]=KFontView
Name[pt]=KFontView
Name[pt_BR]=KFontView
Name[ro]=KFontView
Name[ru]=KFontView
Name[se]=Fontačájeheaddji
Name[si]=KFontView
Name[sk]=KFontView
Name[sl]=KFontView
Name[sr]=К‑приказивач-фонтова
Name[sr@ijekavian]=К‑приказивач-фонтова
Name[sr@ijekavianlatin]=K‑prikazivač-fontova
Name[sr@latin]=K‑prikazivač-fontova
Name[sv]=Kfontview
Name[ta]=KFontView
Name[te]=KFontView
Name[tg]=Намоиши ҳарф
Name[th]=ดูแบบอักษร-K
Name[tr]=KFontView
Name[ug]=KFontView
Name[uk]=KFontView
Name[uz]=KFontView
Name[uz@cyrillic]=KFontView
Name[vi]=KFonView
Name[wa]=Håyneu d' fontes
Name[x-test]=xxKFontViewxx
Name[zh_CN]=KFontView
Name[zh_TW]=KFontView
Exec=kfontview %U
Icon=kfontview
X-KDE-StartupNotify=true
Type=Application
-MimeType=application/x-font-ttf;application/x-font-type1;application/x-font-otf;application/x-font-pcf;application/x-font-bdf;application/vnd.kde.fontspackage;
+MimeType=application/x-font-ttf;application/x-font-type1;application/x-font-otf;application/x-font-pcf;application/x-font-bdf;application/vnd.kde.fontspackage;font/otf;font/ttf;
GenericName=Font Viewer
GenericName[af]=Skriftipe Besigter
GenericName[ar]=عارض الخطوط
GenericName[be]=Прагляд шрыфта
GenericName[be@latin]=Prahladnik šryftoŭ
GenericName[bg]=Преглед на шрифтове
GenericName[bn]=ফন্ট প্রদর্শক
GenericName[bn_IN]=ফন্ট প্রদর্শক
GenericName[br]=Gweler Nodrezhoù
GenericName[bs]=Prikazivač fontova
GenericName[ca]=Visor de tipus de lletra
GenericName[ca@valencia]=Visor de tipus de lletra
GenericName[cs]=Prohlížeč písem
GenericName[csb]=Przezérnik fòntów
GenericName[cy]=Gwelydd Wynebfathau
GenericName[da]=Skrifttypevisning
GenericName[de]=Schriftartenbetrachter
GenericName[el]=Προβολέας γραμματοσειρών
GenericName[en_GB]=Font Viewer
GenericName[eo]=Tipara rigardilo
GenericName[es]=Visor del tipo de letra
GenericName[et]=Fontide näitaja
GenericName[eu]=Letra-tipoen ikustailea
GenericName[fa]=مشاهدهگر قلم
GenericName[fi]=Fonttikatselin
GenericName[fr]=Afficheur de polices de caractères
GenericName[fy]=Lettertypewerjefte
GenericName[ga]=Amharcán Clónna
GenericName[gl]=Visor de tipos de letra
GenericName[gu]=ફોન્ટ દર્શક
GenericName[he]=מציג גופנים
GenericName[hi]=फ़ॉन्ट प्रदर्शक
GenericName[hne]=फोंट प्रदर्सक
GenericName[hr]=Preglednik fontova
GenericName[hsb]=Přehladowar za pisma
GenericName[hu]=Betűtípusböngésző
GenericName[ia]=Visor de fronte
GenericName[id]=Penampil Fonta
GenericName[is]=Leturskoðari
GenericName[it]=Visore di caratteri
GenericName[ja]=フォントビューア
GenericName[ka]=პროგრამა ფონტების სანახავად
GenericName[kk]=Қаріпті қарау құралы
GenericName[km]=កម្មវិធីមើលពុម្ពអក្សរ
GenericName[kn]=ಅಕ್ಷರಶೈಲಿ ವೀಕ್ಷಕ
GenericName[ko]=글꼴 뷰어
GenericName[ku]=Nîşandêra Curetîpan
GenericName[lt]=Šriftų žiūryklė
GenericName[lv]=Fontu skatītājs
GenericName[mai]=फान्ट प्रदर्शक
GenericName[mk]=Прегледувач на фонтови
GenericName[ml]=അക്ഷരസഞ്ചയദര്ശിനി
GenericName[mr]=फॉन्ट प्रदर्शक
GenericName[ms]=Pemapar Fon
GenericName[nb]=Skriftviser
GenericName[nds]=Schriftoortkieker
GenericName[ne]=फन्ट दर्शक
GenericName[nl]=Lettertypeweergave
GenericName[nn]=Skriftvisar
GenericName[or]=ଅକ୍ଷରରୂପ ପ୍ରଦର୍ଶକ
GenericName[pa]=ਫੋਂਟ ਦਰਸ਼ਕ
GenericName[pl]=Przeglądarka czcionek
GenericName[pt]=Visualizador do Tipo de Letra
GenericName[pt_BR]=Visualizador de fontes
GenericName[ro]=Vizualizator de fonturi
GenericName[ru]=Просмотр шрифтов
GenericName[se]=Fontačájeheaddji
GenericName[si]=අකුරු දසුන
GenericName[sk]=Prehliadač písiem
GenericName[sl]=Pregledovalnik pisav
GenericName[sr]=Приказивач фонтова
GenericName[sr@ijekavian]=Приказивач фонтова
GenericName[sr@ijekavianlatin]=Prikazivač fontova
GenericName[sr@latin]=Prikazivač fontova
GenericName[sv]=Teckensnittsvisning
GenericName[ta]=Font Viewer
GenericName[te]=ఫాంట్ వీక్షణి
GenericName[tg]=Намоишгари ҳарфҳо
GenericName[th]=ดูตัวอย่างแบบอักษร
GenericName[tr]=Yazı Tipi Görüntüleyici
GenericName[ug]=خەت نۇسخا كۆرگۈ
GenericName[uk]=Переглядач шрифтів
GenericName[uz]=Shrift koʻruvchi
GenericName[uz@cyrillic]=Шрифт кўрувчи
GenericName[vi]=Trình xem phông chữ
GenericName[wa]=Håyneu d' fontes
GenericName[x-test]=xxFont Viewerxx
GenericName[zh_CN]=字体查看器
GenericName[zh_TW]=字型檢視器
Terminal=false
InitialPreference=1
NoDisplay=true
Categories=Qt;KDE;Utility;
X-DBUS-StartupType=Unique
X-KDE-HasTempFileOption=true
X-DBUS-ServiceName=org.kde.kfontview
diff --git a/kcms/kfontinst/kcmfontinst/FontList.cpp b/kcms/kfontinst/kcmfontinst/FontList.cpp
index 4c5e434f0..64df0917a 100644
--- a/kcms/kfontinst/kcmfontinst/FontList.cpp
+++ b/kcms/kfontinst/kcmfontinst/FontList.cpp
@@ -1,2057 +1,2059 @@
/*
* KFontInst - KDE Font Installer
*
* Copyright 2003-2007 Craig Drummond
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "FontList.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "FcEngine.h"
#include "Fc.h"
#include "KfiConstants.h"
#include "GroupList.h"
#include "FontInstInterface.h"
#include "XmlStrings.h"
#include "Family.h"
#include "Style.h"
#include "File.h"
namespace KFI
{
-const QStringList CFontList::fontMimeTypes(QStringList() << "application/x-font-ttf"
+const QStringList CFontList::fontMimeTypes(QStringList() << "font/ttf"
+ << "font/otf"
+ << "application/x-font-ttf"
<< "application/x-font-otf"
<< "application/x-font-type1"
<< "application/x-font-pcf"
<< "application/x-font-bdf"
<< "application/vnd.kde.fontspackage");
static const int constMaxSlowed = 250;
static void decompose(const QString &name, QString &family, QString &style)
{
int commaPos=name.lastIndexOf(',');
family=-1==commaPos ? name : name.left(commaPos);
style=-1==commaPos ? KFI_WEIGHT_REGULAR : name.mid(commaPos+2);
}
static void addFont(CFontItem *font, CJobRunner::ItemList &urls, QStringList &fontNames,
QSet *fonts, QSet &usedFonts,
bool getEnabled, bool getDisabled)
{
if(!usedFonts.contains(font) &&
( (getEnabled && font->isEnabled()) ||
(getDisabled && !font->isEnabled()) ) )
{
urls.append(CJobRunner::Item(font->url(), font->name(), !font->isEnabled()));
fontNames.append(font->name());
usedFonts.insert(font);
if(fonts)
fonts->insert(Misc::TFont(font->family(), font->styleInfo()));
}
}
static QString replaceEnvVar(const QString &text)
{
QString mod(text);
int endPos(text.indexOf('/'));
if(endPos==-1)
endPos=text.length()-1;
else
endPos--;
if(endPos>0)
{
QString envVar(text.mid(1, endPos));
const char *val=getenv(envVar.toLatin1().constData());
if(val)
mod=Misc::fileSyntax(QFile::decodeName(val)+mod.mid(endPos+1));
}
return mod;
}
//
// Convert from list such as:
//
// Arial
// Arial, Bold
// Courier
// Times
// Times, Italic
//
// To:
//
// Arial (Regular, Bold)
// Coutier
// Times (Regular, Italic)
QStringList CFontList::compact(const QStringList &fonts)
{
QString lastFamily,
entry;
QStringList::ConstIterator it(fonts.begin()),
end(fonts.end());
QStringList compacted;
QSet usedStyles;
for(; it!=end; ++it)
{
QString family,
style;
decompose(*it, family, style);
if(family!=lastFamily)
{
usedStyles.clear();
if(entry.length())
{
entry+=')';
compacted.append(entry);
}
entry=QString(family+" (");
lastFamily=family;
}
if(!usedStyles.contains(style))
{
usedStyles.clear();
if(entry.length() && '('!=entry[entry.length()-1])
entry+=", ";
entry+=style;
usedStyles.insert(style);
}
}
if(entry.length())
{
entry+=')';
compacted.append(entry);
}
return compacted;
}
QString capitaliseFoundry(const QString &foundry)
{
QString f(foundry.toLower());
if(f==QLatin1String("ibm"))
return QLatin1String("IBM");
else if(f==QLatin1String("urw"))
return QLatin1String("URW");
else if(f==QLatin1String("itc"))
return QLatin1String("ITC");
else if(f==QLatin1String("nec"))
return QLatin1String("NEC");
else if(f==QLatin1String("b&h"))
return QLatin1String("B&H");
else if(f==QLatin1String("dec"))
return QLatin1String("DEC");
else
{
QChar *ch(f.data());
int len(f.length());
bool isSpace(true);
while(len--)
{
if (isSpace)
*ch=ch->toUpper();
isSpace=ch->isSpace();
++ch;
}
}
return f;
}
inline bool isSysFolder(const QString §)
{
return i18n(KFI_KIO_FONTS_SYS)==sect || KFI_KIO_FONTS_SYS==sect;
}
CFontItem::CFontItem(CFontModelItem *p, const Style &s, bool sys)
: CFontModelItem(p),
itsStyleName(FC::createStyleName(s.value())),
itsStyle(s)
{
refresh();
if(!Misc::root())
setIsSystem(sys);
}
void CFontItem::refresh()
{
FileCont::ConstIterator it(itsStyle.files().begin()),
end(itsStyle.files().end());
itsEnabled=false;
for(; it!=end; ++it)
if(!Misc::isHidden(Misc::getFile((*it).path())))
{
itsEnabled=true;
break;
}
}
CFamilyItem::CFamilyItem(CFontList &p, const Family &f, bool sys)
: CFontModelItem(NULL),
itsStatus(ENABLED),
itsRealStatus(ENABLED),
itsRegularFont(NULL),
itsParent(p)
{
itsName=f.name();
addFonts(f.styles(), sys);
//updateStatus();
}
CFamilyItem::~CFamilyItem()
{
qDeleteAll(itsFonts);
itsFonts.clear();
}
bool CFamilyItem::addFonts(const StyleCont &styles, bool sys)
{
StyleCont::ConstIterator it(styles.begin()),
end(styles.end());
bool modified=false;
for(; it!=end; ++it)
{
CFontItem *font=findFont((*it).value(), sys);
if(!font)
{
// New font style!
itsFonts.append(new CFontItem(this, *it, sys));
modified=true;
}
else
{
int before=(*it).files().size();
font->addFiles((*it).files());
if((*it).files().size()!=before)
{
modified=true;
font->refresh();
}
}
}
return modified;
}
CFontItem * CFamilyItem::findFont(quint32 style, bool sys)
{
CFontItemCont::ConstIterator fIt(itsFonts.begin()),
fEnd(itsFonts.end());
for(; fIt!=fEnd; ++fIt)
if((*(*fIt)).styleInfo()==style && (*(*fIt)).isSystem()==sys)
return (*fIt);
return NULL;
}
void CFamilyItem::getFoundries(QSet &foundries) const
{
CFontItemCont::ConstIterator it(itsFonts.begin()),
end(itsFonts.end());
for(; it!=end; ++it)
{
FileCont::ConstIterator fIt((*it)->files().begin()),
fEnd((*it)->files().end());
for(; fIt!=fEnd; ++fIt)
if(!(*fIt).foundry().isEmpty())
foundries.insert(capitaliseFoundry((*fIt).foundry()));
}
}
bool CFamilyItem::usable(const CFontItem *font, bool root)
{
return ( root ||
(font->isSystem() && itsParent.allowSys()) ||
(!font->isSystem() && itsParent.allowUser()));
}
void CFamilyItem::addFont(CFontItem *font, bool update)
{
itsFonts.append(font);
if(update)
{
updateStatus();
updateRegularFont(font);
}
}
void CFamilyItem::removeFont(CFontItem *font, bool update)
{
itsFonts.removeAll(font);
if(update)
updateStatus();
if(itsRegularFont==font)
{
itsRegularFont=NULL;
if(update)
updateRegularFont(NULL);
}
delete font;
}
void CFamilyItem::refresh()
{
updateStatus();
itsRegularFont=NULL;
updateRegularFont(NULL);
}
bool CFamilyItem::updateStatus()
{
bool root(Misc::root());
EStatus oldStatus(itsStatus);
CFontItemCont::ConstIterator it(itsFonts.begin()),
end(itsFonts.end());
int en(0), dis(0), allEn(0), allDis(0);
bool oldSys(isSystem()),
sys(false);
itsFontCount=0;
for(; it!=end; ++it)
if(usable(*it, root))
{
if((*it)->isEnabled())
en++;
else
dis++;
if(!sys)
sys=(*it)->isSystem();
itsFontCount++;
}
else
if((*it)->isEnabled())
allEn++;
else
allDis++;
allEn+=en;
allDis+=dis;
itsStatus=en && dis
? PARTIAL
: en
? ENABLED
: DISABLED;
itsRealStatus=allEn && allDis
? PARTIAL
: allEn
? ENABLED
: DISABLED;
if(!root)
setIsSystem(sys);
return itsStatus!=oldStatus || isSystem()!=oldSys;
}
bool CFamilyItem::updateRegularFont(CFontItem *font)
{
static const quint32 constRegular=FC::createStyleVal(FC_WEIGHT_REGULAR, KFI_FC_WIDTH_NORMAL, FC_SLANT_ROMAN);
CFontItem *oldFont(itsRegularFont);
bool root(Misc::root());
if(font && usable(font, root))
{
if(itsRegularFont)
{
int regDiff=abs((long)(itsRegularFont->styleInfo()-constRegular)),
fontDiff=abs((long)(font->styleInfo()-constRegular));
if(fontDiffstyleInfo()-constRegular));
if(diff)), SLOT(fontList(int,QList)));
}
CFontList::~CFontList()
{
qDeleteAll(itsFamilies);
itsFamilies.clear();
itsFamilyHash.clear();
}
void CFontList::dbusServiceOwnerChanged(const QString &name, const QString &from, const QString &to)
{
Q_UNUSED(from);
Q_UNUSED(to);
if(name==QLatin1String(OrgKdeFontinstInterface::staticInterfaceName()))
load();
}
void CFontList::fontList(int pid, const QList &families)
{
// printf("**** fontList:%d/%d %d\n", pid, getpid(), families.count());
if(pid==getpid())
{
QList::ConstIterator it(families.begin()),
end(families.end());
int count(families.size());
for(int i=0; it!=end; ++it, ++i)
{
fontsAdded(*it);
emit listingPercent(i*100/count);
}
emit listingPercent(100);
}
}
void CFontList::unsetSlowUpdates()
{
setSlowUpdates(false);
}
void CFontList::load()
{
for(int t=0; tlist(FontInst::SYS_MASK|FontInst::USR_MASK, getpid());
}
void CFontList::setSlowUpdates(bool slow)
{
if(itsSlowUpdates!=slow)
{
if(!slow)
for(int i=0; i families;
QDataStream ds(&encodedData, QIODevice::WriteOnly);
for(; it!=end; ++it)
if((*it).isValid())
{
if((static_cast((*it).internalPointer()))->isFont())
{
CFontItem *font=static_cast((*it).internalPointer());
families.insert(font->family());
}
else
{
CFamilyItem *fam=static_cast((*it).internalPointer());
families.insert(fam->name());
}
}
ds << families;
mimeData->setData(KFI_FONT_DRAG_MIME, encodedData);
return mimeData;
}
QStringList CFontList::mimeTypes() const
{
QStringList types;
types << "text/uri-list";
return types;
}
QVariant CFontList::headerData(int section, Qt::Orientation orientation,
int role) const
{
if (orientation == Qt::Horizontal)
switch(role)
{
case Qt::DisplayRole:
switch(section)
{
case COL_FONT:
return i18n("Font");
case COL_STATUS:
return i18n("Status");
default:
break;
}
break;
// case Qt::DecorationRole:
// if(COL_STATUS==section)
// return SmallIcon("fontstatus");
// break;
case Qt::TextAlignmentRole:
return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
case Qt::ToolTipRole:
if(COL_STATUS==section)
return i18n("This column shows the status of the font family, and of the "
"individual font styles.");
break;
case Qt::WhatsThisRole:
return whatsThis();
default:
break;
}
return QVariant();
}
QModelIndex CFontList::index(int row, int column, const QModelIndex &parent) const
{
if(parent.isValid()) // Then font...
{
CFamilyItem *fam=static_cast(parent.internalPointer());
if(rowfonts().count())
return createIndex(row, column, fam->fonts().at(row));
}
else // Family....
if(row(index.internalPointer());
if(mi->isFamily())
return QModelIndex();
else
{
CFontItem *font=static_cast(index.internalPointer());
return createIndex(itsFamilies.indexOf(((CFamilyItem *)font->parent())), 0, font->parent());
}
}
int CFontList::rowCount(const QModelIndex &parent) const
{
if(parent.isValid())
{
CFontModelItem *mi=static_cast(parent.internalPointer());
if(mi->isFont())
return 0;
CFamilyItem *fam=static_cast(parent.internalPointer());
return fam->fonts().count();
}
else
return itsFamilies.count();
}
void CFontList::refresh(bool allowSys, bool allowUser)
{
itsAllowSys=allowSys;
itsAllowUser=allowUser;
CFamilyItemCont::ConstIterator it(itsFamilies.begin()),
end(itsFamilies.end());
for(; it!=end; ++it)
(*it)->refresh();
}
void CFontList::getFamilyStats(QSet &enabled, QSet &disabled, QSet &partial)
{
CFamilyItemCont::ConstIterator it(itsFamilies.begin()),
end(itsFamilies.end());
for(; it!=end; ++it)
{
switch((*it)->realStatus())
{
case CFamilyItem::ENABLED:
enabled.insert((*it)->name());
break;
case CFamilyItem::PARTIAL:
partial.insert((*it)->name());
break;
case CFamilyItem::DISABLED:
disabled.insert((*it)->name());
break;
}
}
}
void CFontList::getFoundries(QSet &foundries) const
{
CFamilyItemCont::ConstIterator it(itsFamilies.begin()),
end(itsFamilies.end());
for(; it!=end; ++it)
(*it)->getFoundries(foundries);
}
QString CFontList::whatsThis() const
{
return i18n("This list shows your installed fonts. The fonts are grouped by family, and the"
" number in square brackets represents the number of styles in which the family is"
" available. e.g.
"
""
"- Times [4]"
"
- Regular
"
"- Bold
"
"- Bold Italic
"
"- Italic
"
"
"
" "
"
");
}
void CFontList::fontsAdded(const KFI::Families &families)
{
// printf("**** FONT ADDED:%d\n", families.items.count());
if(itsSlowUpdates)
storeSlowedMessage(families, MSG_ADD);
else
addFonts(families.items, families.isSystem && !Misc::root());
}
void CFontList::fontsRemoved(const KFI::Families &families)
{
// printf("**** FONT REMOVED:%d\n", families.items.count());
if(itsSlowUpdates)
storeSlowedMessage(families, MSG_DEL);
else
removeFonts(families.items, families.isSystem && !Misc::root());
}
void CFontList::storeSlowedMessage(const Families &families, EMsgType type)
{
int folder=families.isSystem ? FontInst::FOLDER_SYS : FontInst::FOLDER_USER;
bool playOld=false;
for(int i=0; iconstMaxSlowed)
playOld=true;
if(playOld)
actionSlowedUpdates(families.isSystem);
FamilyCont::ConstIterator family(families.items.begin()),
fend(families.items.end());
for(; family!=fend; ++family)
{
FamilyCont::ConstIterator f=itsSlowedMsgs[type][folder].find(*family);
if(f!=itsSlowedMsgs[type][folder].end())
{
StyleCont::ConstIterator style((*family).styles().begin()),
send((*family).styles().end());
for(; style!=send; ++style)
{
StyleCont::ConstIterator st=(*f).styles().find(*style);
if(st==(*f).styles().end())
(*f).add(*style);
else
(*st).addFiles((*style).files());
}
}
else
itsSlowedMsgs[type][folder].insert(*family);
}
}
void CFontList::actionSlowedUpdates(bool sys)
{
int folder=sys ? FontInst::FOLDER_SYS : FontInst::FOLDER_USER;
for(int i=0; i modifiedFamilies;
for(; family!=end; ++family)
{
if((*family).styles().count()>0)
{
CFamilyItem *famItem=findFamily((*family).name());
if(famItem)
{
int rowFrom=famItem->fonts().count();
if(famItem->addFonts((*family).styles(), sys))
{
int rowTo=famItem->fonts().count();
if(rowTo!=rowFrom)
{
beginInsertRows(createIndex(famItem->rowNumber(), 0, famItem), rowFrom, rowTo);
endInsertRows();
}
modifiedFamilies.insert(famItem);
}
}
else
{
famItem=new CFamilyItem(*this, *family, sys);
itsFamilies.append(famItem);
itsFamilyHash[famItem->name()]=famItem;
modifiedFamilies.insert(famItem);
}
}
}
int famRowTo=itsFamilies.count();
if(famRowTo!=famRowFrom)
{
beginInsertRows(QModelIndex(), famRowFrom, famRowTo);
endInsertRows();
}
if(!modifiedFamilies.isEmpty())
{
QSet::Iterator it(modifiedFamilies.begin()),
end(modifiedFamilies.end());
for(; it!=end; ++it)
(*it)->refresh();
}
// if(emitLayout)
// emit layoutChanged();
}
void CFontList::removeFonts(const FamilyCont &families, bool sys)
{
// if(!itsSlowUpdates)
// emit layoutAboutToBeChanged();
FamilyCont::ConstIterator family(families.begin()),
end(families.end());
QSet modifiedFamilies;
for(; family!=end; ++family)
{
if((*family).styles().count()>0)
{
CFamilyItem *famItem=findFamily((*family).name());
if(famItem)
{
StyleCont::ConstIterator it((*family).styles().begin()),
end((*family).styles().end());
for(; it!=end; ++it)
{
CFontItem *fontItem=famItem->findFont((*it).value(), sys);
if(fontItem)
{
int before=fontItem->files().count();
fontItem->removeFiles((*it).files());
if(fontItem->files().count()!=before)
{
if(fontItem->files().isEmpty())
{
int row=-1;
if(1!=famItem->fonts().count())
{
row=fontItem->rowNumber();
beginRemoveRows(createIndex(famItem->rowNumber(), 0, famItem), row, row);
}
famItem->removeFont(fontItem, false);
if(-1!=row)
endRemoveRows();
}
else
fontItem->refresh();
}
}
}
if(famItem->fonts().isEmpty())
{
int row=famItem->rowNumber();
beginRemoveRows(QModelIndex(), row, row);
itsFamilyHash.remove(famItem->name());
itsFamilies.removeAt(row);
endRemoveRows();
}
else
modifiedFamilies.insert(famItem);
}
}
}
if(!modifiedFamilies.isEmpty())
{
QSet::Iterator it(modifiedFamilies.begin()),
end(modifiedFamilies.end());
for(; it!=end; ++it)
(*it)->refresh();
}
// if(!itsSlowUpdates)
// emit layoutChanged();
}
CFamilyItem * CFontList::findFamily(const QString &familyName)
{
CFamilyItemHash::Iterator it=itsFamilyHash.find(familyName);
return it==itsFamilyHash.end() ? 0L : *it;
}
inline bool matchString(const QString &str, const QString &pattern)
{
return pattern.isEmpty() || -1!=str.indexOf(pattern, 0, Qt::CaseInsensitive);
}
CFontListSortFilterProxy::CFontListSortFilterProxy(QObject *parent, QAbstractItemModel *model)
: QSortFilterProxyModel(parent),
itsGroup(NULL),
itsFilterCriteria(CFontFilter::CRIT_FAMILY),
itsFilterWs(0),
itsFcQuery(NULL)
{
setSourceModel(model);
setSortCaseSensitivity(Qt::CaseInsensitive);
setFilterKeyColumn(0);
setDynamicSortFilter(false);
itsTimer=new QTimer(this);
connect(itsTimer, SIGNAL(timeout()), SLOT(timeout()));
connect(model, SIGNAL(layoutChanged()), SLOT(invalidate()));
itsTimer->setSingleShot(true);
}
QVariant CFontListSortFilterProxy::data(const QModelIndex &idx, int role) const
{
if (!idx.isValid())
return QVariant();
static const int constMaxFiles=20;
QModelIndex index(mapToSource(idx));
CFontModelItem *mi=static_cast(index.internalPointer());
if(!mi)
return QVariant();
switch(role)
{
case Qt::ToolTipRole:
if(CFontFilter::CRIT_FILENAME==itsFilterCriteria || CFontFilter::CRIT_LOCATION==itsFilterCriteria ||
CFontFilter::CRIT_FONTCONFIG==itsFilterCriteria)
{
if(mi->isFamily())
{
CFamilyItem *fam=static_cast(index.internalPointer());
CFontItemCont::ConstIterator it(fam->fonts().begin()),
end(fam->fonts().end());
FileCont allFiles;
QString tip(""+fam->name()+"");
bool markMatch(CFontFilter::CRIT_FONTCONFIG==itsFilterCriteria);
tip+="";
for(; it!=end; ++it)
allFiles+=(*it)->files();
//qSort(allFiles);
FileCont::ConstIterator fit(allFiles.begin()),
fend(allFiles.end());
for(int i=0; fit!=fend && ifile())
tip+=""+Misc::contractHome((*fit).path())+" |
";
else
tip+=""+Misc::contractHome((*fit).path())+" |
";
if(allFiles.count()>constMaxFiles)
tip+=""+i18n("...plus %1 more", allFiles.count()-constMaxFiles)+" |
";
tip+="
";
return tip;
}
else
{
CFontItem *font=static_cast(index.internalPointer());
QString tip(""+font->name()+"");
const FileCont &files(font->files());
bool markMatch(CFontFilter::CRIT_FONTCONFIG==itsFilterCriteria);
tip+="";
//qSort(files);
FileCont::ConstIterator fit(files.begin()),
fend(files.end());
for(int i=0; fit!=fend && ifile())
tip+=""+Misc::contractHome((*fit).path())+" |
";
else
tip+=""+Misc::contractHome((*fit).path() )+" |
";
if(files.count()>constMaxFiles)
tip+=""+i18n("...plus %1 more", files.count()-constMaxFiles)+" |
";
tip+="
";
return tip;
}
}
break;
case Qt::FontRole:
if(COL_FONT==index.column() && mi->isSystem())
{
QFont font;
font.setItalic(true);
return font;
}
break;
case Qt::ForegroundRole:
if(COL_FONT==index.column() &&
( (mi->isFont() && !(static_cast(index.internalPointer()))->isEnabled()) ||
(mi->isFamily() && CFamilyItem::DISABLED==(static_cast(index.internalPointer()))->status())) )
return KColorScheme(QPalette::Active).foreground(KColorScheme::NegativeText).color();
break;
case Qt::DisplayRole:
if(COL_FONT==index.column())
{
if(mi->isFamily())
{
CFamilyItem *fam=static_cast(index.internalPointer());
return i18n("%1 [%2]", fam->name(), fam->fontCount());
}
else
return (static_cast(index.internalPointer()))->style();
}
break;
case Qt::DecorationRole:
if(mi->isFamily())
{
CFamilyItem *fam=static_cast(index.internalPointer());
switch(index.column())
{
case COL_STATUS:
switch(fam->status())
{
case CFamilyItem::PARTIAL:
return SmallIcon("dialog-ok", 0, KIconLoader::DisabledState);
case CFamilyItem::ENABLED:
return SmallIcon("dialog-ok");
case CFamilyItem::DISABLED:
return SmallIcon("dialog-cancel");
}
break;
default:
break;
}
}
else if(COL_STATUS==index.column())
return SmallIcon( (static_cast(index.internalPointer()))->isEnabled()
? "dialog-ok" : "dialog-cancel", 10);
break;
case Qt::SizeHintRole:
if(mi->isFamily()) {
const int s = KIconLoader::global()->currentSize(KIconLoader::Small);
return QSize(s, s + 4);
}
default:
break;
}
return QVariant();
}
bool CFontListSortFilterProxy::acceptFont(CFontItem *fnt, bool checkFontText) const
{
if(itsGroup && (CGroupListItem::ALL!=itsGroup->type() || (!filterText().isEmpty() && checkFontText)))
{
bool fontMatch(!checkFontText);
if(!fontMatch)
switch(itsFilterCriteria)
{
case CFontFilter::CRIT_FONTCONFIG:
fontMatch=itsFcQuery
? fnt->name()==itsFcQuery->font() // || fnt->files().contains(itsFcQuery->file())
: false;
break;
case CFontFilter::CRIT_STYLE:
fontMatch=matchString(fnt->style(), itsFilterText);
break;
case CFontFilter::CRIT_FOUNDRY:
{
FileCont::ConstIterator it(fnt->files().begin()),
end(fnt->files().end());
for(; it!=end && !fontMatch; ++it)
fontMatch=0==(*it).foundry().compare(itsFilterText, Qt::CaseInsensitive);
break;
}
case CFontFilter::CRIT_FILENAME:
{
FileCont::ConstIterator it(fnt->files().begin()),
end(fnt->files().end());
for(; it!=end && !fontMatch; ++it)
{
QString file(Misc::getFile((*it).path()));
int pos(Misc::isHidden(file) ? 1 : 0);
if(pos==file.indexOf(itsFilterText, pos, Qt::CaseInsensitive))
fontMatch=true;
}
break;
}
case CFontFilter::CRIT_LOCATION:
{
FileCont::ConstIterator it(fnt->files().begin()),
end(fnt->files().end());
for(; it!=end && !fontMatch; ++it)
if(0==Misc::getDir((*it).path()).indexOf(itsFilterText, 0, Qt::CaseInsensitive))
fontMatch=true;
break;
}
case CFontFilter::CRIT_FILETYPE:
{
FileCont::ConstIterator it(fnt->files().begin()),
end(fnt->files().end());
QStringList::ConstIterator mimeEnd(itsFilterTypes.constEnd());
for(; it!=end && !fontMatch; ++it)
{
QStringList::ConstIterator mime(itsFilterTypes.constBegin());
for(; mime!=mimeEnd; ++mime)
if(Misc::checkExt((*it).path(), *mime))
fontMatch=true;
}
break;
}
case CFontFilter::CRIT_WS:
fontMatch=fnt->writingSystems()&itsFilterWs;
break;
default:
break;
}
return fontMatch && itsGroup->hasFont(fnt);
}
return true;
}
bool CFontListSortFilterProxy::acceptFamily(CFamilyItem *fam) const
{
CFontItemCont::ConstIterator it(fam->fonts().begin()),
end(fam->fonts().end());
bool familyMatch(CFontFilter::CRIT_FAMILY==itsFilterCriteria &&
matchString(fam->name(), itsFilterText));
for(; it!=end; ++it)
if(acceptFont(*it, !familyMatch))
return true;
return false;
}
bool CFontListSortFilterProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
QModelIndex index(sourceModel()->index(sourceRow, 0, sourceParent));
if(index.isValid())
{
CFontModelItem *mi=static_cast(index.internalPointer());
if(mi->isFont())
{
CFontItem *font=static_cast(index.internalPointer());
return acceptFont(font, !(CFontFilter::CRIT_FAMILY==itsFilterCriteria &&
matchString(font->family(), itsFilterText)));
}
else
return acceptFamily(static_cast(index.internalPointer()));
}
return false;
}
bool CFontListSortFilterProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
if(left.isValid() && right.isValid())
{
CFontModelItem *lmi=static_cast(left.internalPointer()),
*rmi=static_cast(right.internalPointer());
if(lmi->isFont()isFont())
return true;
if(lmi->isFont())
{
CFontItem *lfi=static_cast(left.internalPointer()),
*rfi=static_cast(right.internalPointer());
if(COL_STATUS==filterKeyColumn())
{
if(lfi->isEnabled()isEnabled() ||
(lfi->isEnabled()==rfi->isEnabled() &&
lfi->styleInfo()styleInfo()))
return true;
}
else
if(lfi->styleInfo()styleInfo())
return true;
}
else
{
CFamilyItem *lfi=static_cast(left.internalPointer()),
*rfi=static_cast(right.internalPointer());
if(COL_STATUS==filterKeyColumn())
{
if(lfi->status()status() ||
(lfi->status()==rfi->status() && QString::localeAwareCompare(lfi->name(), rfi->name())<0))
return true;
}
else
if(QString::localeAwareCompare(lfi->name(), rfi->name())<0)
return true;
}
}
return false;
}
void CFontListSortFilterProxy::setFilterGroup(CGroupListItem *grp)
{
if(grp!=itsGroup)
{
// bool wasNull=!itsGroup;
itsGroup=grp;
// if(!(wasNull && itsGroup && CGroupListItem::ALL==itsGroup->type()))
clear();
}
}
void CFontListSortFilterProxy::setFilterText(const QString &text)
{
if(text!=itsFilterText)
{
//
// If we are filtering on file location, then expand ~ to /home/user, etc.
if (CFontFilter::CRIT_LOCATION==itsFilterCriteria && !text.isEmpty() && ('~'==text[0] || '$'==text[0]))
if('~'==text[0])
itsFilterText=1==text.length()
? QDir::homePath()
: QString(text).replace(0, 1, QDir::homePath());
else
itsFilterText=replaceEnvVar(text);
else
itsFilterText=text;
if(itsFilterText.isEmpty())
{
itsTimer->stop();
timeout();
}
else
itsTimer->start(CFontFilter::CRIT_FONTCONFIG==itsFilterCriteria ? 750 : 400);
}
}
void CFontListSortFilterProxy::setFilterCriteria(CFontFilter::ECriteria crit, qulonglong ws, const QStringList &ft)
{
if(crit!=itsFilterCriteria || ws!=itsFilterWs || ft!=itsFilterTypes)
{
itsFilterWs=ws;
itsFilterCriteria=crit;
itsFilterTypes=ft;
if(CFontFilter::CRIT_LOCATION==itsFilterCriteria)
setFilterText(itsFilterText);
itsTimer->stop();
timeout();
}
}
void CFontListSortFilterProxy::timeout()
{
if(CFontFilter::CRIT_FONTCONFIG==itsFilterCriteria)
{
int commaPos=itsFilterText.indexOf(',');
QString query(itsFilterText);
if(-1!=commaPos)
{
QString style(query.mid(commaPos+1));
query=query.left(commaPos);
query=query.trimmed();
query+=":style=";
style=style.trimmed();
query+=style;
}
else
query=query.trimmed();
if(!itsFcQuery)
{
itsFcQuery=new CFcQuery(this);
connect(itsFcQuery, SIGNAL(finished()), SLOT(fcResults()));
}
itsFcQuery->run(query);
}
else
{
clear();
emit refresh();
}
}
void CFontListSortFilterProxy::fcResults()
{
if(CFontFilter::CRIT_FONTCONFIG==itsFilterCriteria)
{
clear();
emit refresh();
}
}
CFontListView::CFontListView(QWidget *parent, CFontList *model)
: QTreeView(parent),
itsProxy(new CFontListSortFilterProxy(this, model)),
itsModel(model),
itsAllowDrops(false)
{
setModel(itsProxy);
itsModel=model;
header()->setStretchLastSection(false);
resizeColumnToContents(COL_STATUS);
header()->setResizeMode(COL_STATUS, QHeaderView::Fixed);
header()->setResizeMode(COL_FONT, QHeaderView::Stretch);
setSelectionMode(QAbstractItemView::ExtendedSelection);
setSelectionBehavior(QAbstractItemView::SelectRows);
setSortingEnabled(true);
sortByColumn(COL_FONT, Qt::AscendingOrder);
setAllColumnsShowFocus(true);
setAlternatingRowColors(true);
setAcceptDrops(true);
setDropIndicatorShown(false);
setDragEnabled(true);
setDragDropMode(QAbstractItemView::DragDrop);
header()->setClickable(true);
header()->setSortIndicatorShown(true);
connect(this, SIGNAL(collapsed(QModelIndex)), SLOT(itemCollapsed(QModelIndex)));
connect(header(), SIGNAL(sectionClicked(int)), SLOT(setSortColumn(int)));
connect(itsProxy, SIGNAL(refresh()), SIGNAL(refresh()));
connect(itsModel, SIGNAL(listingPercent(int)), SLOT(listingPercent(int)));
setWhatsThis(model->whatsThis());
header()->setWhatsThis(whatsThis());
itsMenu=new QMenu(this);
itsDeleteAct=itsMenu->addAction(QIcon::fromTheme("edit-delete"), i18n("Delete"),
this, SIGNAL(del()));
itsMenu->addSeparator();
itsEnableAct=itsMenu->addAction(QIcon::fromTheme("enablefont"), i18n("Enable"),
this, SIGNAL(enable()));
itsDisableAct=itsMenu->addAction(QIcon::fromTheme("disablefont"), i18n("Disable"),
this, SIGNAL(disable()));
if(!Misc::app(KFI_VIEWER).isEmpty())
itsMenu->addSeparator();
itsPrintAct=Misc::app(KFI_VIEWER).isEmpty() ? 0L : itsMenu->addAction(QIcon::fromTheme("document-print"), i18n("Print..."),
this, SIGNAL(print()));
itsViewAct=Misc::app(KFI_VIEWER).isEmpty() ? 0L : itsMenu->addAction(QIcon::fromTheme("kfontview"), i18n("Open in Font Viewer"),
this, SLOT(view()));
itsMenu->addSeparator();
itsMenu->addAction(QIcon::fromTheme("view-refresh"), i18n("Reload"), model, SLOT(load()));
}
void CFontListView::getFonts(CJobRunner::ItemList &urls, QStringList &fontNames, QSet *fonts,
bool selected, bool getEnabled, bool getDisabled)
{
QModelIndexList selectedItems(selected ? selectedIndexes() : allIndexes());
QSet usedFonts;
QModelIndex index;
foreach(index, selectedItems)
if(index.isValid())
{
QModelIndex realIndex(itsProxy->mapToSource(index));
if(realIndex.isValid())
{
if((static_cast(realIndex.internalPointer()))->isFont())
{
CFontItem *font=static_cast(realIndex.internalPointer());
addFont(font, urls, fontNames, fonts, usedFonts,
getEnabled, getDisabled);
}
else
{
CFamilyItem *fam=static_cast(realIndex.internalPointer());
for(int ch=0; chfontCount(); ++ch)
{
QModelIndex child(itsProxy->mapToSource(index.child(ch, 0)));
if(child.isValid() &&
(static_cast(child.internalPointer()))->isFont())
{
CFontItem *font=static_cast(child.internalPointer());
addFont(font, urls, fontNames, fonts, usedFonts,
getEnabled, getDisabled);
}
}
}
}
}
fontNames=CFontList::compact(fontNames);
}
QSet CFontListView::getFiles()
{
QModelIndexList items(allIndexes());
QModelIndex index;
QSet files;
foreach(index, items)
if(index.isValid())
{
QModelIndex realIndex(itsProxy->mapToSource(index));
if(realIndex.isValid())
if((static_cast(realIndex.internalPointer()))->isFont())
{
CFontItem *font=static_cast(realIndex.internalPointer());
FileCont::ConstIterator it(font->files().begin()),
end(font->files().end());
for(; it!=end; ++it)
{
QStringList assoc;
files.insert((*it).path());
Misc::getAssociatedFiles((*it).path(), assoc);
QStringList::ConstIterator ait(assoc.constBegin()),
aend(assoc.constEnd());
for(; ait!=aend; ++ait)
files.insert(*ait);
}
}
}
return files;
}
void CFontListView::getPrintableFonts(QSet &items, bool selected)
{
QModelIndexList selectedItems(selected ? selectedIndexes() : allIndexes());
QModelIndex index;
foreach(index, selectedItems)
{
CFontItem *font=NULL;
if(index.isValid() && 0==index.column())
{
QModelIndex realIndex(itsProxy->mapToSource(index));
if(realIndex.isValid())
{
if((static_cast(realIndex.internalPointer()))->isFont())
font=static_cast(realIndex.internalPointer());
else
{
CFamilyItem *fam=static_cast(realIndex.internalPointer());
font=fam->regularFont();
}
}
}
if(font && !font->isBitmap() && font->isEnabled())
items.insert(Misc::TFont(font->family(), font->styleInfo()));
}
}
void CFontListView::setFilterGroup(CGroupListItem *grp)
{
CGroupListItem *oldGrp(itsProxy->filterGroup());
itsProxy->setFilterGroup(grp);
itsAllowDrops=grp && !grp->isCustom();
if(!Misc::root())
{
bool refreshStats(false);
if(!grp || !oldGrp)
refreshStats=true;
else
{
// Check to see whether we have changed from listing all fonts,
// listing just system or listing personal fonts.
CGroupListItem::EType aType(CGroupListItem::CUSTOM==grp->type() ||
CGroupListItem::ALL==grp->type() ||
CGroupListItem::UNCLASSIFIED==grp->type()
? CGroupListItem::CUSTOM : grp->type()),
bType(CGroupListItem::CUSTOM==oldGrp->type() ||
CGroupListItem::ALL==oldGrp->type() ||
CGroupListItem::UNCLASSIFIED==oldGrp->type()
? CGroupListItem::CUSTOM : oldGrp->type());
refreshStats=aType!=bType;
}
if(refreshStats)
itsModel->refresh(!grp || !grp->isPersonal(),
!grp || !grp->isSystem());
}
// when switching groups, for some reason it is not always sorted.
setSortingEnabled(true);
}
void CFontListView::listingPercent(int percent)
{
// when the font list is first loaded, for some reason it is not always sorted.
// re-enabling sorting here seems to fix the issue - BUG 221610
if(100==percent)
setSortingEnabled(true);
}
void CFontListView::refreshFilter()
{
itsProxy->clear();
}
void CFontListView::filterText(const QString &text)
{
itsProxy->setFilterText(text);
}
void CFontListView::filterCriteria(int crit, qulonglong ws, const QStringList &ft)
{
itsProxy->setFilterCriteria((CFontFilter::ECriteria)crit, ws, ft);
}
void CFontListView::stats(int &enabled, int &disabled, int &partial)
{
enabled=disabled=partial=0;
for(int i=0; irowCount(); ++i)
{
QModelIndex idx(itsProxy->index(i, 0, QModelIndex()));
if(!idx.isValid())
break;
QModelIndex sourceIdx(itsProxy->mapToSource(idx));
if(!sourceIdx.isValid())
break;
if((static_cast(sourceIdx.internalPointer()))->isFamily())
switch((static_cast(sourceIdx.internalPointer()))->status())
{
case CFamilyItem::ENABLED:
enabled++;
break;
case CFamilyItem::DISABLED:
disabled++;
break;
case CFamilyItem::PARTIAL:
partial++;
break;
}
}
}
void CFontListView::selectedStatus(bool &enabled, bool &disabled)
{
QModelIndexList selected(selectedIndexes());
QModelIndex index;
enabled=disabled=false;
foreach(index, selected)
{
QModelIndex realIndex(itsProxy->mapToSource(index));
if(realIndex.isValid())
{
if((static_cast(realIndex.internalPointer()))->isFamily())
{
switch((static_cast(realIndex.internalPointer()))->status())
{
case CFamilyItem::ENABLED:
enabled=true;
break;
case CFamilyItem::DISABLED:
disabled=true;
break;
case CFamilyItem::PARTIAL:
enabled=true;
disabled=true;
break;
}
}
else
{
if((static_cast(realIndex.internalPointer()))->isEnabled())
enabled=true;
else
disabled=true;
}
}
if(enabled && disabled)
break;
}
}
QModelIndexList CFontListView::allFonts()
{
QModelIndexList rv;
int rowCount(itsProxy->rowCount());
for(int i=0; iindex(i, 0, QModelIndex()));
int childRowCount(itsProxy->rowCount(idx));
for(int j=0; jindex(j, 0, idx));
if(child.isValid())
rv.append(itsProxy->mapToSource(child));
}
}
return rv;
}
void CFontListView::selectFirstFont()
{
if(0==selectedIndexes().count())
for(int i=0; iindex(0, i, QModelIndex()));
if(idx.isValid())
selectionModel()->select(idx, QItemSelectionModel::Select);
}
}
void CFontListView::setSortColumn(int col)
{
if(col!=itsProxy->filterKeyColumn())
{
itsProxy->setFilterKeyColumn(col);
itsProxy->clear();
}
}
void CFontListView::selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected)
{
QAbstractItemView::selectionChanged(selected, deselected);
if(itsModel->slowUpdates())
return;
emit itemsSelected(getSelectedItems());
}
QModelIndexList CFontListView::getSelectedItems()
{
//
// Go throgh current selection, and for any 'font' items that are selected,
// ensure 'family' item is not...
QModelIndexList selectedItems(selectedIndexes()),
deselectList;
QModelIndex index;
QSet selectedFamilies;
bool en(false),
dis(false);
foreach(index, selectedItems)
if(index.isValid())
{
QModelIndex realIndex(itsProxy->mapToSource(index));
if(realIndex.isValid())
{
if((static_cast(realIndex.internalPointer()))->isFont())
{
CFontItem *font=static_cast(realIndex.internalPointer());
if(font->isEnabled())
en=true;
else
dis=true;
if(!selectedFamilies.contains(font->parent()))
{
selectedFamilies.insert(font->parent());
for(int i=0; imapFromSource(
itsModel->createIndex(font->parent()->rowNumber(),
i, font->parent())));
}
}
else
{
switch((static_cast(realIndex.internalPointer()))->status())
{
case CFamilyItem::ENABLED:
en=true;
break;
case CFamilyItem::DISABLED:
dis=true;
break;
case CFamilyItem::PARTIAL:
en=dis=true;
break;
}
}
}
}
if(deselectList.count())
foreach(index, deselectList)
selectionModel()->select(index, QItemSelectionModel::Deselect);
QModelIndexList sel;
QSet pointers;
selectedItems=selectedIndexes();
foreach(index, selectedItems)
{
QModelIndex idx(itsProxy->mapToSource(index));
if(!pointers.contains(idx.internalPointer()))
{
pointers.insert(idx.internalPointer());
sel.append(idx);
}
}
return sel;
}
void CFontListView::itemCollapsed(const QModelIndex &idx)
{
if(idx.isValid())
{
QModelIndex index(itsProxy->mapToSource(idx));
if(index.isValid() && (static_cast(index.internalPointer()))->isFamily())
{
CFamilyItem *fam=static_cast(index.internalPointer());
CFontItemCont::ConstIterator it(fam->fonts().begin()),
end(fam->fonts().end());
for(; it!=end; ++it)
for(int i=0; iselect(itsProxy->mapFromSource(itsModel->createIndex((*it)->rowNumber(),
i, *it)),
QItemSelectionModel::Deselect);
}
}
}
static bool isScalable(const QString &str)
{
QByteArray cFile(QFile::encodeName(str));
return Misc::checkExt(cFile, "ttf") || Misc::checkExt(cFile, "otf") || Misc::checkExt(cFile, "ttc") ||
Misc::checkExt(cFile, "pfa") || Misc::checkExt(cFile, "pfb");
}
void CFontListView::view()
{
// Number of fonts user has selected, before we ask if they really want to view them all...
static const int constMaxBeforePrompt=10;
QModelIndexList selectedItems(selectedIndexes());
QModelIndex index;
QSet fonts;
foreach(index, selectedItems)
{
QModelIndex realIndex(itsProxy->mapToSource(index));
if(realIndex.isValid())
{
if((static_cast(realIndex.internalPointer()))->isFont())
{
CFontItem *font(static_cast(realIndex.internalPointer()));
fonts.insert(font);
}
else
{
CFontItem *font((static_cast(realIndex.internalPointer()))->regularFont());
if(font)
fonts.insert(font);
}
}
}
if(fonts.count() &&
(fonts.count()::ConstIterator it(fonts.begin()),
end(fonts.end());
QStringList args;
for(; it!=end; ++it)
{
QString file;
int index(0);
if(!(*it)->isEnabled())
{
// For a disabled font, we need to find the first scalable font entry in its file list...
FileCont::ConstIterator fit((*it)->files().begin()),
fend((*it)->files().end());
for(; fit!=fend; ++fit)
if(isScalable((*fit).path()))
{
file=(*fit).path();
index=(*fit).index();
break;
}
if(file.isEmpty())
{
file=(*it)->fileName();
index=(*it)->index();
}
}
args << FC::encode((*it)->family(), (*it)->styleInfo(), file, index).url();
}
QProcess::startDetached(Misc::app(KFI_VIEWER), args);
}
}
QModelIndexList CFontListView::allIndexes()
{
QModelIndexList rv;
int rowCount(itsProxy->rowCount());
for(int i=0; iindex(i, 0, QModelIndex()));
int childRowCount(itsProxy->rowCount(idx));
rv.append(idx);
for(int j=0; jindex(j, 0, idx));
if(child.isValid())
rv.append(child);
}
}
return rv;
}
void CFontListView::startDrag(Qt::DropActions supportedActions)
{
QModelIndexList indexes(selectedIndexes());
if (indexes.count())
{
QMimeData *data = model()->mimeData(indexes);
if (!data)
return;
QModelIndex index(itsProxy->mapToSource(indexes.first()));
const char *icon="application-x-font-pcf";
if(index.isValid())
{
CFontItem *font=(static_cast(index.internalPointer()))->isFont()
? static_cast(index.internalPointer())
: (static_cast(index.internalPointer()))->regularFont();
if(font && !font->isBitmap())
// if("application/x-font-type1"==font->mimetype())
// icon="application-x-font-type1";
// else
icon="application-x-font-ttf";
}
QPoint hotspot;
QPixmap pix(DesktopIcon(icon, KIconLoader::SizeMedium));
hotspot.setX(0); // pix.width()/2);
hotspot.setY(0); // pix.height()/2);
QDrag *drag = new QDrag(this);
drag->setPixmap(pix);
drag->setMimeData(data);
drag->setHotSpot(hotspot);
drag->start(supportedActions);
}
}
void CFontListView::dragEnterEvent(QDragEnterEvent *event)
{
if(itsAllowDrops && event->mimeData()->hasFormat("text/uri-list")) // "application/x-kde-urilist" ??
event->acceptProposedAction();
}
void CFontListView::dropEvent(QDropEvent *event)
{
if(itsAllowDrops && event->mimeData()->hasFormat("text/uri-list"))
{
event->acceptProposedAction();
QList urls(event->mimeData()->urls());
QList::ConstIterator it(urls.begin()),
end(urls.end());
QSet kurls;
QMimeDatabase db;
for (; it!=end; ++it)
{
QMimeType mime = db.mimeTypeForUrl(*it);
foreach (const QString &fontMime, CFontList::fontMimeTypes) {
if (mime.inherits(fontMime)) {
kurls.insert(*it);
break;
}
}
}
if(kurls.count())
emit fontsDropped(kurls);
}
}
void CFontListView::contextMenuEvent(QContextMenuEvent *ev)
{
bool valid(indexAt(ev->pos()).isValid());
itsDeleteAct->setEnabled(valid);
bool en(false),
dis(false);
QModelIndexList selectedItems(selectedIndexes());
QModelIndex index;
foreach(index, selectedItems)
{
QModelIndex realIndex(itsProxy->mapToSource(index));
if(realIndex.isValid())
{
if((static_cast(realIndex.internalPointer()))->isFont())
{
if((static_cast(realIndex.internalPointer())->isEnabled()))
en=true;
else
dis=true;
}
else
{
switch((static_cast(realIndex.internalPointer()))->status())
{
case CFamilyItem::ENABLED:
en=true;
break;
case CFamilyItem::DISABLED:
dis=true;
break;
case CFamilyItem::PARTIAL:
en=dis=true;
break;
}
}
}
if(en && dis)
break;
}
itsEnableAct->setEnabled(dis);
itsDisableAct->setEnabled(en);
if(itsPrintAct)
itsPrintAct->setEnabled(en|dis);
if(itsViewAct)
itsViewAct->setEnabled(en|dis);
itsMenu->popup(ev->globalPos());
}
bool CFontListView::viewportEvent(QEvent *event)
{
executeDelayedItemsLayout();
return QTreeView::viewportEvent(event);
}
}
diff --git a/kcms/kfontinst/lib/Misc.cpp b/kcms/kfontinst/lib/Misc.cpp
index d722cc7df..a201b06af 100644
--- a/kcms/kfontinst/lib/Misc.cpp
+++ b/kcms/kfontinst/lib/Misc.cpp
@@ -1,492 +1,493 @@
/*
* KFontInst - KDE Font Installer
*
* Copyright 2003-2007 Craig Drummond
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "Misc.h"
#include "config-paths.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace KFI
{
namespace Misc
{
QString prettyUrl(const QUrl &url)
{
QString u(url.url());
u.replace("%20", " ");
return u;
}
QString dirSyntax(const QString &d)
{
if(!d.isEmpty())
{
QString ds(d);
ds.replace("//", "/");
int slashPos(ds.lastIndexOf('/'));
if(slashPos!=(((int)ds.length())-1))
ds.append('/');
return ds;
}
return d;
}
QString fileSyntax(const QString &d)
{
if(!d.isEmpty())
{
QString ds(d);
ds.replace("//", "/");
int slashPos(ds.lastIndexOf('/'));
if(slashPos==(((int)ds.length())-1))
ds.remove(slashPos, 1);
return ds;
}
return d;
}
QString getDir(const QString &f)
{
QString d(f);
int slashPos(d.lastIndexOf('/'));
if(slashPos!=-1)
d.remove(slashPos+1, d.length());
return dirSyntax(d);
}
QString getFile(const QString &f)
{
QString d(f);
int slashPos=d.lastIndexOf('/');
if(slashPos!=-1)
d.remove(0, slashPos+1);
return d;
}
bool createDir(const QString &dir)
{
if (!QDir().mkpath(dir))
return false;
//
// Clear any umask before setting dir perms
mode_t oldMask(umask(0000));
const QByteArray d = QFile::encodeName(dir);
::chmod(d.constData(), DIR_PERMS);
// Reset umask
::umask(oldMask);
return true;
}
void setFilePerms(const QByteArray &f)
{
//
// Clear any umask before setting file perms
mode_t oldMask(umask(0000));
::chmod(f.constData(), FILE_PERMS);
// Reset umask
::umask(oldMask);
}
bool doCmd(const QString &cmd, const QString &p1, const QString &p2, const QString &p3)
{
QStringList args;
if(!p1.isEmpty())
args << p1;
if(!p2.isEmpty())
args << p2;
if(!p3.isEmpty())
args << p3;
return 0==QProcess::execute(cmd, args);
}
QString changeExt(const QString &f, const QString &newExt)
{
QString newStr(f);
int dotPos(newStr.lastIndexOf('.'));
if(-1==dotPos)
newStr+=QChar('.')+newExt;
else
{
newStr.remove(dotPos+1, newStr.length());
newStr+=newExt;
}
return newStr;
}
//
// Get a list of files associated with a file, e.g.:
//
// File: /home/a/courier.pfa
//
// Associated: /home/a/courier.afm /home/a/courier.pfm
//
void getAssociatedFiles(const QString &path, QStringList &files, bool afmAndPfm)
{
QString ext(path);
int dotPos(ext.lastIndexOf('.'));
bool check(false);
if(-1==dotPos) // Hmm, no extension - check anyway...
check=true;
else // Cool, got an extension - see if it is a Type1 font...
{
ext=ext.mid(dotPos+1);
check=0==ext.compare("pfa", Qt::CaseInsensitive) ||
0==ext.compare("pfb", Qt::CaseInsensitive);
}
if(check)
{
const char *afm[]={"afm", "AFM", "Afm", NULL},
*pfm[]={"pfm", "PFM", "Pfm", NULL};
bool gotAfm(false);
int e;
for(e=0; afm[e]; ++e)
{
QString statFile(changeExt(path, afm[e]));
if(fExists(statFile))
{
files.append(statFile);
gotAfm=true;
break;
}
}
if(afmAndPfm || !gotAfm)
for(e=0; pfm[e]; ++e)
{
QString statFile(changeExt(path, pfm[e]));
if(fExists(statFile))
{
files.append(statFile);
break;
}
}
}
}
time_t getTimeStamp(const QString &item)
{
QT_STATBUF info;
return !item.isEmpty() && 0==QT_LSTAT(QFile::encodeName(item), &info) ? info.st_mtime : 0;
}
bool check(const QString &path, bool file, bool checkW)
{
QT_STATBUF info;
QByteArray pathC(QFile::encodeName(path));
return 0==QT_LSTAT(pathC, &info) &&
(file ? (S_ISREG(info.st_mode) || S_ISLNK(info.st_mode))
: S_ISDIR(info.st_mode)) &&
(!checkW || 0==::access(pathC, W_OK));
}
QString getFolder(const QString &defaultDir, const QString &root, QStringList &dirs)
{
if(dirs.contains(defaultDir))
return defaultDir;
else
{
QStringList::const_iterator it,
end=dirs.constEnd();
bool found=false;
for(it=dirs.constBegin(); it!=end && !found; ++it)
if(0==(*it).indexOf(root))
return *it;
}
return defaultDir;
}
bool checkExt(const QString &fname, const QString &ext)
{
QString extension('.'+ext);
return fname.length()>extension.length()
? 0==fname.mid(fname.length()-extension.length()).compare(extension, Qt::CaseInsensitive)
: false;
}
bool isBitmap(const QString &str)
{
return checkExt(str, "pcf") || checkExt(str, "bdf") || checkExt(str, "pcf.gz") || checkExt(str, "bdf.gz");
}
bool isMetrics(const QString &str)
{
return checkExt(str, "afm") || checkExt(str, "pfm");
}
int getIntQueryVal(const QUrl &url, const char *key, int defVal)
{
QUrlQuery query(url);
QString item(query.queryItemValue(key));
int val(defVal);
if(!item.isNull())
val=item.toInt();
return val;
}
bool printable(const QString &mime)
{
- return "application/x-font-type1"==mime || "application/x-font-ttf"==mime ||
+ return "font/otf"==mime || "font/ttf"==mime ||
+ "application/x-font-type1"==mime || "application/x-font-ttf"==mime ||
"application/x-font-otf"==mime || "application/x-font-type1"==mime;
}
uint qHash(const KFI::Misc::TFont &key)
{
//return qHash(QString(key.family+'%'+QString().setNum(key.styleInfo, 16)));
const QChar *p = key.family.unicode();
int n = key.family.size();
uint h = 0,
g;
h = (h << 4) + key.styleInfo;
if ((g = (h & 0xf0000000)) != 0)
h ^= g >> 23;
h &= ~g;
while (n--)
{
h = (h << 4) + (*p++).unicode();
if ((g = (h & 0xf0000000)) != 0)
h ^= g >> 23;
h &= ~g;
}
return h;
}
// Taken from qdom.cpp
QString encodeText(const QString &str, QTextStream &s)
{
const QTextCodec *const codec = s.codec();
Q_ASSERT(codec);
QString retval(str);
int len = retval.length(),
i = 0;
while (i < len)
{
const QChar ati(retval.at(i));
if (ati == QLatin1Char('<'))
{
retval.replace(i, 1, QLatin1String("<"));
len += 3;
i += 4;
}
else if (ati == QLatin1Char('"'))
{
retval.replace(i, 1, QLatin1String("""));
len += 5;
i += 6;
}
else if (ati == QLatin1Char('&'))
{
retval.replace(i, 1, QLatin1String("&"));
len += 4;
i += 5;
}
else if (ati == QLatin1Char('>') && i >= 2 && retval[i - 1] == QLatin1Char(']') && retval[i - 2] == QLatin1Char(']'))
{
retval.replace(i, 1, QLatin1String(">"));
len += 3;
i += 4;
}
else
{
if(codec->canEncode(ati))
++i;
else
{
// We have to use a character reference to get it through.
const ushort codepoint(ati.unicode());
const QString replacement(QLatin1String("") + QString::number(codepoint, 16) + QLatin1Char(';'));
retval.replace(i, 1, replacement);
i += replacement.length();
len += replacement.length() - 1;
}
}
}
return retval;
}
QString contractHome(QString path)
{
if (!path.isEmpty() && '/'==path[0])
{
QString home(QDir::homePath());
if(path.startsWith(home))
{
int len = home.length();
if(len>1 && (path.length() == len || path[len] == '/'))
return path.replace(0, len, QString::fromLatin1("~"));
}
}
return path;
}
QString expandHome(QString path)
{
if(!path.isEmpty() && '~'==path[0])
return 1==path.length() ? QDir::homePath() : path.replace(0, 1, QDir::homePath());
return path;
}
QMap getFontFileMap(const QSet &files)
{
QMap map;
QSet::ConstIterator it=files.constBegin(),
end=files.constEnd();
QMap > fontsFiles;
for(;it!=end; ++it)
fontsFiles[unhide(getFile(*it))].insert(getDir(*it));
QMap >::ConstIterator fIt(fontsFiles.constBegin()),
fEnd(fontsFiles.constEnd());
for(; fIt!=fEnd; ++fIt)
if(fIt.value().count()>1)
{
QVector orig(fIt.value().count()),
modified(fIt.value().count());
QSet::ConstIterator oIt(fIt.value().constBegin()),
oEnd(fIt.value().constEnd());
bool good=true;
int count=fIt.value().count();
for(int i=0; i apps;
if(!apps.contains(name)) {
QStringList installPaths;
if (qstrcmp(path, "libexec") == 0)
installPaths.append(KFONTINST_LIBEXEC_DIR);
apps[name] = QStandardPaths::findExecutable(name, installPaths);
}
return apps[name];
}
} // Misc::
} // KFI::
diff --git a/kcms/kfontinst/thumbnail/FontThumbnail.cpp b/kcms/kfontinst/thumbnail/FontThumbnail.cpp
index 52bfdb415..412272dd7 100644
--- a/kcms/kfontinst/thumbnail/FontThumbnail.cpp
+++ b/kcms/kfontinst/thumbnail/FontThumbnail.cpp
@@ -1,125 +1,125 @@
/*
* KFontInst - KDE Font Installer
*
* Copyright 2003-2007 Craig Drummond
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "FontThumbnail.h"
#include "KfiConstants.h"
#include "FcEngine.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "debug.h"
#define KFI_DBUG qCDebug(KCM_KFONTINST_THUMBNAIL)
extern "C"
{
Q_DECL_EXPORT ThumbCreator *new_creator()
{
return new KFI::CFontThumbnail;
}
}
namespace KFI
{
CFontThumbnail::CFontThumbnail()
{
}
bool CFontThumbnail::create(const QString &path, int width, int height, QImage &img)
{
QString realPath(path);
QTemporaryDir *tempDir = 0;
KFI_DBUG << "Create font thumbnail for:" << path << endl;
// Is this a appliaction/vnd.kde.fontspackage file? If so, extract 1 scalable font...
QMimeDatabase db;
if (Misc::isPackage(path) || "application/zip" == db.mimeTypeForFile(path, QMimeDatabase::MatchContent).name())
{
KZip zip(path);
if(zip.open(QIODevice::ReadOnly))
{
const KArchiveDirectory *zipDir=zip.directory();
if(zipDir)
{
QStringList fonts(zipDir->entries());
if(fonts.count())
{
QStringList::ConstIterator it(fonts.begin()),
end(fonts.end());
for(; it!=end; ++it)
{
const KArchiveEntry *entry=zipDir->entry(*it);
if(entry && entry->isFile())
{
delete tempDir;
tempDir=new QTemporaryDir(QDir::tempPath() + "/" KFI_TMP_DIR_PREFIX);
tempDir->setAutoRemove(true);
((KArchiveFile *)entry)->copyTo(tempDir->path());
QString mime(db.mimeTypeForFile(tempDir->path()+QLatin1Char('/')+entry->name()).name());
- if(mime=="application/x-font-ttf" || mime=="application/x-font-otf" ||
- mime=="application/x-font-type1")
+ if(mime=="font/ttf" || mime=="font/otf" || mime=="application/x-font-ttf" ||
+ mime=="application/x-font-otf" || mime=="application/x-font-type1")
{
realPath=tempDir->path()+QLatin1Char('/')+entry->name();
break;
}
else
::unlink(QFile::encodeName(tempDir->path()+QLatin1Char('/')+entry->name()).data());
}
}
}
}
}
}
QColor bgnd(Qt::black);
bgnd.setAlpha(0);
img=itsEngine.draw(realPath, KFI_NO_STYLE_INFO, 0, QApplication::palette().text().color(), bgnd, width, height, true);
delete tempDir;
return !img.isNull();
}
ThumbCreator::Flags CFontThumbnail::flags() const
{
return None;
}
}
diff --git a/kcms/kfontinst/thumbnail/fontthumbnail.desktop b/kcms/kfontinst/thumbnail/fontthumbnail.desktop
index a2a86f797..4268ea126 100644
--- a/kcms/kfontinst/thumbnail/fontthumbnail.desktop
+++ b/kcms/kfontinst/thumbnail/fontthumbnail.desktop
@@ -1,97 +1,97 @@
[Desktop Entry]
Type=Service
Name=Font Files
Name[af]=Skrif tipe Lêers
Name[ar]=ملفّات الخطوط
Name[be]=Файлы шрыфтоў
Name[be@latin]=Fajły šryftoŭ
Name[bg]=Файлове с шрифтове
Name[bn]=ফন্ট ফাইল
Name[bn_IN]=ফন্ট ফাইল
Name[br]=Restroù Nodrezhoù
Name[bs]=Datoteke fontova
Name[ca]=Fitxers de tipus de lletra
Name[ca@valencia]=Fitxers de tipus de lletra
Name[cs]=Soubory s písmy
Name[csb]=Lopczi fòntów
Name[cy]=Ffeiliau Ffont
Name[da]=Skrifttypefiler
Name[de]=Schriftdateien
Name[el]=Αρχεία γραμματοσειρών
Name[en_GB]=Font Files
Name[eo]=Tipardosieroj
Name[es]=Archivos de tipos de letra
Name[et]=Fondifailid
Name[eu]=Letra-tipoen fitxategiak
Name[fa]=پرونده قلمها
Name[fi]=Fonttitiedostot
Name[fr]=Fichiers de polices de caractères
Name[fy]=Lettertypetriemmen
Name[ga]=Comhaid Chló
Name[gl]=Ficheiros de tipos de letra
Name[gu]=ફોન્ટ ફાઇલો
Name[he]=קבצי גופנים
Name[hi]=फ़ॉन्ट फ़ाइलें
Name[hne]=फोंट फाइल मन ल
Name[hr]=Datoteke fontova
Name[hsb]=Pismowe dataje
Name[hu]=Betűtípusfájlok
Name[ia]=Files de font
Name[id]=Berkas Fonta
Name[is]=Leturskrár
Name[it]=File dei caratteri
Name[ja]=フォントファイル
Name[ka]=ფონტების ფაილები
Name[kk]=Қаріп файлдары
Name[km]=ឯកសារពុម្ពអក្សរ
Name[kn]=ಅಕ್ಷರಶೈಲಿ ಕಡತಗಳು
Name[ko]=글꼴 파일
Name[ku]=Pelên Curetîpan
Name[lt]=Šriftų failai
Name[lv]=Fontu faili
Name[mai]=फान्ट फाइलसभ
Name[mk]=Датотеки со фонтови
Name[ml]=അക്ഷരസഞ്ചയ ഫയലുകള്
Name[mr]=फॉन्ट फाईल्स
Name[ms]=Fail Fon
Name[nb]=Skriftfiler
Name[nds]=Schriftoortdateien
Name[ne]=फन्ट फाइल
Name[nl]=Lettertypebestanden
Name[nn]=Skriftfiler
Name[oc]=Fichièrs de poliça
Name[or]=ଅକ୍ଷରରୂପ ଫାଇଲଗୁଡ଼ିକ
Name[pa]=ਫੋਂਟ ਫਾਈਲਾਂ
Name[pl]=Pliki czcionek
Name[pt]=Ficheiros de Tipos de Letra
Name[pt_BR]=Arquivos de fonte
Name[ro]=Fișiere font
Name[ru]=Файлы шрифтов
Name[se]=Fontafiillat
Name[si]=අකුරු ගොනුව
Name[sk]=Súbory písiem
Name[sl]=Datoteke s pisavami
Name[sr]=Фајлови фонтова
Name[sr@ijekavian]=Фајлови фонтова
Name[sr@ijekavianlatin]=Fajlovi fontova
Name[sr@latin]=Fajlovi fontova
Name[sv]=Teckensnittsfiler
Name[ta]=மின்னெழுத்துக் கோப்புகள்
Name[te]=ఫాంట్ ఫైళ్ళు
Name[tg]=Файлҳои ҳарф
Name[th]=แฟ้มแบบอักษรต่าง ๆ
Name[tr]=Yazı Tipi Dosyaları
Name[ug]=خەت نۇسخا ھۆججەتلەر
Name[uk]=Файли шрифтів
Name[uz]=Shrift-fayllari
Name[uz@cyrillic]=Шрифт-файллари
Name[vi]=Tập tin phông chữ
Name[wa]=Fitchîs fontes
Name[xh]=Iifayile Zohlobo lwamagama
Name[x-test]=xxFont Filesxx
Name[zh_CN]=字体文件
Name[zh_TW]=字型檔案
X-KDE-ServiceTypes=ThumbCreator
-MimeType=application/x-font-ttf;application/x-font-type1;application/x-font-bdf;application/x-font-pcf;application/x-font-otf;fonts/package;
+MimeType=application/x-font-ttf;application/x-font-type1;application/x-font-bdf;application/x-font-pcf;application/x-font-otf;fonts/package;font/ttf;font/otf;
X-KDE-Library=fontthumbnail
CacheThumbnail=true
diff --git a/kcms/kfontinst/viewpart/FontViewPart.cpp b/kcms/kfontinst/viewpart/FontViewPart.cpp
index 488c8d0c4..7138e9398 100644
--- a/kcms/kfontinst/viewpart/FontViewPart.cpp
+++ b/kcms/kfontinst/viewpart/FontViewPart.cpp
@@ -1,578 +1,578 @@
/*
* KFontInst - KDE Font Installer
*
* Copyright 2003-2007 Craig Drummond
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "FontViewPart.h"
#include "Misc.h"
#include "KfiConstants.h"
#include "FcEngine.h"
#include "PreviewSelectAction.h"
#include "FontInstInterface.h"
#include "FontInst.h"
#include "config-workspace.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
#include
#include
#include
#include
#include
#include "config-fontinst.h"
// Enable the following to allow printing of non-installed fonts. Does not seem to work :-(
//#define KFI_PRINT_APP_FONTS
namespace KFI
{
static QString getFamily(const QString &font)
{
int commaPos=font.lastIndexOf(',');
return -1==commaPos ? font : font.left(commaPos);
}
K_PLUGIN_FACTORY(CFontViewPartFactory, registerPlugin();)
K_EXPORT_PLUGIN(CFontViewPartFactory("kfontview"))
CFontViewPart::CFontViewPart(QWidget *parentWidget, QObject *parent, const QList &)
: KParts::ReadOnlyPart(parent),
itsConfig(KSharedConfig::openConfig()),
itsProc(NULL),
itsTempDir(NULL),
itsInterface(new FontInstInterface()),
itsOpening(false)
{
// create browser extension (for printing when embedded into browser)
itsExtension = new BrowserExtension(this);
itsFrame=new QFrame(parentWidget);
QFrame *previewFrame=new QFrame(itsFrame);
QWidget *controls=new QWidget(itsFrame);
// QGroupBox *metaBox=new QGroupBox(i18n("Information:"), controls);
itsFaceWidget=new QWidget(controls);
QBoxLayout *mainLayout=new QBoxLayout(QBoxLayout::TopToBottom, itsFrame);
QBoxLayout *previewLayout=new QBoxLayout(QBoxLayout::LeftToRight, previewFrame),
*controlsLayout=new QBoxLayout(QBoxLayout::LeftToRight, controls),
*faceLayout=new QBoxLayout(QBoxLayout::LeftToRight, itsFaceWidget);
// QBoxLayout *metaLayout=new QBoxLayout(QBoxLayout::LeftToRight, metaBox);
// itsMetaLabel=new QLabel(metaBox);
// itsMetaLabel->setAlignment(Qt::AlignTop);
// metaLayout->addWidget(itsMetaLabel);
previewLayout->setMargin(0);
previewLayout->setSpacing(0);
faceLayout->setMargin(0);
controlsLayout->setMargin(0);
previewLayout->setSpacing(0);
itsFrame->setFrameShape(QFrame::NoFrame);
itsFrame->setFocusPolicy(Qt::ClickFocus);
previewFrame->setFrameShape(QFrame::StyledPanel);
previewFrame->setFrameShadow(QFrame::Sunken);
KAboutData aboutData(KFI_NAME, i18n("FontViewPart"), WORKSPACE_VERSION_STRING);
setComponentData(aboutData);
itsPreview=new CFontPreview(previewFrame);
itsPreview->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
itsFaceLabel=new QLabel(i18n("Show Face:"), itsFaceWidget);
itsFaceSelector=new QSpinBox(itsFaceWidget);
itsFaceSelector->setValue(1);
itsInstallButton=new QPushButton(i18n("Install..."), controls);
itsInstallButton->setEnabled(false);
previewLayout->addWidget(itsPreview);
faceLayout->addWidget(itsFaceLabel);
faceLayout->addWidget(itsFaceSelector);
faceLayout->addItem(new QSpacerItem(faceLayout->spacing(), 0, QSizePolicy::Fixed, QSizePolicy::Fixed));
itsFaceWidget->hide();
itsPreview->engine()->readConfig(*itsConfig);
//controlsLayout->addWidget(metaBox);
//controlsLayout->addStretch(2);
controlsLayout->addWidget(itsFaceWidget);
controlsLayout->addStretch(1);
controlsLayout->addWidget(itsInstallButton);
mainLayout->addWidget(previewFrame);
mainLayout->addWidget(controls);
connect(itsPreview, SIGNAL(status(bool)), SLOT(previewStatus(bool)));
connect(itsInstallButton, SIGNAL(clicked()), SLOT(install()));
connect(itsFaceSelector, SIGNAL(valueChanged(int)), SLOT(showFace(int)));
itsChangeTextAction=actionCollection()->addAction("changeText");
itsChangeTextAction->setIcon(QIcon::fromTheme("edit-rename"));
itsChangeTextAction->setText(i18n("Change Text..."));
connect(itsChangeTextAction, SIGNAL(triggered(bool)), SLOT(changeText()));
CPreviewSelectAction *displayTypeAction=new CPreviewSelectAction(this, CPreviewSelectAction::BlocksAndScripts);
actionCollection()->addAction("displayType", displayTypeAction);
connect(displayTypeAction, SIGNAL(range(QList)),
SLOT(displayType(QList)));
QAction *zoomIn=actionCollection()->addAction(KStandardAction::ZoomIn, itsPreview, SLOT(zoomIn())),
*zoomOut=actionCollection()->addAction(KStandardAction::ZoomOut, itsPreview, SLOT(zoomOut()));
connect(itsPreview, SIGNAL(atMax(bool)), zoomIn, SLOT(setDisabled(bool)));
connect(itsPreview, SIGNAL(atMin(bool)), zoomOut, SLOT(setDisabled(bool)));
setXMLFile("kfontviewpart.rc");
setWidget(itsFrame);
itsExtension->enablePrint(false);
FontInst::registerTypes();
connect(itsInterface, SIGNAL(status(int,int)), SLOT(dbusStatus(int,int)));
connect(itsInterface, SIGNAL(fontStat(int,KFI::Family)), SLOT(fontStat(int,KFI::Family)));
}
CFontViewPart::~CFontViewPart()
{
delete itsTempDir;
itsTempDir=NULL;
delete itsInterface;
itsInterface=NULL;
}
static inline QUrl mostLocalUrl(const QUrl &url, QWidget *widget)
{
auto job = KIO::mostLocalUrl(url);
KJobWidgets::setWindow(job, widget);
job->exec();
return job->mostLocalUrl();
}
bool CFontViewPart::openUrl(const QUrl &url)
{
if (!url.isValid() || !closeUrl())
return false;
// itsMetaLabel->setText(QString());
// itsMetaInfo.clear();
itsFontDetails=FC::decode(url);
if(!itsFontDetails.family.isEmpty() ||
KFI_KIO_FONTS_PROTOCOL==url.scheme() || mostLocalUrl(url, itsFrame).isLocalFile())
{
setUrl(url);
emit started(0);
setLocalFilePath(this->url().path());
bool ret=openFile();
if (ret)
emit completed();
return ret;
}
else
return ReadOnlyPart::openUrl(url);
}
bool CFontViewPart::openFile()
{
// NOTE: Can't do the real open here, as we don't seem to be able to use KIO::NetAccess functions
// during initial start-up. Bug report 111535 indicates that calling "konqueror " crashes.
itsInstallButton->setEnabled(false);
QTimer::singleShot(0, this, SLOT(timeout()));
return true;
}
static inline bool statUrl(const QUrl &url, KIO::UDSEntry *udsEntry)
{
auto job = KIO::stat(url);
job->exec();
if (job->error())
return false;
*udsEntry = job->statResult();
return true;
}
void CFontViewPart::timeout()
{
if(!itsInstallButton)
return;
bool isFonts(KFI_KIO_FONTS_PROTOCOL==url().scheme()),
showFs(false),
package(false);
int fileIndex(-1);
QString fontFile;
// itsMetaUrl=url();
delete itsTempDir;
itsTempDir=NULL;
itsOpening=true;
if(!itsFontDetails.family.isEmpty())
{
emit setWindowCaption(FC::createName(itsFontDetails.family, itsFontDetails.styleInfo));
fontFile=FC::getFile(url());
fileIndex=FC::getIndex(url());
}
else if(isFonts)
{
KIO::UDSEntry udsEntry;
bool found = statUrl(url(), &udsEntry);
if(!found)
{
// Check if url is "fonts:/ if so try fonts:/System/, then fonts:/Personal
QStringList pathList(url().adjusted(QUrl::StripTrailingSlash).path().split('/', QString::SkipEmptyParts));
if(pathList.count()==1)
{
found = statUrl(QUrl(QString("fonts:/"+i18n(KFI_KIO_FONTS_SYS)+'/'+pathList[0])), &udsEntry);
if (!found)
found = statUrl(QUrl(QString("fonts:/"+i18n(KFI_KIO_FONTS_USER)+'/'+pathList[0])), &udsEntry);
}
}
if(found)
{
if(udsEntry.numberValue(KIO::UDSEntry::UDS_HIDDEN, 0))
{
fontFile=udsEntry.stringValue(UDS_EXTRA_FILE_NAME);
fileIndex=udsEntry.numberValue(UDS_EXTRA_FILE_FACE, 0);
}
itsFontDetails.family=getFamily(udsEntry.stringValue(KIO::UDSEntry::UDS_NAME));
itsFontDetails.styleInfo=udsEntry.numberValue(UDS_EXTRA_FC_STYLE);
emit setWindowCaption(udsEntry.stringValue(KIO::UDSEntry::UDS_NAME));
}
else
{
previewStatus(false);
return;
}
}
else
{
QString path(localFilePath());
// Is this a application/vnd.kde.fontspackage file? If so, extract 1 scalable font...
if((package=Misc::isPackage(path)))
{
KZip zip(path);
if(zip.open(QIODevice::ReadOnly))
{
const KArchiveDirectory *zipDir=zip.directory();
if(zipDir)
{
QStringList fonts(zipDir->entries());
if(fonts.count())
{
QStringList::ConstIterator it(fonts.begin()),
end(fonts.end());
for(; it!=end; ++it)
{
const KArchiveEntry *entry=zipDir->entry(*it);
if(entry && entry->isFile())
{
delete itsTempDir;
itsTempDir=new QTemporaryDir(QDir::tempPath() + "/" KFI_TMP_DIR_PREFIX);
itsTempDir->setAutoRemove(true);
((KArchiveFile *)entry)->copyTo(itsTempDir->path());
QMimeDatabase db;
QString mime(db.mimeTypeForFile(itsTempDir->path()+QLatin1Char('/')+entry->name()).name());
- if(mime=="application/x-font-ttf" || mime=="application/x-font-otf" ||
- mime=="application/x-font-type1")
+ if(mime=="font/ttf" || mime=="font/otf" || mime=="application/x-font-ttf" ||
+ mime=="application/x-font-otf" || mime=="application/x-font-type1")
{
fontFile=itsTempDir->path()+QLatin1Char('/')+entry->name();
//setLocalFilePath(itsTempDir->path()+QLatin1Char('/')+entry->name());
// itsMetaUrl=QUrl::fromLocalFile(localFilePath());
break;
}
else
::unlink(QFile::encodeName(itsTempDir->path()+QLatin1Char('/')+entry->name()).data());
}
}
}
}
}
}
}
itsInstallButton->setEnabled(false);
if(itsFontDetails.family.isEmpty())
emit setWindowCaption(url().toDisplayString());
else
FcInitReinitialize();
itsPreview->showFont(!package && itsFontDetails.family.isEmpty()
? localFilePath()
: fontFile.isEmpty()
? itsFontDetails.family
: fontFile,
itsFontDetails.styleInfo, fileIndex);
if(!isFonts && itsPreview->engine()->getNumIndexes()>1)
{
showFs=true;
itsFaceSelector->setRange(1, itsPreview->engine()->getNumIndexes());
itsFaceSelector->setSingleStep(1);
itsFaceSelector->blockSignals(true);
itsFaceSelector->setValue(1);
itsFaceSelector->blockSignals(false);
}
itsFaceWidget->setVisible(showFs);
}
void CFontViewPart::previewStatus(bool st)
{
if(itsOpening)
{
bool printable(false);
if(st)
{
checkInstallable();
if(Misc::app(KFI_PRINTER).isEmpty())
printable=false;
if(KFI_KIO_FONTS_PROTOCOL==url().scheme())
printable=!Misc::isHidden(url());
else if(!FC::decode(url()).family.isEmpty())
printable=!Misc::isHidden(FC::getFile(url()));
#ifdef KFI_PRINT_APP_FONTS
else
{
// TODO: Make this work! Plus, printing of disabled TTF/OTF's should also be possible!
KMimeType::Ptr mime=KMimeType::findByUrl(QUrl::fromLocalFile(localFilePath()), 0, false, true);
printable=mime->is("application/x-font-ttf") || mime->is("application/x-font-otf");
}
#endif
}
itsExtension->enablePrint(st && printable);
itsOpening=false;
}
itsChangeTextAction->setEnabled(st);
// if(st)
// getMetaInfo(itsFaceSelector->isVisible() && itsFaceSelector->value()>0
// ? itsFaceSelector->value()-1 : 0);
// else
if(!st)
KMessageBox::error(itsFrame, i18n("Could not read font."));
}
void CFontViewPart::install()
{
if(!itsProc || QProcess::NotRunning==itsProc->state())
{
QStringList args;
if(!itsProc)
itsProc=new QProcess(this);
else
itsProc->kill();
QString title = QGuiApplication::applicationDisplayName();
if (title.isEmpty())
title = QCoreApplication::applicationName();
args << "--embed" << QString().sprintf("0x%x", (unsigned int)(itsFrame->window()->winId()))
<< "--qwindowtitle" << title
<< "--qwindowicon" << "kfontview"
<< url().toDisplayString();
connect(itsProc, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(installlStatus()));
itsProc->start(Misc::app(KFI_INSTALLER), args);
itsInstallButton->setEnabled(false);
}
}
void CFontViewPart::installlStatus()
{
checkInstallable();
}
void CFontViewPart::dbusStatus(int pid, int status)
{
if(pid==getpid() && FontInst::STATUS_OK!=status)
itsInstallButton->setEnabled(false);
}
void CFontViewPart::fontStat(int pid, const KFI::Family &font)
{
if(pid==getpid())
itsInstallButton->setEnabled(!Misc::app(KFI_INSTALLER).isEmpty() && font.styles().count()==0);
}
void CFontViewPart::changeText()
{
bool status;
QString oldStr(itsPreview->engine()->getPreviewString()),
newStr(QInputDialog::getText(itsFrame, i18n("Preview String"),
i18n("Please enter new string:"),
QLineEdit::Normal,
oldStr, &status));
if(status && newStr!=oldStr)
{
itsPreview->engine()->setPreviewString(newStr);
itsPreview->engine()->writeConfig(*itsConfig);
itsPreview->showFont();
}
}
void CFontViewPart::print()
{
QStringList args;
QString title = QGuiApplication::applicationDisplayName();
if (title.isEmpty())
title = QCoreApplication::applicationName();
if(!itsFontDetails.family.isEmpty())
{
args << "--embed" << QString().sprintf("0x%x", (unsigned int)(itsFrame->window()->winId()))
<< "--qwindowtitle" << title
<< "--qwindowicon" << "kfontview"
<< "--size" << "0"
<< "--pfont" << QString(itsFontDetails.family+','+QString().setNum(itsFontDetails.styleInfo));
}
#ifdef KFI_PRINT_APP_FONTS
else
args << "--embed" << QString().sprintf("0x%x", (unsigned int)(itsFrame->window()->winId()))
<< "--qwindowtitle" << title
<< "--qwindowicon" << "kfontview"
<< "--size " << "0"
<< localFilePath()
<< QString().setNum(KFI_NO_STYLE_INFO);
#endif
if(args.count())
QProcess::startDetached(Misc::app(KFI_PRINTER), args);
}
void CFontViewPart::displayType(const QList &range)
{
itsPreview->setUnicodeRange(range);
itsChangeTextAction->setEnabled(0==range.count());
}
void CFontViewPart::showFace(int face)
{
itsPreview->showFace(face-1);
}
void CFontViewPart::checkInstallable()
{
if(itsFontDetails.family.isEmpty())
{
if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(OrgKdeFontinstInterface::staticInterfaceName()))
QProcess::startDetached(QLatin1String(KFONTINST_LIB_EXEC_DIR"/fontinst"), QStringList());
itsInstallButton->setEnabled(false);
itsInterface->statFont(itsPreview->engine()->descriptiveName(), FontInst::SYS_MASK|FontInst::USR_MASK, getpid());
}
}
#if 0
void CFontViewPart::getMetaInfo(int face)
{
if(itsMetaInfo[face].isEmpty())
{
// Pass as much inofmration as possible to analyzer...
if(KFI_KIO_FONTS_PROTOCOL!=itsMetaUrl.protocol())
{
itsMetaUrl.removeQueryItem(KFI_KIO_FACE);
if(face>0)
itsMetaUrl.addQueryItem(KFI_KIO_FACE, QString().setNum(face));
}
KFileMetaInfo meta(itsMetaUrl);
if(meta.isValid() && meta.keys().count())
{
QStringList keys(meta.keys());
QStringList::const_iterator it(keys.begin()),
end(keys.end());
itsMetaInfo[face]="";
for(; it!=end; ++it)
{
KFileMetaInfoItem mi(meta.item(*it));
itsMetaInfo[face]+=""+mi.name()+" |
"+
mi.value().toString()+" |
";
}
itsMetaInfo[face]+="
";
itsMetaLabel->setText(itsMetaInfo[face]);
}
else
itsMetaLabel->setText(i18n("No information
"));
}
else
itsMetaLabel->setText(itsMetaInfo[face]);
}
#endif
BrowserExtension::BrowserExtension(CFontViewPart *parent)
: KParts::BrowserExtension(parent)
{
setURLDropHandlingEnabled(true);
}
void BrowserExtension::enablePrint(bool enable)
{
if(enable!=isActionEnabled("print") && (!enable || !Misc::app(KFI_PRINTER).isEmpty()))
emit enableAction("print", enable);
}
void BrowserExtension::print()
{
if(!Misc::app(KFI_PRINTER).isEmpty())
static_cast(parent())->print();
}
}
#include "FontViewPart.moc"