KUtils
kemoticons.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kemoticons.h"
00021 #include "kemoticonsprovider.h"
00022
00023 #include <QFile>
00024 #include <QDir>
00025
00026 #include <kpluginloader.h>
00027 #include <kdebug.h>
00028 #include <kstandarddirs.h>
00029 #include <kconfiggroup.h>
00030 #include <ktar.h>
00031 #include <kzip.h>
00032 #include <kmimetype.h>
00033 #include <kdirwatch.h>
00034
00035 class KEmoticonsPrivate
00036 {
00037 public:
00038 KEmoticonsPrivate(KEmoticons *parent);
00039 ~KEmoticonsPrivate();
00040 void loadServiceList();
00041 KEmoticonsProvider *loadProvider(const KService::Ptr &service);
00042
00043 QList<KService::Ptr> m_loaded;
00044 QHash<QString, KEmoticonsTheme> m_themes;
00045 KDirWatch *m_dirwatch;
00046 KEmoticons *q;
00047
00048
00049 void themeChanged(const QString &path);
00050 };
00051
00052 KEmoticonsPrivate::KEmoticonsPrivate(KEmoticons *parent)
00053 : q(parent)
00054 {
00055 }
00056
00057 KEmoticonsPrivate::~KEmoticonsPrivate()
00058 {
00059 delete m_dirwatch;
00060 }
00061
00062 bool priorityLessThan(const KService::Ptr &s1, const KService::Ptr &s2)
00063 {
00064 return (s1->property("X-KDE-Priority").toInt() > s2->property("X-KDE-Priority").toInt());
00065 }
00066
00067 void KEmoticonsPrivate::loadServiceList()
00068 {
00069 QString constraint("(exist Library)");
00070 m_loaded = KServiceTypeTrader::self()->query("KEmoticons", constraint);
00071 qSort(m_loaded.begin(), m_loaded.end(), priorityLessThan);
00072 }
00073
00074 KEmoticonsProvider *KEmoticonsPrivate::loadProvider(const KService::Ptr &service)
00075 {
00076 KPluginFactory *factory = KPluginLoader(service->library()).factory();
00077 if (!factory) {
00078 kWarning() << "Invalid plugin factory for" << service->library();
00079 return 0;
00080 }
00081 KEmoticonsProvider *provider = factory->create<KEmoticonsProvider>(0);
00082 return provider;
00083 }
00084
00085 void KEmoticonsPrivate::themeChanged(const QString &path)
00086 {
00087 QFileInfo info(path);
00088 QString name = info.dir().dirName();
00089
00090 if (m_themes.contains(name)) {
00091 q->theme(name);
00092 }
00093 }
00094
00095 KEmoticons::KEmoticons()
00096 : d(new KEmoticonsPrivate(this))
00097 {
00098 d->loadServiceList();
00099 d->m_dirwatch = new KDirWatch;
00100 connect(d->m_dirwatch, SIGNAL(dirty(const QString&)), this, SLOT(themeChanged(const QString&)));
00101 }
00102
00103 KEmoticons::~KEmoticons()
00104 {
00105 delete d;
00106 }
00107
00108 KEmoticonsTheme KEmoticons::theme()
00109 {
00110 return theme(currentThemeName());
00111 }
00112
00113 KEmoticonsTheme KEmoticons::theme(const QString &name)
00114 {
00115 if (d->m_themes.contains(name)) {
00116 return d->m_themes.value(name);
00117 }
00118
00119 for (int i = 0; i < d->m_loaded.size(); ++i) {
00120 QString fName = d->m_loaded.at(i)->property("X-KDE-EmoticonsFileName").toString();
00121 QString path = KGlobal::dirs()->findResource("emoticons", name + '/' + fName);
00122
00123 if (QFile::exists(path)) {
00124 KEmoticonsProvider *provider = d->loadProvider(d->m_loaded.at(i));
00125 KEmoticonsTheme theme(provider);
00126 theme.loadTheme(path);
00127 d->m_themes.insert(name, theme);
00128
00129 if (!d->m_dirwatch->contains(path)) {
00130 d->m_dirwatch->addFile(path);
00131 }
00132 return theme;
00133 }
00134 }
00135 return KEmoticonsTheme();
00136 }
00137
00138 QString KEmoticons::currentThemeName()
00139 {
00140 KConfigGroup config(KSharedConfig::openConfig("kdeglobals"), "Emoticons");
00141 QString name = config.readEntry("emoticonsTheme", "kde4");
00142 return name;
00143 }
00144
00145 QStringList KEmoticons::themeList()
00146 {
00147 QStringList ls;
00148 const QStringList themeDirs = KGlobal::dirs()->findDirs("emoticons", "");
00149
00150 for (int i = 0; i < themeDirs.count(); ++i) {
00151 QDir themeQDir(themeDirs[i]);
00152 themeQDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
00153 themeQDir.setSorting(QDir::Name);
00154 ls << themeQDir.entryList();
00155 }
00156 return ls;
00157 }
00158
00159 void KEmoticons::setTheme(const KEmoticonsTheme &theme)
00160 {
00161 setTheme(theme.themeName());
00162 }
00163
00164 void KEmoticons::setTheme(const QString &theme)
00165 {
00166 KConfigGroup config(KSharedConfig::openConfig("kdeglobals"), "Emoticons");
00167 config.writeEntry("emoticonsTheme", theme);
00168 config.sync();
00169 }
00170
00171 KEmoticonsTheme KEmoticons::newTheme(const QString &name, const KService::Ptr &service)
00172 {
00173 KEmoticonsProvider *provider = d->loadProvider(service);
00174 KEmoticonsTheme theme(provider);
00175 theme.setThemeName(name);
00176
00177 theme.createNew();
00178
00179 return theme;
00180 }
00181
00182 QStringList KEmoticons::installTheme(const QString &archiveName)
00183 {
00184 QStringList foundThemes;
00185 KArchiveEntry *currentEntry = 0L;
00186 KArchiveDirectory* currentDir = 0L;
00187 KArchive *archive = 0L;
00188
00189 QString localThemesDir(KStandardDirs::locateLocal("emoticons", QString()));
00190
00191 if (localThemesDir.isEmpty()) {
00192 kError() << "Could not find a suitable place in which to install the emoticon theme";
00193 return QStringList();
00194 }
00195
00196 QString currentBundleMimeType = KMimeType::findByPath(archiveName, 0, false)->name();
00197
00198 if (currentBundleMimeType == "application/zip" ||
00199 currentBundleMimeType == "application/x-zip" ||
00200 currentBundleMimeType == "application/x-zip-compressed") {
00201 archive = new KZip(archiveName);
00202 } else if (currentBundleMimeType == "application/x-compressed-tar" ||
00203 currentBundleMimeType == "application/x-bzip-compressed-tar" ||
00204 currentBundleMimeType == "application/x-gzip" ||
00205 currentBundleMimeType == "application/x-bzip") {
00206 archive = new KTar(archiveName);
00207 } else if (archiveName.endsWith("jisp") || archiveName.endsWith("zip")) {
00208 archive = new KZip(archiveName);
00209 } else {
00210 archive = new KTar(archiveName);
00211 }
00212
00213 if (!archive || !archive->open(QIODevice::ReadOnly)) {
00214 kError() << "Could not open" << archiveName << "for unpacking";
00215 delete archive;
00216 return QStringList();
00217 }
00218
00219 const KArchiveDirectory* rootDir = archive->directory();
00220
00221
00222 const QStringList entries = rootDir->entries();
00223 for (QStringList::ConstIterator it = entries.begin(); it != entries.end(); ++it) {
00224 currentEntry = const_cast<KArchiveEntry*>(rootDir->entry(*it));
00225
00226 if (currentEntry->isDirectory()) {
00227 currentDir = dynamic_cast<KArchiveDirectory*>(currentEntry);
00228
00229 for (int i = 0; i < d->m_loaded.size(); ++i) {
00230 QString fName = d->m_loaded.at(i)->property("X-KDE-EmoticonsFileName").toString();
00231
00232 if (currentDir && currentDir->entry(fName) != NULL) {
00233 foundThemes.append(currentDir->name());
00234 }
00235 }
00236 }
00237 }
00238
00239 if (foundThemes.isEmpty()) {
00240 kError() << "The file" << archiveName << "is not a valid emoticon theme archive";
00241 archive->close();
00242 delete archive;
00243 return QStringList();
00244 }
00245
00246 for (int themeIndex = 0; themeIndex < foundThemes.size(); ++themeIndex) {
00247 const QString &theme = foundThemes[themeIndex];
00248
00249 currentEntry = const_cast<KArchiveEntry *>(rootDir->entry(theme));
00250 if (currentEntry == 0) {
00251 kDebug() << "couldn't get next archive entry";
00252 continue;
00253 }
00254
00255 if (currentEntry->isDirectory()) {
00256 currentDir = dynamic_cast<KArchiveDirectory*>(currentEntry);
00257
00258 if (currentDir == 0) {
00259 kDebug() << "couldn't cast archive entry to KArchiveDirectory";
00260 continue;
00261 }
00262
00263 currentDir->copyTo(localThemesDir + theme);
00264 }
00265 }
00266
00267 archive->close();
00268 delete archive;
00269
00270 return foundThemes;
00271 }
00272
00273 void KEmoticons::setParseMode(KEmoticonsTheme::ParseMode mode)
00274 {
00275 KConfigGroup config(KSharedConfig::openConfig("kdeglobals"), "Emoticons");
00276 config.writeEntry("parseMode", int(mode));
00277 config.sync();
00278 }
00279
00280 KEmoticonsTheme::ParseMode KEmoticons::parseMode()
00281 {
00282 KConfigGroup config(KSharedConfig::openConfig("kdeglobals"), "Emoticons");
00283 return (KEmoticonsTheme::ParseMode) config.readEntry("parseMode", int(KEmoticonsTheme::RelaxedParse));
00284 }
00285
00286 #include "kemoticons.moc"
00287
00288