[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kopete-devel
Subject:    Re: [kopete-devel] [PATCH] New class Kopete::Picture
From:       Michaël_Larouche <michael.larouche () kdemail ! net>
Date:       2005-12-10 20:06:19
Message-ID: 200512101506.21379.michael.larouche () kdemail ! net
[Download RAW message or body]

[Attachment #2 (multipart/signed)]

[Attachment #4 (multipart/mixed)]


Le December 10, 2005 13:02, Olivier Goffart a écrit :
> Le Samedi 10 Décembre 2005 15:50, Michaël Larouche a écrit :
> > Le December 8, 2005 19:48, Olivier Goffart a écrit :
> > >  - I don't think it's a good idea to use it by pointer.
> >
> > Yep, I reworked my class to be implicitly shared.
>
> Good.
> It was IMO not even required to be shared, because both QString, QPixmap,
> and QImage are shared already.
> Anyway, if it's done, it's ok.
>
> > >  - You probably shouldn't do the conversion immediatly, but only on
> > > demand.
> >
> > I prefer the current way. IMO the "getter" method should be fast, even at
> > first call.
>
> I disagree.
> Why should this be so fast ?
> There is no reason to do all the conversion when Kopete start, and eat all
> the memory, for contact we will not talk with, or we don't need the photo,
> ...
>
> > >  - QPixmap vs. QImage ?
> >
> > Yes, QPixmap should be used, because it's faster for display but QImage
> > was used in MetaContact instead, so I used QImage.
>
> I'm not really sure here.
> We also apply effect to the photo (in the contactlist)

Yet another version which do the conversion on demand. See the new attached 
patch. 
-- 
Michaël Larouche (Shock The Dark Mage)
KDE developer working on Kopete, Kamefu...on dial-up :P
--------------------------------------
Blog: http://mlarouche.blogspot.com/
MSN/Email: michael.larouche@kdemail.net
IRC: irc.freenode.org/DarkShock on #kopete, #kde-devel, #kde4-devel, #plasma, 
#kamefu
Jabber: darkshock@myjabber.net, darkshock@linux-quebec.org, 
darkshock@gmail.com
AIM: darkshock19
Gadu-Gadu: 1172438
ICQ: 29644783
Yahoo: darkshock_TT

["kopetepicture_v4.patch" (text/x-diff)]

Index: kopete/chatwindow/chatmessagepart.cpp
===================================================================
--- kopete/chatwindow/chatmessagepart.cpp	(révision 487239)
+++ kopete/chatwindow/chatmessagepart.cpp	(copie de travail)
@@ -80,6 +80,7 @@
 #include "kopeteglobal.h"
 #include "kopeteemoticons.h"
 #include "kopeteview.h"
+#include "kopetepicture.h"
 
 #include "kopetechatwindowstyle.h"
 
@@ -989,12 +990,12 @@
 		resultHTML = resultHTML.replace( pos , timeRegExp.cap(0).length() , timeKeyword );
 	}
 
-	// FIXME: Force update of photo when using image path.
-	// Replace userIconPath (use image path)
+	// Replace userIconPath
 	if( message.from() )
 	{
-
-		QString photoPath = \
message.from()->property(Kopete::Global::Properties::self()->photo().key()).value().toString();
 +		QString photoPath;
+#if 0
+		photoPath = message.from()->property(Kopete::Global::Properties::self()->photo().key()).value().toString();
  // If the photo path is empty, set the default buddy icon for the theme
 		if( photoPath.isEmpty() )
 		{
@@ -1003,19 +1004,19 @@
 			else if(message.direction() == Kopete::Message::Outbound)
 				photoPath = QString::fromUtf8("Outgoing/buddy_icon.png");
 		}
-		resultHTML = resultHTML.replace(QString::fromUtf8("%userIconPath%"), photoPath);
-#if 0
-		QImage photo = message.from()->metaContact()->photo();
-		if( !photo.isNull() )
+#endif
+		if( !message.from()->metaContact()->picture().isNull() )
 		{
-			QByteArray ba;
-			QBuffer buffer( ba );
-			buffer.open( IO_WriteOnly );
-			photo.save ( &buffer, "PNG" );
-			QString photo64=KCodecs::base64Encode(ba);
-			resultHTML = resultHTML.replace( QString::fromUtf8("%userIconPath%"), \
QString("data:image/png;base64,%1").arg(photo64) ); +			photoPath = \
QString("data:image/png;base64,%1").arg( \
message.from()->metaContact()->picture().base64() );  }
-#endif
+		else
+		{
+			if(message.direction() == Kopete::Message::Inbound)
+				photoPath = QString::fromUtf8("Incoming/buddy_icon.png");
+			else if(message.direction() == Kopete::Message::Outbound)
+				photoPath = QString::fromUtf8("Outgoing/buddy_icon.png");
+		}
+		resultHTML = resultHTML.replace(QString::fromUtf8("%userIconPath%"), photoPath);
 	}
 
 	// Replace messages.
@@ -1069,7 +1070,7 @@
 			resultHTML = resultHTML.replace( pos , timeRegExp.cap(0).length() , timeKeyword \
);  }
 		// Get contact image paths
-		// TODO: Use metaContact current photo path.
+#if 0
 		QString photoIncomingPath, photoOutgoingPath;
 		photoIncomingPath = remoteContact->property( \
Kopete::Global::Properties::self()->photo().key()).value().toString();  \
photoOutgoingPath = d->manager->myself()->property(Kopete::Global::Properties::self()->photo().key()).value().toString();
 @@ -1081,28 +1082,29 @@
 
 		resultHTML = resultHTML.replace( QString::fromUtf8("%incomingIconPath%"), \
photoIncomingPath);  resultHTML = resultHTML.replace( \
                QString::fromUtf8("%outgoingIconPath%"), photoOutgoingPath);
-#if 0
-		QImage photoIncoming = remoteContact->metaContact()->photo();
-		if( !photoIncoming.isNull() )
+#endif
+		QString photoIncoming, photoOutgoing;
+		if( !remoteContact->metaContact()->picture().isNull() )
 		{
-			QByteArray ba;
-			QBuffer buffer( ba );
-			buffer.open( IO_WriteOnly );
-			photoIncoming.save ( &buffer, "PNG" );
-			QString photo64=KCodecs::base64Encode(ba);
-			resultHTML = resultHTML.replace( QString::fromUtf8("%incomingIconPath%"), \
QString("data:image/png;base64,%1").arg(photo64) ); +			photoIncoming = \
QString("data:image/png;base64,%1").arg( \
remoteContact->metaContact()->picture().base64() );  }
-		QImage photoOutgoing = d->manager->myself()->metaContact()->photo();
-		if( !photoOutgoing.isNull() )
+		else
 		{
-			QByteArray ba;
-			QBuffer buffer( ba );
-			buffer.open( IO_WriteOnly );
-			photoOutgoing.save ( &buffer, "PNG" );
-			QString photo64=KCodecs::base64Encode(ba);
-			resultHTML = resultHTML.replace( QString::fromUtf8("%outgoingIconPath%"), \
QString("data:image/png;base64,%1").arg(photo64) ); +			photoIncoming = \
QString::fromUtf8("Incoming/buddy_icon.png");  }
-#endif
+		
+		if( !d->manager->myself()->metaContact()->picture().isNull() )
+		{
+			photoOutgoing =  QString("data:image/png;base64,%1").arg( \
d->manager->myself()->metaContact()->picture().base64() ); +		}
+		else
+		{
+			photoOutgoing = QString::fromUtf8("Outgoing/buddy_icon.png");
+		}
+
+
+		resultHTML = resultHTML.replace( QString::fromUtf8("%incomingIconPath%"), \
photoIncoming); +		resultHTML = resultHTML.replace( \
QString::fromUtf8("%outgoingIconPath%"), photoOutgoing );  }
 
 	return resultHTML;
Index: libkopete/kopetepicture.h
===================================================================
--- libkopete/kopetepicture.h	(révision 0)
+++ libkopete/kopetepicture.h	(révision 0)
@@ -0,0 +1,149 @@
+/*
+    kopetepicture.h - Kopete Picture
+
+    Copyright (c) 2005      by Michaël Larouche       \
<michael.larouche@kdemail.net> +
+    Kopete    (c) 2002-2005 by the Kopete developers  <kopete-devel@kde.org>
+
+    *************************************************************************
+    *                                                                       *
+    * This library is free software; you can redistribute it and/or         *
+    * modify it under the terms of the GNU Lesser General Public            *
+    * License as published by the Free Software Foundation; either          *
+    * version 2 of the License, or (at your option) any later version.      *
+    *                                                                       *
+    *************************************************************************
+*/
+#ifndef KOPETEPICTURE_H
+#define KOPETEPICTURE_H
+
+#include <kdemacros.h>
+#include <ksharedptr.h>
+#include "kopete_export.h"
+
+#include <qimage.h>
+
+namespace KABC
+{
+	class Picture;
+}
+
+namespace Kopete
+{
+/**
+ * @brief Represent a picture in Kopete context
+ *
+ * It kept a cache of a QImage object, a base64 string and
+ * a path to a image file. It ensure that all source are synced.
+ * Interally, the image is stored in PNG format when possible.
+ * It can happen that the image path do not return a PNG file.
+ *
+ * You can only use an QImage and a image path to create/update
+ * the picture.
+ * If the picture doesn't exist as a file, it generate a local
+ * copy into ~/.kde/share/apps/kopete/metacontactpicturecache
+ *
+ * This class is implicitly shared, so don't use it as a pointer.
+ *
+ * How to use this class:
+ * @code
+ * Kopete::Picture picture;
+ * picture.setPicture(QImage());
+ * picture.setPicture(QString("/tmp/image.png"));
+ * 
+ * QString base64 = picture.base64();
+ * QString path = picture.path();
+ * QImage image = picture.image();
+ * @endcode
+ *
+ * @author Michaël Larouche <michael.larouche@kdemail.net>
+ */
+class KOPETE_EXPORT Picture	
+{
+public:
+	/**
+	 * Create a empty Kopete::Picture
+	 */
+	Picture();
+	/**
+	 * Create a picture from a local path.
+	 */
+	Picture(const QString &path);
+	/**
+	 * Create a picture from a QImage.
+	 */
+	Picture(const QImage &image);
+	/**
+	 * Create a picture from a KABC::Picture.
+	 */
+	Picture(const KABC::Picture &picture);
+	/**
+	 * Copy a picture. It doesn't create a full copy, it just make a reference.
+	 */
+	Picture(const Picture &other);
+	/**
+	 * Delete the Kopete::Picture
+	 */
+	~Picture();
+	/**
+	 * Assignment operator.
+	 * Like the copy constructor, it just make a reference.
+	 */
+	Picture &operator=(const Picture &other);
+
+	/**
+	 * Return the current picture as QImage.
+	 * QImage can used to draw the image on a context.
+	 * 
+	 * @return the QImage cache of current picture.
+	 */
+	QImage image();
+	/**
+	 * Return the current picture as a base64 string.
+	 * The base64 is used to include the picture into a XML/XHTML context.
+	 */
+	QString base64();
+	/**
+	 * Return the local path of the current picture.
+	 */
+	QString path();
+
+	/**
+	 * Check if the picture is null.
+ 	 */
+	bool isNull();
+	/**
+	 * Reset the picture.
+	 */
+	void clear();
+
+	/**
+	 * Set the picture content.
+	 * @param image the picture as a QImage.
+	 */
+	void setPicture(const QImage &image);
+	/**
+	 * Set the picture content.
+	 * @param path the path to the picture.
+	 */
+	void setPicture(const QString &path);
+	/**
+	 * Set the picture content.
+	 * @param picture a KABC Picture.
+	 */
+	void setPicture(const KABC::Picture &picture);
+	
+private:
+	/**
+	 * Kopete::Picture is implicitly shared.
+	 * Detach the instance when modifying data.
+	 */
+	void detach();
+
+	class Private;
+	KSharedPtr<Private> d;
+};
+
+}//END namespace Kopete
+
+#endif
Index: libkopete/kopetecontactlist.cpp
===================================================================
--- libkopete/kopetecontactlist.cpp	(révision 487239)
+++ libkopete/kopetecontactlist.cpp	(copie de travail)
@@ -40,6 +40,7 @@
 #include "kopeteaccount.h"
 #include "kopeteaccountmanager.h"
 #include "kopetegroup.h"
+#include "kopetepicture.h"
 
 
 namespace  Kopete
@@ -332,32 +333,9 @@
 
 void ContactList::slotPhotoChanged()
 {
-	QString photoURL;
-	
-	MetaContact::PropertySource photoSource = myself()->photoSource();
-	
-	// Save the image to ~./kde/share/apps/kopete/global-photo.png if the source is not \
                custom.
-	if(photoSource != MetaContact::SourceCustom)
-	{
-		QImage globalPhoto = myself()->photo();
+	kdDebug( 14010 ) << k_funcinfo << myself()->picture().path() << endl;
 
-		photoURL = "global-photo.png";
-		photoURL = locateLocal("appdata", photoURL);
-
-		if(!globalPhoto.save(photoURL, "PNG"))
-		{
-				kdDebug( 14010 ) << k_funcinfo << "Error while saving the global photo to file." \
                << endl;
-				return;
-		}
-	}
-	else
-	{
-		photoURL = myself()->customPhoto().path();
-	}
-
-	kdDebug( 14010 ) << k_funcinfo << photoURL << endl;
-
-	emit globalIdentityChanged(Kopete::Global::Properties::self()->photo().key(), \
photoURL); +	emit globalIdentityChanged(Kopete::Global::Properties::self()->photo().key(), \
myself()->picture().path());  }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
                
Index: libkopete/kopetemetacontact.cpp
===================================================================
--- libkopete/kopetemetacontact.cpp	(révision 487239)
+++ libkopete/kopetemetacontact.cpp	(copie de travail)
@@ -41,6 +41,7 @@
 #include "kopeteglobal.h"
 #include "kopeteprefs.h"
 #include "kopeteuiglobal.h"
+#include "kopetepicture.h"
 
 namespace Kopete {
 
@@ -56,10 +57,13 @@
 { public:
 	Private() :
 		photoSource(MetaContact::SourceCustom), \
                displayNameSource(MetaContact::SourceCustom),
-		displayNameSourceContact(0L),  photoSourceContact(0L), temporary(false), \
                onlineStatus(Kopete::OnlineStatus::Offline),
-		photoSyncedWithKABC(false)
+		displayNameSourceContact(0L),  photoSourceContact(0L), temporary(false),
+		onlineStatus(Kopete::OnlineStatus::Offline), photoSyncedWithKABC(false)
 	{}
 
+	~Private()
+	{}
+
 	QPtrList<Contact> contacts;
 
 	// property sources	
@@ -75,7 +79,6 @@
 	
 	// used when source is custom
 	QString displayName;
-	KURL photoUrl;
 
 	QPtrList<Group> groups;
 	QMap<QString, QMap<QString, QString> > addressBook;
@@ -89,7 +92,7 @@
 	QString photoSourcePID, photoSourceAID, photoSourceCID;
 
 	// The photo cache. Reduce disk access and CPU usage.
-	QImage customPhotoCache, contactPhotoCache;
+	Picture customPicture, contactPicture, kabcPicture;
 };
 
 MetaContact::MetaContact()
@@ -107,6 +110,8 @@
 	connect( this, SIGNAL( contactAdded( Kopete::Contact * ) ), SIGNAL( \
persistentDataChanged() ) );  connect( this, SIGNAL( contactRemoved( Kopete::Contact \
* ) ), SIGNAL( persistentDataChanged() ) );  
+	// Update the KABC picture when the KDE Address book change.
+	connect(KABCPersistence::self()->addressBook(), \
SIGNAL(addressBookChanged(AddressBook *)), this, \
SLOT(slotUpdateAddressBookPicture()));  
 	// make sure MetaContact is at least in one group
 	addToGroup( Group::topLevel() );
@@ -318,7 +323,6 @@
 	d->photoSource = source;	
 	if ( source != oldSource )
 	{
-		Message::clearImageCache();
 		emit photoChanged();
 	}
 }
@@ -653,45 +657,41 @@
 
 KURL MetaContact::customPhoto() const
 {
-	return d->photoUrl;
+	return KURL(d->customPicture.path());
 }
 
 void MetaContact::setPhoto( const KURL &url )
 {
-	d->photoUrl = url;
-	// Create the cache for the photo.
-	d->customPhotoCache = photoFromCustom();
+	d->customPicture.setPicture(url.path());
 
 	if ( photoSource() == SourceCustom )
 	{
-		Message::clearImageCache();
 		emit photoChanged();
 	}
 }
 
 QImage MetaContact::photo() const
 {
+	return picture().image();
+}
+
+Picture &MetaContact::picture() const
+{
 	if ( photoSource() == SourceKABC )
 	{
-		// kabc source, try to get from addressbook
-		// if the metacontact has a kabc association
-		if ( ! metaContactId().isEmpty() )
-			return photoFromKABC(metaContactId());
+		return d->kabcPicture;
 	}
 	else if ( photoSource() == SourceContact )
 	{
-		return d->contactPhotoCache;
+		return d->contactPicture;
 	}
 
-	return d->customPhotoCache;
+	return d->customPicture;
 }
 
 QImage MetaContact::photoFromCustom() const
 {
-	if ( d->photoUrl.isEmpty() || !d->photoUrl.isValid() )
-		return QImage();
-
-	return QImage(d->photoUrl.path());
+	return d->customPicture.image();
 }
 
 QImage photoFromContact( Kopete::Contact *contact) /*const*/
@@ -771,11 +771,23 @@
 	
 	// Create a cache for the contact photo.
 	if(d->photoSourceContact != 0L)
-		d->contactPhotoCache = photoFromContact(d->photoSourceContact);
+	{
+		QVariant photoProp;
+		if ( contact->hasProperty( Kopete::Global::Properties::self()->photo().key() ) )
+			photoProp = contact->property( Kopete::Global::Properties::self()->photo().key() \
).value();  
+		if(photoProp.canCast( QVariant::Image ))
+			d->contactPicture.setPicture(photoProp.toImage());
+		else if(photoProp.canCast( QVariant::Pixmap ))
+			d->contactPicture.setPicture(photoProp.toPixmap().convertToImage());
+		else if(!photoProp.asString().isEmpty())
+		{
+			d->contactPicture.setPicture(photoProp.toString());
+		}
+	}
+
 	if ( photoSource() == SourceContact )
 	{
-		Message::clearImageCache();
 		emit photoChanged();
 	}
 }
@@ -818,11 +830,7 @@
 				if(d->photoSyncedWithKABC)
 					setPhotoSyncedWithKABC(true);
 					
-				// Update the contact photo cache.
-				d->contactPhotoCache = photoFromContact(subcontact);
-
-				Message::clearImageCache();
-				emit photoChanged();
+				setPhotoSourceContact(subcontact);
 			}
 		}
 	}
@@ -927,7 +935,7 @@
 	displayName.appendChild( metaContact.createTextNode( d->displayName ) );
 	metaContact.documentElement().appendChild( displayName );
 	QDomElement photo = metaContact.createElement( QString::fromUtf8("photo" ) );
-	KURL photoUrl = d->photoUrl;
+	KURL photoUrl = KURL(d->customPicture.path());
 	photo.appendChild( metaContact.createTextNode( photoUrl.url() ) );
 	metaContact.documentElement().appendChild( photo );
 
@@ -1012,7 +1020,11 @@
 
 	QString strContactId = element.attribute( QString::fromUtf8("contactId") );
 	if( !strContactId.isEmpty() )
+	{
 		d->metaContactId = strContactId;
+		// Set the KABC Picture
+		slotUpdateAddressBookPicture();
+	}
 
 	QDomElement contactElement = element.firstChild().toElement();
 	while( !contactElement.isNull() )
@@ -1255,6 +1267,28 @@
 	setPhotoSourceContact( findContact( d->photoSourcePID, d->photoSourceAID, \
d->photoSourceCID) );  }
 
+void MetaContact::slotUpdateAddressBookPicture()
+{
+	KABC::AddressBook* ab = KABCPersistence::self()->addressBook();
+	QString id = metaContactId();
+	if ( !id.isEmpty() && !id.contains(':') )
+	{
+		KABC::Addressee theAddressee = ab->findByUid(id);
+		if ( theAddressee.isEmpty() )
+		{
+			kdDebug( 14010 ) << k_funcinfo << "no KABC::Addressee found for ( " << id << " ) \
" << " in current address book" << endl; +		}
+		else
+		{
+			KABC::Picture pic = theAddressee.photo();
+			if ( pic.data().isNull() && pic.url().isEmpty() )
+				pic = theAddressee.logo();
+
+			d->kabcPicture.setPicture(pic);
+		}
+	}
+}
+
 bool MetaContact::isTemporary() const
 {
 	return d->temporary;
@@ -1333,8 +1367,8 @@
 			}
 			case SourceCustom:
 			{
-				if( !d->photoUrl.isEmpty() )
-					newValue = d->photoUrl.url();
+				if( !d->customPicture.isNull() )
+					newValue = d->customPicture.path();
 				break;
 			}
 			// Don't sync the photo with KABC if the source is KABC !
Index: libkopete/kopetepicture.cpp
===================================================================
--- libkopete/kopetepicture.cpp	(révision 0)
+++ libkopete/kopetepicture.cpp	(révision 0)
@@ -0,0 +1,205 @@
+/*
+    kopetepicture.cpp - Kopete Picture
+
+    Copyright (c) 2005      by Michaël Larouche       \
<michael.larouche@kdemail.net> +
+    Kopete    (c) 2002-2005 by the Kopete developers  <kopete-devel@kde.org>
+
+    *************************************************************************
+    *                                                                       *
+    * This library is free software; you can redistribute it and/or         *
+    * modify it under the terms of the GNU Lesser General Public            *
+    * License as published by the Free Software Foundation; either          *
+    * version 2 of the License, or (at your option) any later version.      *
+    *                                                                       *
+    *************************************************************************
+*/
+#include "kopetepicture.h"
+
+#include <qbuffer.h>
+
+#include <kabc/picture.h>
+
+#include <kmdcodec.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+
+namespace Kopete
+{
+
+class Picture::Private : public KShared
+{
+public:
+	Private()
+	 : updatePath(false), updateImage(false), updateBase64(false)
+	{}
+
+	QString pictureBase64;
+	QImage pictureImage;
+	QString picturePath;
+
+	bool updatePath;
+	bool updateImage;
+	bool updateBase64;
+};
+
+Picture::Picture()
+ : d(new Private)
+{
+}
+
+Picture::Picture(const QString &path)
+ : d(new Private)
+{
+	setPicture(path);
+}
+
+Picture::Picture(const QImage &image)
+ : d(new Private)
+{
+	setPicture(image);
+}
+
+Picture::Picture(const KABC::Picture &picture)
+ : d(new Private)
+{
+	setPicture(picture);
+}
+
+Picture::Picture(const Picture &other)
+ : d(other.d)
+{}
+
+Picture::~Picture()
+{}
+
+Picture &Picture::operator=(const Picture &other)
+{
+	d = other.d;
+	return *this;
+}
+
+QImage Picture::image()
+{
+	// Do the conversion if only needed.
+	// If the image is null, the path is not empty then.
+	if( d->updateImage )
+	{
+		d->pictureImage = QImage(d->picturePath);
+
+		d->updateImage = false;
+	}
+
+	return d->pictureImage;
+}
+
+QString Picture::base64()
+{
+	if( d->updateBase64 )
+	{
+		// Generate base64 cache for the picture.
+		QByteArray tempArray;
+		QBuffer tempBuffer( tempArray );
+		tempBuffer.open( IO_WriteOnly );
+		// Make sure it create a image cache.
+		image().save( &tempBuffer, "PNG" );
+		d->pictureBase64 = KCodecs::base64Encode(tempArray);
+
+		d->updateBase64 = false;
+	}
+
+	return d->pictureBase64;
+}
+
+QString Picture::path()
+{
+	if( d->updatePath )
+	{
+		// For a image source, finding a filename is tricky.
+		// I decided to use MD5 Hash as the filename.
+		QString localPhotoPath;
+		
+		// Generate MD5 Hash for the image.
+		QByteArray tempArray;
+		QBuffer tempBuffer(tempArray);
+		tempBuffer.open( IO_WriteOnly );
+		image().save(&tempBuffer, "PNG");
+		KMD5 context(tempArray);
+		// Save the image to a file.
+		localPhotoPath = context.hexDigest() + ".png";
+		localPhotoPath = locateLocal( "appdata", \
QString::fromUtf8("metacontactpicturecache/%1").arg( localPhotoPath) ); \
+		image().save(localPhotoPath, "PNG"); +		d->picturePath = localPhotoPath;
+
+		d->updatePath = false;
+	}
+
+	return d->picturePath;
+}
+
+bool Picture::isNull()
+{
+	if( d->pictureBase64.isEmpty() && d->picturePath.isEmpty() && \
d->pictureImage.isNull() ) +	{
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
+void Picture::clear()
+{
+	detach();
+	d->pictureBase64 = QString::null;
+	d->picturePath = QString::null;
+	d->pictureImage = QImage();
+}
+
+void Picture::setPicture(const QImage &image)
+{
+	detach();
+	d->pictureImage = image;
+	
+	// Set which part need to be updated when called
+	d->updateImage = false;
+	d->updatePath = true;
+	d->updateBase64 = true;
+}
+
+void Picture::setPicture(const QString &path)
+{
+	detach();
+	d->picturePath = path;
+	
+	// Set which part need to be updated when called
+	d->updateImage = true;
+	d->updatePath = false;
+	d->updateBase64 = true;
+}
+
+void Picture::setPicture(const KABC::Picture &picture)
+{
+	// No need to call detach() here because setPicture will do it.
+	if ( picture.isIntern())
+	{
+		setPicture( picture.data() );
+	}
+	else
+	{
+		setPicture( picture.url() );
+	}
+}
+
+void Picture::detach()
+{
+	// there is no detach in KSharedPtr.
+	if( d.count() == 1 )
+		return;
+
+	// Warning: this only works as long as the private object doesn't contain pointers \
to allocated objects. +	d = new Private(*d);
+}
+
+} // END namespace Kopete
Index: libkopete/kopetemetacontact.h
===================================================================
--- libkopete/kopetemetacontact.h	(révision 487239)
+++ libkopete/kopetemetacontact.h	(copie de travail)
@@ -41,6 +41,7 @@
 
 class Plugin;
 class Group;
+class Picture;
 
 /**
  * @author Will Stephenson <will@stevello.free-online.co.uk>
@@ -187,6 +188,15 @@
 	QImage photo() const;
 
 	/**
+	 * Return the correct Kopete::Picture object depending of the metacontact photo \
source. +	 *
+	 * This photo is obtained from the source set with @ref setPhotoSource
+	 *
+	 * KDE4 TODO: Rename this to photo() and use the new object.
+	 */
+	Picture &picture() const;
+
+	/**
 	 * @brief Set the custom displayName.
 	 *
 	 * This display name is used when name source is Custom
@@ -207,10 +217,10 @@
 	QString customDisplayName() const;
 
 	/**
-	 * @brief Returns the custom display name
+	 * @brief Returns the custom display photo
 	 *
-	 * @see displayName()
-	 * @see displayNameSource()
+	 * @see photo()
+	 * @see photoSource()
 	 */
 	KURL customPhoto() const;
 
@@ -571,6 +581,11 @@
 	 */
 	void slotAllPluginsLoaded();
 
+	/**
+	 * Update the KABC Picture when the addressbook is changed.
+	 */
+	void slotUpdateAddressBookPicture();
+
 protected:
 	//QImage photoFromContact( Kopete::Contact *c) const;
 	//QImage photoFromKABC( const QString &id ) const;
Index: libkopete/Makefile.am
===================================================================
--- libkopete/Makefile.am	(révision 487239)
+++ libkopete/Makefile.am	(copie de travail)
@@ -27,7 +27,7 @@
 	kopetemessageevent.cpp kopetemessagehandler.cpp kopetemessagehandlerchain.cpp \
 	kopetesimplemessagehandler.cpp kopeteproperties.cpp kabcpersistence.cpp \
connectionmanager.skel \  clientiface.stub managedconnectionaccount.cpp \
                networkstatuscommon.h kopeteconfig.kcfgc kopeteutils.cpp \
-	kopeteprefs.cpp
+	kopeteprefs.cpp kopetepicture.cpp
 
 libkopete_la_LDFLAGS = -no-undefined -version-info 1:0:0 $(all_libraries)
 libkopete_la_LIBADD = -lkabc ui/libkopeteui.la $(LIB_KIO) $(LIB_XSS) $(LIBXML_LIBS) \
$(LIBXSLT_LIBS) @@ -58,7 +58,7 @@
 	kopeteonlinestatus.h kopeteonlinestatusmanager.h kopetepasswordedaccount.h \
 	kopetepassword.h kopeteplugin.h kopeteprotocol.h kopetesimplemessagehandler.h \
kopetetask.h \  kopetetransfermanager.h kopeteuiglobal.h kopetexsl.h \
                kabcpersistence.h managedconnectionaccount.h \
-	kopetenotifydataobject.h kopeteversion.h kopeteprefs.h
+	kopetenotifydataobject.h kopeteversion.h kopeteprefs.h kopetepicture.h
 
 # vim: set noet:
 


[Attachment #8 (application/pgp-signature)]

_______________________________________________
kopete-devel mailing list
kopete-devel@kde.org
https://mail.kde.org/mailman/listinfo/kopete-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic