KUtils
kemoticons.cpp
Go to the documentation of this file.
00001 /********************************************************************************** 00002 * Copyright (C) 2007 by Carlo Segato <brandon.ml@gmail.com> * 00003 * Copyright (C) 2008 Montel Laurent <montel@kde.org> * 00004 * * 00005 * This library is free software; you can redistribute it and/or * 00006 * modify it under the terms of the GNU Lesser General Public * 00007 * License as published by the Free Software Foundation; either * 00008 * version 2.1 of the License, or (at your option) any later version. * 00009 * * 00010 * This library is distributed in the hope that it will be useful, * 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00013 * Lesser General Public License for more details. * 00014 * * 00015 * You should have received a copy of the GNU Lesser General Public * 00016 * License along with this library. If not, see <http://www.gnu.org/licenses/>.* 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 //private slots 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 const int numberOfTheme = m_loaded.size(); 00099 for (int i = 0; i < numberOfTheme; ++i) { 00100 const QString fName = m_loaded.at(i)->property("X-KDE-EmoticonsFileName").toString(); 00101 const QString path = KGlobal::dirs()->findResource("emoticons", name + '/' + fName); 00102 00103 if (QFile::exists(path)) { 00104 KEmoticonsProvider *provider = loadProvider(m_loaded.at(i)); 00105 KEmoticonsTheme theme(provider); 00106 theme.loadTheme(path); 00107 m_themes.insert(name, theme); 00108 00109 if (!m_dirwatch->contains(path)) { 00110 m_dirwatch->addFile(path); 00111 } 00112 return theme; 00113 } 00114 } 00115 return KEmoticonsTheme(); 00116 } 00117 00118 KEmoticons::KEmoticons() 00119 : d(new KEmoticonsPrivate(this)) 00120 { 00121 d->loadServiceList(); 00122 d->m_dirwatch = new KDirWatch; 00123 connect(d->m_dirwatch, SIGNAL(dirty(const QString&)), this, SLOT(themeChanged(const QString&))); 00124 } 00125 00126 KEmoticons::~KEmoticons() 00127 { 00128 delete d; 00129 } 00130 00131 KEmoticonsTheme KEmoticons::theme() 00132 { 00133 return theme(currentThemeName()); 00134 } 00135 00136 KEmoticonsTheme KEmoticons::theme(const QString &name) 00137 { 00138 if (d->m_themes.contains(name)) { 00139 return d->m_themes.value(name); 00140 } 00141 00142 return d->loadTheme(name); 00143 } 00144 00145 QString KEmoticons::currentThemeName() 00146 { 00147 KConfigGroup config(KSharedConfig::openConfig("kdeglobals"), "Emoticons"); 00148 QString name = config.readEntry("emoticonsTheme", "kde4"); 00149 return name; 00150 } 00151 00152 QStringList KEmoticons::themeList() 00153 { 00154 QStringList ls; 00155 const QStringList themeDirs = KGlobal::dirs()->findDirs("emoticons", ""); 00156 00157 for (int i = 0; i < themeDirs.count(); ++i) { 00158 QDir themeQDir(themeDirs[i]); 00159 themeQDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); 00160 themeQDir.setSorting(QDir::Name); 00161 ls << themeQDir.entryList(); 00162 } 00163 return ls; 00164 } 00165 00166 void KEmoticons::setTheme(const KEmoticonsTheme &theme) 00167 { 00168 setTheme(theme.themeName()); 00169 } 00170 00171 void KEmoticons::setTheme(const QString &theme) 00172 { 00173 KConfigGroup config(KSharedConfig::openConfig("kdeglobals"), "Emoticons"); 00174 config.writeEntry("emoticonsTheme", theme); 00175 config.sync(); 00176 } 00177 00178 KEmoticonsTheme KEmoticons::newTheme(const QString &name, const KService::Ptr &service) 00179 { 00180 KEmoticonsProvider *provider = d->loadProvider(service); 00181 KEmoticonsTheme theme(provider); 00182 theme.setThemeName(name); 00183 00184 theme.createNew(); 00185 00186 return theme; 00187 } 00188 00189 QStringList KEmoticons::installTheme(const QString &archiveName) 00190 { 00191 QStringList foundThemes; 00192 KArchiveEntry *currentEntry = 0L; 00193 KArchiveDirectory* currentDir = 0L; 00194 KArchive *archive = 0L; 00195 00196 QString localThemesDir(KStandardDirs::locateLocal("emoticons", QString())); 00197 00198 if (localThemesDir.isEmpty()) { 00199 kError() << "Could not find a suitable place in which to install the emoticon theme"; 00200 return QStringList(); 00201 } 00202 00203 const QString currentBundleMimeType = KMimeType::findByPath(archiveName, 0, false)->name(); 00204 00205 if (currentBundleMimeType == "application/zip" || 00206 currentBundleMimeType == "application/x-zip" || 00207 currentBundleMimeType == "application/x-zip-compressed") { 00208 archive = new KZip(archiveName); 00209 } else if (currentBundleMimeType == "application/x-compressed-tar" || 00210 currentBundleMimeType == "application/x-bzip-compressed-tar" || 00211 currentBundleMimeType == "application/x-lzma-compressed-tar" || 00212 currentBundleMimeType == "application/x-xz-compressed-tar" || 00213 currentBundleMimeType == "application/x-gzip" || 00214 currentBundleMimeType == "application/x-bzip" || 00215 currentBundleMimeType == "application/x-lzma" || 00216 currentBundleMimeType == "application/x-xz") { 00217 archive = new KTar(archiveName); 00218 } else if (archiveName.endsWith(QLatin1String("jisp")) || archiveName.endsWith(QLatin1String("zip"))) { 00219 archive = new KZip(archiveName); 00220 } else { 00221 archive = new KTar(archiveName); 00222 } 00223 00224 if (!archive || !archive->open(QIODevice::ReadOnly)) { 00225 kError() << "Could not open" << archiveName << "for unpacking"; 00226 delete archive; 00227 return QStringList(); 00228 } 00229 00230 const KArchiveDirectory* rootDir = archive->directory(); 00231 00232 // iterate all the dirs looking for an emoticons.xml file 00233 const QStringList entries = rootDir->entries(); 00234 for (QStringList::ConstIterator it = entries.begin(); it != entries.end(); ++it) { 00235 currentEntry = const_cast<KArchiveEntry*>(rootDir->entry(*it)); 00236 00237 if (currentEntry->isDirectory()) { 00238 currentDir = dynamic_cast<KArchiveDirectory*>(currentEntry); 00239 00240 for (int i = 0; i < d->m_loaded.size(); ++i) { 00241 QString fName = d->m_loaded.at(i)->property("X-KDE-EmoticonsFileName").toString(); 00242 00243 if (currentDir && currentDir->entry(fName) != NULL) { 00244 foundThemes.append(currentDir->name()); 00245 } 00246 } 00247 } 00248 } 00249 00250 if (foundThemes.isEmpty()) { 00251 kError() << "The file" << archiveName << "is not a valid emoticon theme archive"; 00252 archive->close(); 00253 delete archive; 00254 return QStringList(); 00255 } 00256 00257 for (int themeIndex = 0; themeIndex < foundThemes.size(); ++themeIndex) { 00258 const QString &theme = foundThemes[themeIndex]; 00259 00260 currentEntry = const_cast<KArchiveEntry *>(rootDir->entry(theme)); 00261 if (currentEntry == 0) { 00262 kDebug() << "couldn't get next archive entry"; 00263 continue; 00264 } 00265 00266 if (currentEntry->isDirectory()) { 00267 currentDir = dynamic_cast<KArchiveDirectory*>(currentEntry); 00268 00269 if (currentDir == 0) { 00270 kDebug() << "couldn't cast archive entry to KArchiveDirectory"; 00271 continue; 00272 } 00273 00274 currentDir->copyTo(localThemesDir + theme); 00275 } 00276 } 00277 00278 archive->close(); 00279 delete archive; 00280 00281 return foundThemes; 00282 } 00283 00284 void KEmoticons::setParseMode(KEmoticonsTheme::ParseMode mode) 00285 { 00286 KConfigGroup config(KSharedConfig::openConfig("kdeglobals"), "Emoticons"); 00287 config.writeEntry("parseMode", int(mode)); 00288 config.sync(); 00289 } 00290 00291 KEmoticonsTheme::ParseMode KEmoticons::parseMode() 00292 { 00293 KConfigGroup config(KSharedConfig::openConfig("kdeglobals"), "Emoticons"); 00294 return (KEmoticonsTheme::ParseMode) config.readEntry("parseMode", int(KEmoticonsTheme::RelaxedParse)); 00295 } 00296 00297 #include "kemoticons.moc" 00298 00299 // kate: space-indent on; indent-width 4; replace-tabs on;
KDE 4.6 API Reference