20 #include <QtCore/QLatin1String>
21 #include <QtCore/QBuffer>
22 #include <QtCore/QCoreApplication>
23 #include <QtCore/QFile>
24 #include <QtCore/QPointer>
25 #include <QtCore/QStringList>
26 #include <QtCore/QDir>
27 #include <QtGui/QPainter>
28 #include <QtGui/QImageReader>
32 #include <kstandarddirs.h>
37 #include <kio/netaccess.h>
49 AvatarManager *AvatarManager::s_self = 0;
60 class AvatarManager::Private
69 void createDirectory(
const KUrl &directory);
75 QImage scaleImage(
const QImage &source);
78 static const QString
UserDir(
"User");
83 AvatarManager::AvatarManager(
QObject *parent)
84 :
QObject(parent), d(new Private)
87 d->baseDir = KUrl( KStandardDirs::locateLocal(
"appdata", QLatin1String(
"avatars") ) );
90 d->createDirectory( d->baseDir );
101 Q_ASSERT(!newEntry.
name.isEmpty());
103 KUrl avatarUrl(d->baseDir);
110 d->createDirectory( avatarUrl );
114 d->createDirectory( avatarUrl );
120 avatarUrl.addPath( protocolName );
121 d->createDirectory( avatarUrl );
122 avatarUrl.addPath( accountName );
123 d->createDirectory( avatarUrl );
130 KUrl dataUrl(avatarUrl);
132 kDebug(14010) <<
"Base directory: " << avatarUrl.toLocalFile();
135 KUrl configUrl = avatarUrl;
138 QByteArray data = newEntry.
data;
139 QImage avatar = newEntry.
image;
143 avatar.loadFromData(data);
145 else if(!newEntry.
dataPath.isEmpty()){
147 f.open(QIODevice::ReadOnly);
151 avatar.loadFromData(data);
153 else if(!avatar.isNull()){
154 QByteArray tempArray;
155 QBuffer tempBuffer(&tempArray);
156 tempBuffer.open( QIODevice::WriteOnly );
157 avatar.save(&tempBuffer,
"PNG");
161 else if(!newEntry.
path.isEmpty()){
162 avatar = QImage(newEntry.
path);
164 QFile f(newEntry.
path);
165 f.open(QIODevice::ReadOnly);
171 kDebug() <<
"Warning: No valid image source!";
175 avatar = d->scaleImage(avatar);
177 QString avatarFilename;
182 avatarFilename = KIO::encodeFileName(newEntry.
contact->
contactId()) +
".png";
189 QByteArray tempArray;
190 QBuffer tempBuffer(&tempArray);
191 tempBuffer.open( QIODevice::WriteOnly );
192 avatar.save(&tempBuffer,
"PNG");
193 KMD5 context(tempArray);
194 avatarFilename = context.hexDigest() + QLatin1String(
".png");
198 kDebug(14010) <<
"Saving " << avatarFilename <<
" on disk.";
199 avatarUrl.addPath( avatarFilename );
201 if( !avatar.save( avatarUrl.toLocalFile(),
"PNG") )
203 kDebug(14010) <<
"Saving of scaled avatar to " << avatarUrl.toLocalFile() <<
" failed !";
207 QString dataFilename;
212 dataFilename = KIO::encodeFileName(newEntry.
contact->
contactId()) + QLatin1String(
"_");
215 dataFilename += KMD5(data).hexDigest();
217 QBuffer buffer(&data);
218 buffer.open(QIODevice::ReadOnly);
219 QImageReader ir(&buffer);
220 dataFilename += QLatin1String(
".") + QLatin1String(ir.format());
223 dataUrl.addPath(dataFilename);
224 QFile f(dataUrl.toLocalFile());
225 if (!f.open(QIODevice::WriteOnly))
227 kDebug(14010) <<
"Saving of original avatar to " << dataUrl.toLocalFile() <<
" failed !";
235 KConfigGroup avatarConfig(KSharedConfig::openConfig( configUrl.toLocalFile(), KConfig::SimpleConfig), newEntry.
name );
237 avatarConfig.writeEntry(
"Filename", avatarFilename );
238 avatarConfig.writeEntry(
"DataFilename", dataFilename );
239 avatarConfig.writeEntry(
"Category",
int(newEntry.
category) );
244 newEntry.
path = avatarUrl.toLocalFile();
245 newEntry.
dataPath = dataUrl.toLocalFile();
255 if( entryToRemove.
name.isEmpty() && entryToRemove.
path.isEmpty() )
263 if( KIO::NetAccess::del(KUrl(entryToRemove.
path),0) )
265 kDebug(14010) <<
"Removing avatar from config.";
267 KUrl configUrl(d->baseDir);
271 KConfigGroup avatarConfig ( KSharedConfig::openConfig( configUrl.toLocalFile(), KConfig::SimpleConfig ), entryToRemove.
name );
272 avatarConfig.deleteGroup();
285 if( entryToCheck.
name.isEmpty() )
292 KUrl configUrl(d->baseDir);
296 KConfigGroup avatarConfig ( KSharedConfig::openConfig( configUrl.toLocalFile(), KConfig::SimpleConfig ), avatarName );
297 kDebug(14010) <<
"Checking if an avatar exists: " << avatarName;
298 if(!avatarConfig.exists()){
304 void AvatarManager::Private::createDirectory(
const KUrl &directory)
306 if( !QFile::exists(directory.toLocalFile()) )
308 kDebug(14010) <<
"Creating directory: " << directory.toLocalFile();
309 if( !KIO::NetAccess::mkdir(directory,0) )
311 kDebug(14010) <<
"Directory " << directory.toLocalFile() <<
" creating failed.";
316 QImage AvatarManager::Private::scaleImage(
const QImage &source)
324 QImage result(96, 96, QImage::Format_ARGB32);
327 QPainter paint(&result);
331 if( source.width() > 96 || source.height() > 96 )
333 const QImage scaled = source.scaled( 96, 96, Qt::KeepAspectRatio, Qt::SmoothTransformation );
335 x = (96 - scaled.width()) / 2.0;
336 y = (96 - scaled.height()) / 2.0;
338 paint.translate(x, y);
339 paint.drawImage(QPoint(0, 0), scaled);
341 x = (96 - source.width()) / 2.0;
342 y = (96 - source.height()) / 2.0;
344 paint.translate(x, y);
345 paint.drawImage(QPoint(0, 0), source);
354 class AvatarQueryJob::Private
358 : queryJob(parent), category(AvatarManager::
All)
361 QPointer<AvatarQueryJob> queryJob;
362 AvatarManager::AvatarCategory category;
366 void listAvatarDirectory(
const QString &path);
370 :
KJob(parent), d(new Private(this))
382 d->category = category;
387 d->baseDir = KUrl( KStandardDirs::locateLocal(
"appdata", QLatin1String(
"avatars") ) );
391 d->listAvatarDirectory(
UserDir );
395 KUrl contactUrl(d->baseDir);
398 const QDir contactDir(contactUrl.toLocalFile());
399 const QStringList subdirsList = contactDir.entryList( QDir::AllDirs | QDir::NoDotAndDotDot );
400 foreach(
const QString &subdir, subdirsList)
402 d->listAvatarDirectory(
ContactDir + QDir::separator() + subdir );
412 return d->avatarList;
415 void AvatarQueryJob::Private::listAvatarDirectory(
const QString &relativeDirectory)
417 KUrl avatarDirectory = baseDir;
418 avatarDirectory.addPath(relativeDirectory);
420 kDebug(14010) <<
"Listing avatars in " << avatarDirectory.toLocalFile();
423 KUrl avatarConfigUrl = avatarDirectory;
425 if( QFile::exists(avatarConfigUrl.toLocalFile()) )
427 KConfig *avatarConfig =
new KConfig( avatarConfigUrl.toLocalFile(), KConfig::SimpleConfig);
429 const QStringList groupEntryList = avatarConfig->groupList();
430 foreach(
const QString &groupEntry, groupEntryList)
432 KConfigGroup cg(avatarConfig, groupEntry);
435 listedEntry.
name = groupEntry;
436 listedEntry.
category =
static_cast<Kopete::AvatarManager::AvatarCategory
>( cg.readEntry(
"Category", 0) );
438 const QString filename = cg.readEntry(
"Filename", QString() );
439 KUrl avatarPath(avatarDirectory);
440 avatarPath.addPath( filename );
441 listedEntry.
path = avatarPath.toLocalFile();
443 const QString dataFilename = cg.readEntry(
"DataFilename", QString() );
444 KUrl dataPath(avatarDirectory);
445 dataPath.addPath( dataFilename );
446 listedEntry.
dataPath = dataPath.toLocalFile();
448 avatarList << listedEntry;
458 #include "kopeteavatarmanager.moc"
static const QString ContactDir("Contacts")
static const QString AvatarConfig("avatarconfig.rc")
Protocol * protocol() const
AvatarQueryJob(QObject *parent=0)
Kopete::Contact * contact
contact is used when adding a new contact avatar. AvatarManager use it to create the final url...
AvatarManager::AvatarCategory category
category in which the avatar belong
QString dataPath
path is the full path to the data on disk
QImage image
image is used when adding a new avatar, AvatarManager will write the image on disk.
struct Kopete::AvatarManager::AvatarEntry AvatarEntry
A single entry in AvatarManager.
void avatarRemoved(Kopete::AvatarManager::AvatarEntry entryRemoved)
An avatar was removed from storage.
static const QString UserDir("User")
QString name
name is a friendly name to identity the avatar
QString pluginId() const
Get the plugin id.
bool remove(Kopete::AvatarManager::AvatarEntry entryToRemove)
Remove an avatar from the storage.
static AvatarManager * self()
Get the only instance of AvatarManager.
void avatarAdded(Kopete::AvatarManager::AvatarEntry newEntry)
An avatar was added into the storage.
QByteArray data
original data used to construct the image
QList< Kopete::AvatarManager::AvatarEntry > avatarList() const
Get the avatar list based on the query.
A single entry in AvatarManager.
Kopete::AvatarManager::AvatarEntry add(Kopete::AvatarManager::AvatarEntry newEntry)
Add an new avatar to the storage.
QString path
path is the full path to the image on disk
void setQueryFilter(Kopete::AvatarManager::AvatarCategory category)
Set the filter for the avatar job.
bool exists(Kopete::AvatarManager::AvatarEntry avatarToCheck)
Check if an avatar exists.
Manage the avatar storage.