22 #include "imageprovider.h" 
   26 #include <KImageCache> 
   30 class Akonadi::ImageProviderPrivate
 
   32   Q_DECLARE_PUBLIC( ImageProvider )
 
   36     struct QueuedJobHelper {
 
   42     ImageProviderPrivate( ImageProvider *q ) : q_ptr( q )
 
   49     QImage polishImage( 
const QImage &img )
 
   51       const int sz = 48 * 4;
 
   52       QImage roundedImage = QImage( QSize( sz, sz ), QImage::Format_ARGB32_Premultiplied );
 
   53       roundedImage.fill( Qt::transparent );
 
   55       p.begin( &roundedImage );
 
   56       QPainterPath clippingPath;
 
   57       QRectF imgRect = QRectF( QPoint( 0, 0 ), roundedImage.size() );
 
   58       clippingPath.addRoundedRect( imgRect, 24, 24 );
 
   59       p.setClipPath( clippingPath );
 
   60       p.setClipping( 
true );
 
   61       p.drawImage( QRectF( QPointF( 0, 0 ), roundedImage.size() ), img );
 
   66     QHash<KJob *, QString> jobs;
 
   69     QHash<KJob *, QByteArray> jobData;
 
   75     QList<QueuedJobHelper> queuedJobs;
 
   78     QStringList pendingPersons;
 
   81     KImageCache *imageCache;
 
   87     void result( KJob *job );
 
   92     void recv( KIO::Job *job, 
const QByteArray &data );
 
   97 void Akonadi::ImageProviderPrivate::recv( KIO::Job *job, 
const QByteArray &data )
 
  102 void Akonadi::ImageProviderPrivate::result( KJob *job )
 
  104   Q_Q( ImageProvider );
 
  105   if ( !jobs.contains( job ) ) {
 
  106     kDebug() << 
"Tried to handle unknown job, returning...";
 
  112   if ( queuedJobs.count() > 0 ) {
 
  113     QueuedJobHelper helper = queuedJobs.takeFirst();
 
  114     q->loadImage( helper.who, helper.url, helper.polishImage );
 
  117   if ( job->error() ) {
 
  119     KIO::TransferJob* kiojob = 
dynamic_cast<KIO::TransferJob*
>( job );
 
  120     kError() << 
"Image job for" << jobs.value( job ) << 
"returned error:" << kiojob->errorString();
 
  122     const QString who = jobs.value( job );
 
  125     image.loadFromData( jobData.value( job ) );
 
  126     KIO::TransferJob* kiojob = 
dynamic_cast<KIO::TransferJob*
>( job );
 
  127     const QString cacheKey = who + QLatin1Char( 
'@' ) +
 
  128                              kiojob->property( 
"imageUrl" ).value<KUrl>().pathOrUrl();
 
  130     kDebug() << 
"Downloaded image for" << who << 
"(key:" << cacheKey << 
")";
 
  132     imageCache->insertImage( cacheKey, image );
 
  133     pendingPersons.removeAll( cacheKey );
 
  135     bool polishImage = job->property( 
"polishImage" ).toBool();
 
  137     Q_EMIT q->imageLoaded( who,
 
  138                            kiojob->property( 
"imageUrl" ).value<KUrl>(),
 
  139                            polishImage ? this->polishImage( image ) : image );
 
  143   jobData.remove( job );
 
  146 Akonadi::ImageProvider::ImageProvider( QObject *parent )
 
  148     d_ptr( new ImageProviderPrivate( this ) )
 
  150   Q_D( ImageProvider );
 
  155 Akonadi::ImageProvider::~ImageProvider()
 
  157   Q_D( ImageProvider );
 
  162                                           bool polishImage, KImageCache *cache )
 
  166   if ( who.isEmpty() ) {
 
  170   if ( !d->imageCache && !cache ) {
 
  172     d->imageCache = 
new KImageCache( QLatin1String( 
"plasma_engine_preview" ),
 
  174   } 
else if ( !d->imageCache && cache ) {
 
  176     d->imageCache = cache;
 
  177   } 
else if ( d->imageCache && cache ) {
 
  180     d->imageCache = cache;
 
  183   const QString cacheKey = who + QLatin1Char( 
'@' ) + url.pathOrUrl();
 
  186   if ( d->pendingPersons.contains( cacheKey ) ) {
 
  187     kDebug() << 
"Job for" << who << 
"already running, returning";
 
  193   preview.fill( Qt::transparent );
 
  195   if ( d->imageCache->findImage( cacheKey, &preview ) ) {
 
  197     kDebug() << 
"Image for" << who << 
"already in cache, returning it";
 
  198     return polishImage ? d->polishImage( preview ) : preview;
 
  201   if ( !url.isValid() ) {
 
  202     kDebug() << 
"Invalid url, returning";
 
  206   kDebug() << 
"No cache, fetching image for" << who;
 
  208   d->pendingPersons << cacheKey;
 
  212   if ( d->runningJobs < 500 ) {
 
  214     kDebug() << 
"Starting fetch job for" << who;
 
  215     KIO::Job *job = KIO::get( url, KIO::NoReload, KIO::HideProgressInfo );
 
  216     job->setAutoDelete( 
true );
 
  218     connect( job, SIGNAL(data(KIO::Job*,QByteArray)),
 
  219              this, SLOT(recv(KIO::Job*,QByteArray)) );
 
  220     connect( job, SIGNAL(result(KJob*)),
 
  221              this, SLOT(result(KJob*)) );
 
  226     job->setProperty( 
"imageUrl", url );
 
  227     job->setProperty( 
"polishImage", polishImage );
 
  230     kDebug() << 
"Queuing job for" << who;
 
  231     ImageProviderPrivate::QueuedJobHelper helper;
 
  234     helper.polishImage = polishImage;
 
  235     d->queuedJobs.append( helper );
 
  244   Q_FOREACH ( KJob *job, d->jobs.keys() ) {
 
  246     d->jobs.remove( job );
 
  247     d->jobData.remove( job );
 
  251 #include "moc_imageprovider.cpp" 
QImage loadImage(const QString &who, const KUrl &url, bool polishImage=false, KImageCache *cache=0)
Starts fetching the avatar/image from network. 
 
Class fetching avatars/images from network and storing them in KImageCache. 
 
void abortAllJobs()
Aborts all running jobs.