• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdenetwork
  • Sitemap
  • Contact Us
 

kopete/libkopete

kopeteavatarmanager.cpp

Go to the documentation of this file.
00001 /*
00002     kopeteavatarmanager.cpp - Global avatar manager
00003 
00004     Copyright (c) 2007      by Michaƫl Larouche      <larouche@kde.org>
00005 
00006     Kopete    (c) 2002-2007 by the Kopete developers <kopete-devel@kde.org>
00007 
00008     *************************************************************************
00009     *                                                                       *
00010     * This library is free software; you can redistribute it and/or         *
00011     * modify it under the terms of the GNU Lesser General Public            *
00012     * License as published by the Free Software Foundation; either          *
00013     * version 2 of the License, or (at your option) any later version.      *
00014     *                                                                       *
00015     *************************************************************************
00016 */
00017 #include "kopeteavatarmanager.h"
00018 
00019 // Qt includes
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 // KDE includes
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 // Kopete includes
00040 #include <kopetecontact.h>
00041 #include <kopeteaccount.h>
00042 
00043 namespace Kopete
00044 {
00045 
00046 //BEGIN AvatarManager
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     // Locate avatar data dir on disk
00085     d->baseDir = KUrl( KStandardDirs::locateLocal("appdata", QLatin1String("avatars") ) );
00086 
00087     // Create directory on disk, if necessary
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     // First find where to save the file
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             // Use the account id for sub directory
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     // Second, open the avatar configuration in current directory.
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     // Scale avatar
00141     avatar = d->scaleImage(avatar);
00142 
00143     QString avatarFilename;
00144 
00145     // for the contact avatar, save it with the contactId + .png
00146     if (newEntry.category == AvatarManager::Contact && newEntry.contact)
00147     {
00148         avatarFilename = newEntry.contact->contactId() + ".png";
00149     }
00150     else
00151     {
00152         // Find MD5 hash for filename
00153         // MD5 always contain ASCII caracteres so it is more save for a filename.
00154         // Name can use UTF-8 characters.
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     // Save image on disk   
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         // Save metadata of image
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         // Add final path to the new entry for avatarAdded signal
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     // We need name and path to remove an avatar from the storage.
00194     if( entryToRemove.name.isEmpty() && entryToRemove.path.isEmpty() )
00195         return false;
00196     
00197     // We don't allow removing avatars from Contact category
00198     if( entryToRemove.category & Kopete::AvatarManager::Contact )
00199         return false;
00200 
00201     // Delete the image file first, file delete is more likely to fail than config group remove.
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     //make an empty image and fill with transparent color
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     // scale and center the image
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 //END AvatarManager
00270 
00271 //BEGIN AvatarQueryJob
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     // Finish the job
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     // Look for Avatar configuration
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         // Each avatar entry in configuration is a group
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 //END AvatarQueryJob
00370 
00371 }
00372 
00373 #include "kopeteavatarmanager.moc"

kopete/libkopete

Skip menu "kopete/libkopete"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdenetwork

Skip menu "kdenetwork"
  • kget
  • kopete
  •   kopete
  •   libkopete
  •       libpapillon
  • krfb
Generated for kdenetwork by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal