kopete/libkopete
kopeteavatarmanager.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 #include "kopeteavatarmanager.h"
00018
00019
00020 #include <QtCore/QLatin1String>
00021 #include <QtCore/QBuffer>
00022 #include <QtCore/QCoreApplication>
00023 #include <QtCore/QFile>
00024 #include <QtCore/QPointer>
00025 #include <QtCore/QStringList>
00026 #include <QtCore/QDir>
00027 #include <QtGui/QPainter>
00028
00029
00030 #include <kdebug.h>
00031 #include <kstandarddirs.h>
00032 #include <kconfig.h>
00033 #include <kcodecs.h>
00034 #include <kurl.h>
00035 #include <kio/job.h>
00036 #include <kio/netaccess.h>
00037 #include <klocale.h>
00038
00039
00040 #include <kopetecontact.h>
00041 #include <kopeteaccount.h>
00042
00043 namespace Kopete
00044 {
00045
00046
00047 AvatarManager *AvatarManager::s_self = 0;
00048
00049 AvatarManager *AvatarManager::self()
00050 {
00051 if( !s_self )
00052 {
00053 s_self = new AvatarManager;
00054 }
00055 return s_self;
00056 }
00057
00058 class AvatarManager::Private
00059 {
00060 public:
00061 KUrl baseDir;
00062
00067 void createDirectory(const KUrl &directory);
00068
00073 QImage scaleImage(const QImage &source);
00074 };
00075
00076 static const QString UserDir("User");
00077 static const QString ContactDir("Contacts");
00078 static const QString AvatarConfig("avatarconfig.rc");
00079
00080
00081 AvatarManager::AvatarManager(QObject *parent)
00082 : QObject(parent), d(new Private)
00083 {
00084
00085 d->baseDir = KUrl( KStandardDirs::locateLocal("appdata", QLatin1String("avatars") ) );
00086
00087
00088 d->createDirectory( d->baseDir );
00089 }
00090
00091 AvatarManager::~AvatarManager()
00092 {
00093 delete d;
00094 }
00095
00096 Kopete::AvatarManager::AvatarEntry AvatarManager::add(Kopete::AvatarManager::AvatarEntry newEntry)
00097 {
00098 Q_ASSERT(!newEntry.name.isEmpty());
00099
00100 KUrl avatarUrl(d->baseDir);
00101
00102
00103 switch(newEntry.category)
00104 {
00105 case AvatarManager::User:
00106 avatarUrl.addPath( UserDir );
00107 d->createDirectory( avatarUrl );
00108 break;
00109 case AvatarManager::Contact:
00110 avatarUrl.addPath( ContactDir );
00111 d->createDirectory( avatarUrl );
00112
00113 if( newEntry.contact && newEntry.contact->account() )
00114 {
00115 QString accountName = newEntry.contact->account()->accountId();
00116 avatarUrl.addPath( accountName );
00117 d->createDirectory( avatarUrl );
00118 }
00119 break;
00120 default:
00121 break;
00122 }
00123
00124 kDebug(14010) << "Base directory: " << avatarUrl.path();
00125
00126
00127 KUrl configUrl = avatarUrl;
00128 configUrl.addPath( AvatarConfig );
00129
00130 QImage avatar;
00131 if( !newEntry.path.isEmpty() && newEntry.image.isNull() )
00132 {
00133 avatar = QImage(newEntry.path);
00134 }
00135 else
00136 {
00137 avatar = newEntry.image;
00138 }
00139
00140
00141 avatar = d->scaleImage(avatar);
00142
00143 QString avatarFilename;
00144
00145
00146 if (newEntry.category == AvatarManager::Contact && newEntry.contact)
00147 {
00148 avatarFilename = newEntry.contact->contactId() + ".png";
00149 }
00150 else
00151 {
00152
00153
00154
00155 QByteArray tempArray;
00156 QBuffer tempBuffer(&tempArray);
00157 tempBuffer.open( QIODevice::WriteOnly );
00158 avatar.save(&tempBuffer, "PNG");
00159 KMD5 context(tempArray);
00160 avatarFilename = context.hexDigest() + QLatin1String(".png");
00161 }
00162
00163
00164 kDebug(14010) << "Saving " << avatarFilename << " on disk.";
00165 avatarUrl.addPath( avatarFilename );
00166
00167 if( !avatar.save( avatarUrl.path(), "PNG") )
00168 {
00169 kDebug(14010) << "Saving of " << avatarUrl.path() << " failed !";
00170 return AvatarEntry();
00171 }
00172 else
00173 {
00174
00175 KConfigGroup avatarConfig(KSharedConfig::openConfig( configUrl.path(), KConfig::SimpleConfig), newEntry.name );
00176
00177 avatarConfig.writeEntry( "Filename", avatarFilename );
00178 avatarConfig.writeEntry( "Category", int(newEntry.category) );
00179
00180 avatarConfig.sync();
00181
00182
00183 newEntry.path = avatarUrl.path();
00184
00185 emit avatarAdded(newEntry);
00186 }
00187
00188 return newEntry;
00189 }
00190
00191 bool AvatarManager::remove(Kopete::AvatarManager::AvatarEntry entryToRemove)
00192 {
00193
00194 if( entryToRemove.name.isEmpty() && entryToRemove.path.isEmpty() )
00195 return false;
00196
00197
00198 if( entryToRemove.category & Kopete::AvatarManager::Contact )
00199 return false;
00200
00201
00202 if( KIO::NetAccess::del(KUrl(entryToRemove.path),0) )
00203 {
00204 kDebug(14010) << "Removing avatar from config.";
00205
00206 KUrl configUrl(d->baseDir);
00207 configUrl.addPath( UserDir );
00208 configUrl.addPath( AvatarConfig );
00209
00210 KConfigGroup avatarConfig ( KSharedConfig::openConfig( configUrl.path(), KConfig::SimpleConfig ), entryToRemove.name );
00211 avatarConfig.deleteGroup();
00212 avatarConfig.sync();
00213
00214 emit avatarRemoved(entryToRemove);
00215
00216 return true;
00217 }
00218
00219 return false;
00220 }
00221
00222 void AvatarManager::Private::createDirectory(const KUrl &directory)
00223 {
00224 if( !QFile::exists(directory.path()) )
00225 {
00226 kDebug(14010) << "Creating directory: " << directory.path();
00227 if( !KIO::NetAccess::mkdir(directory,0) )
00228 {
00229 kDebug(14010) << "Directory " << directory.path() <<" creating failed.";
00230 }
00231 }
00232 }
00233
00234 QImage AvatarManager::Private::scaleImage(const QImage &source)
00235 {
00236 if (source.isNull())
00237 {
00238 return QImage();
00239 }
00240
00241
00242 QImage result(96, 96, QImage::Format_ARGB32);
00243 result.fill(0);
00244
00245 QPainter paint(&result);
00246 float x = 0, y = 0;
00247
00248
00249 if( source.width() > 96 || source.height() > 96 )
00250 {
00251 QImage scaled = source.scaled( 96, 96, Qt::KeepAspectRatio, Qt::SmoothTransformation );
00252
00253 x = (96 - scaled.width()) / 2.0;
00254 y = (96 - scaled.height()) / 2.0;
00255
00256 paint.translate(x, y);
00257 paint.drawImage(QPoint(0, 0), scaled);
00258 } else {
00259 x = (96 - source.width()) / 2.0;
00260 y = (96 - source.height()) / 2.0;
00261
00262 paint.translate(x, y);
00263 paint.drawImage(QPoint(0, 0), source);
00264 }
00265
00266 return result;
00267 }
00268
00269
00270
00271
00272 class AvatarQueryJob::Private
00273 {
00274 public:
00275 Private(AvatarQueryJob *parent)
00276 : queryJob(parent), category(AvatarManager::All)
00277 {}
00278
00279 QPointer<AvatarQueryJob> queryJob;
00280 AvatarManager::AvatarCategory category;
00281 QList<AvatarManager::AvatarEntry> avatarList;
00282 KUrl baseDir;
00283
00284 void listAvatarDirectory(const QString &path);
00285 };
00286
00287 AvatarQueryJob::AvatarQueryJob(QObject *parent)
00288 : KJob(parent), d(new Private(this))
00289 {
00290
00291 }
00292
00293 AvatarQueryJob::~AvatarQueryJob()
00294 {
00295 delete d;
00296 }
00297
00298 void AvatarQueryJob::setQueryFilter(Kopete::AvatarManager::AvatarCategory category)
00299 {
00300 d->category = category;
00301 }
00302
00303 void AvatarQueryJob::start()
00304 {
00305 d->baseDir = KUrl( KStandardDirs::locateLocal("appdata", QLatin1String("avatars") ) );
00306
00307 if( d->category & Kopete::AvatarManager::User )
00308 {
00309 d->listAvatarDirectory( UserDir );
00310 }
00311 if( d->category & Kopete::AvatarManager::Contact )
00312 {
00313 KUrl contactUrl(d->baseDir);
00314 contactUrl.addPath( ContactDir );
00315
00316 QDir contactDir(contactUrl.path());
00317 QStringList subdirsList = contactDir.entryList( QDir::AllDirs | QDir::NoDotAndDotDot );
00318 QString subdir;
00319 foreach(subdir, subdirsList)
00320 {
00321 d->listAvatarDirectory( ContactDir + QDir::separator() + subdir );
00322 }
00323 }
00324
00325
00326 emitResult();
00327 }
00328
00329 QList<Kopete::AvatarManager::AvatarEntry> AvatarQueryJob::avatarList() const
00330 {
00331 return d->avatarList;
00332 }
00333
00334 void AvatarQueryJob::Private::listAvatarDirectory(const QString &relativeDirectory)
00335 {
00336 KUrl avatarDirectory = baseDir;
00337 avatarDirectory.addPath(relativeDirectory);
00338
00339 kDebug(14010) << "Listing avatars in " << avatarDirectory.path();
00340
00341
00342 KUrl avatarConfigUrl = avatarDirectory;
00343 avatarConfigUrl.addPath( AvatarConfig );
00344 if( QFile::exists(avatarConfigUrl.path()) )
00345 {
00346 KConfig *avatarConfig = new KConfig( avatarConfigUrl.path(), KConfig::SimpleConfig);
00347
00348 QStringList groupEntryList = avatarConfig->groupList();
00349 QString groupEntry;
00350 foreach(groupEntry, groupEntryList)
00351 {
00352 KConfigGroup cg(avatarConfig, groupEntry);
00353
00354 Kopete::AvatarManager::AvatarEntry listedEntry;
00355 listedEntry.name = groupEntry;
00356 listedEntry.category = static_cast<Kopete::AvatarManager::AvatarCategory>( cg.readEntry("Category", 0) );
00357
00358 QString filename = cg.readEntry( "Filename", QString() );
00359 KUrl avatarPath(avatarDirectory);
00360 avatarPath.addPath( filename );
00361 listedEntry.path = avatarPath.path();
00362
00363 avatarList << listedEntry;
00364 }
00365 delete avatarConfig;
00366 }
00367 }
00368
00369
00370
00371 }
00372
00373 #include "kopeteavatarmanager.moc"