Advertisement
Guest User

Untitled

a guest
Feb 21st, 2012
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.09 KB | None | 0 0
  1. // Local includes
  2. #include "avatarimage.h"
  3.  
  4. // Global includes
  5. #include <QPainter>
  6. #include <QPixmapCache>
  7. #include <QContactManager>
  8. #include <QContact>
  9. #include <QContactFetchRequest>
  10. #include <QContactLocalIdFilter>
  11. #include <QContactThumbnail>
  12. #include <QContactAvatar>
  13. #include <QContactName>
  14. #include <QContactDisplayLabel>
  15. #include <QTimer>
  16. #include <QSet>
  17. #include <QDebug>
  18.  
  19. QTM_USE_NAMESPACE
  20.  
  21. class AvatarImageShared : public QObject
  22. {
  23. Q_OBJECT
  24.  
  25. public:
  26. AvatarImageShared()
  27. : defaultPixmap("/usr/share/themes/blanco/meegotouch/icons/icon-m-content-avatar-placeholder.png")
  28. , defaultPixmapInverted("/usr/share/themes/blanco/meegotouch/icons/icon-m-content-avatar-placeholder-dialog.png")
  29. , maskPixmap("/usr/share/themes/blanco/meegotouch/images/theme/basement/meegotouch-avatar/meegotouch-avatar-placeholder-background.png")
  30. , manager("tracker")
  31. {
  32. fetchTimer.setSingleShot(true);
  33. fetchTimer.setInterval(20);
  34. }
  35.  
  36. QPixmap defaultPixmap;
  37. QPixmap defaultPixmapInverted;
  38. QPixmap maskPixmap;
  39.  
  40. /// Get the image from a contactId
  41. QPixmap image(quint32 contactId);
  42.  
  43. signals:
  44. void avatarsLoaded();
  45.  
  46. private slots:
  47. void startLoading();
  48. void contactsFetched();
  49.  
  50. protected:
  51. QString cacheKey(quint32 contactId) const;
  52. void queueContact(quint32 contactId);
  53. QPixmap loadImage(const QContact& contact);
  54.  
  55. protected:
  56. QContactManager manager;
  57. QTimer fetchTimer;
  58. QSet<quint32> ids;
  59. };
  60.  
  61. Q_GLOBAL_STATIC(AvatarImageShared, avatarShared)
  62.  
  63. void AvatarImageShared::startLoading()
  64. {
  65. qDebug() << Q_FUNC_INFO << ids.size();
  66.  
  67. // Setup the id filter
  68. QContactLocalIdFilter idFilter;
  69. idFilter.setIds( ids.toList() );
  70.  
  71. // Create a fetch request
  72. QContactFetchRequest* request = new QContactFetchRequest;
  73. connect(request, SIGNAL(resultsAvailable()), this, SLOT(contactsFetched()));
  74. request->setFilter(idFilter);
  75. request->setManager(&manager);
  76. request->start();
  77. }
  78.  
  79. void AvatarImageShared::contactsFetched()
  80. {
  81. qDebug() << Q_FUNC_INFO;
  82.  
  83. // Get the sending request
  84. QContactFetchRequest* request = qobject_cast<QContactFetchRequest*>( sender() );
  85.  
  86. // Create a image for each contact
  87. foreach(const QContact& contact, request->contacts()) {
  88. // Get the contactId
  89. quint32 contactId = contact.localId();
  90.  
  91. // Create the image
  92. QPixmap pixmap = loadImage(contact);
  93.  
  94. ids.remove(contactId);
  95.  
  96. // Add it to the cache
  97. QPixmapCache::insert(cacheKey(contactId), pixmap);
  98. }
  99.  
  100. // Free the memory
  101. request->deleteLater();
  102.  
  103. emit avatarsLoaded();
  104. }
  105.  
  106. QString AvatarImageShared::cacheKey(quint32 contactId) const
  107. {
  108. return QString("avatarimage_%1").arg(contactId);
  109. }
  110.  
  111. void AvatarImageShared::queueContact(quint32 contactId)
  112. {
  113. // Do not add twice
  114. if ( ids.contains(contactId) )
  115. return;
  116.  
  117. // Add the contactId to our queue
  118. ids.insert(contactId);
  119.  
  120. // Prepare the timer
  121. fetchTimer.start();
  122. }
  123.  
  124. QPixmap AvatarImageShared::image(quint32 contactId)
  125. {
  126. QPixmap pixmap;
  127.  
  128. // Search the pixmap in the cache
  129. if (QPixmapCache::find(cacheKey(contactId), &pixmap))
  130. return pixmap;
  131. else {
  132. // Queue the contact
  133. queueContact(contactId);
  134. return QPixmap();
  135. }
  136. }
  137.  
  138. QPixmap AvatarImageShared::loadImage(const QContact &contact)
  139. {
  140. // First try to find the thumbnail image
  141. QContactThumbnail thumbnail = contact.detail<QContactThumbnail>();
  142. QPixmap thumbnailImage = QPixmap::fromImage(thumbnail.thumbnail());
  143. if ( thumbnailImage.isNull() == false )
  144. //maskImage(image, thumbnailImage);
  145. return thumbnailImage;
  146. else {
  147. // Get the avatar image if we don't have a thumbnail
  148. QContactAvatar avatar = contact.detail<QContactAvatar>();
  149. QString path = avatar.imageUrl().toLocalFile();
  150.  
  151. if ( path.isEmpty() == false ) {
  152. //QImage tmp(path);
  153. //maskImage(image, tmp.scaled(image.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
  154. return QPixmap(path);
  155. }
  156. else {
  157. // Get the contact name
  158. QContactName name = contact.detail<QContactName>();
  159.  
  160. QString initials;
  161. QString firstName = name.firstName();
  162. QString lastName = name.lastName();
  163.  
  164. if ( firstName.isEmpty() && lastName.isEmpty() )
  165. return avatarShared()->defaultPixmap;
  166. else {
  167. // Construct the initials
  168. if ( firstName.isEmpty() )
  169. initials = lastName.left(1);
  170. else if ( lastName.isEmpty() )
  171. initials = firstName.left(1);
  172. else
  173. initials = firstName.left(1) + lastName.left(1);
  174.  
  175. // Load the default image
  176. //image.load("/usr/share/themes/blanco/meegotouch/images/theme/basement/meegotouch-avatar/meegotouch-avatar-placeholder-background.png");
  177. QPixmap pm = avatarShared()->maskPixmap;
  178.  
  179. QPainter painter(&pm);
  180.  
  181. QFont font("Nokia Pure", 24, QFont::Bold);
  182. painter.setFont(font);
  183. painter.setPen(Qt::white);
  184.  
  185. QRect rect(QPoint(), pm.size());
  186. painter.drawText(rect, Qt::AlignCenter, initials);
  187.  
  188. return pm;
  189. }
  190. }
  191. }
  192.  
  193. return QPixmap();
  194. }
  195.  
  196. class AvatarImagePrivate : public QObject
  197. {
  198. Q_OBJECT
  199.  
  200. public:
  201. AvatarImagePrivate()
  202. : contactId(-1)
  203. {
  204. // Connect to the shared avatar loader
  205. connect(avatarShared(), SIGNAL(avatarsLoaded()), this, SLOT(updatePixmap()));
  206. }
  207.  
  208. // Properties
  209. int contactId;
  210. QPixmap pixmap;
  211.  
  212. // Functions
  213. public slots:
  214. void updatePixmap();
  215. };
  216.  
  217. void AvatarImagePrivate::updatePixmap()
  218. {
  219. QPixmap pixmap;
  220.  
  221. // Load the image or get one from cache
  222. if ( contactId > 0 )
  223. pixmap = avatarShared()->image(contactId);
  224.  
  225. // Load the default pixmap
  226. if ( pixmap.isNull() )
  227. pixmap = avatarShared()->defaultPixmap;
  228.  
  229. // Assign the new pixmap
  230. this->pixmap = pixmap;
  231. }
  232.  
  233. AvatarImage::AvatarImage(QDeclarativeItem *parent)
  234. : QDeclarativeItem(parent)
  235. , d(new AvatarImagePrivate)
  236. {
  237. // We want to paint this item
  238. setFlag(ItemHasNoContents, false);
  239. }
  240.  
  241. AvatarImage::~AvatarImage()
  242. {
  243. delete d;
  244. }
  245.  
  246. void AvatarImage::setContactId(int contactId)
  247. {
  248. if ( d->contactId == contactId )
  249. return;
  250.  
  251. d->contactId = contactId;
  252. emit contactIdChanged();
  253.  
  254. d->updatePixmap();
  255. }
  256.  
  257. int AvatarImage::contactId() const
  258. {
  259. return d->contactId;
  260. }
  261.  
  262. void AvatarImage::componentComplete()
  263. {
  264. // Base class may do something more
  265. QDeclarativeItem::componentComplete();
  266. }
  267.  
  268. void AvatarImage::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
  269. {
  270. Q_UNUSED(option);
  271. Q_UNUSED(widget);
  272.  
  273. // Simply draw the pixmap
  274. painter->drawPixmap(0, 0, d->pixmap);
  275. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement