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