Initial commit
[tietoopcom] / src / TocUi / IconProvider.cpp
1 /** \file IconProvider.cpp\r
2  * \brief Implementation of IconProvider class\r
3  * \r
4  * Tieto Open Communicator - Client for the Telepathy communications framework.\r
5  * Copyright (c) 2010, Tieto Corporation\r
6  *\r
7  * All rights reserved.\r
8  * Redistribution and use in source and binary forms, with or without modification,\r
9  * are permitted provided that the following conditions are met:\r
10  *\r
11  *      Redistributions of source code must retain the above copyright notice,\r
12  *      this list of conditions and the following disclaimer.\r
13  *      Redistributions in binary form must reproduce the above copyright notice,\r
14  *      this list of conditions and the following disclaimer in the documentation\r
15  *      and/or other materials provided with the distribution.\r
16  *      Neither the name of the Tieto Corporation nor the names of its contributors \r
17  *      may be used to endorse or promote products derived from this software without\r
18  *      specific prior written permission.\r
19  *\r
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
23  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
27  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
28  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
29  * \r
30  */\r
31  \r
32 #include <QPainter>\r
33 #include <QIcon>\r
34 #include <QDebug>\r
35 \r
36 #include "IconProvider"\r
37 #include "TocSettings"\r
38 \r
39 \r
40 // Initialize static object\r
41 IconProvider* IconProvider::mp_self = 0;\r
42 \r
43 // ---------------------------------------------------------------------------\r
44 // getInstance\r
45 // ---------------------------------------------------------------------------\r
46 //\r
47 IconProvider* IconProvider::getInstance() \r
48 {\r
49         if ( !mp_self)\r
50                 mp_self = new IconProvider();\r
51 \r
52         return mp_self;\r
53 }\r
54 \r
55 // ---------------------------------------------------------------------------\r
56 // Constructor\r
57 // ---------------------------------------------------------------------------\r
58 //\r
59 IconProvider::IconProvider():\r
60         _customIconId(1),\r
61         _defaultMaleImagePath(":/contactmale.png"),\r
62         _defaultFemaleImagePath(":/contactfemale.png"),\r
63         _defaultUnknownImagePath(":/unknown.png")\r
64 {\r
65         //Initialize _defaultIcons map according to gender and status\r
66         \r
67         //Male\r
68         QImage* pNoFrame = new QImage(_defaultMaleImagePath);\r
69         QImage* pRed    = addStatusFrame(pNoFrame, Busy);\r
70         QImage* pYellow = addStatusFrame(pNoFrame, Away);\r
71         QImage* pGreen  = addStatusFrame(pNoFrame, Available);\r
72         \r
73         _defaultIcons[Male << 8 | Hidden]       = pNoFrame;\r
74         _defaultIcons[Male << 8 | Offline]      = pNoFrame;\r
75         _defaultIcons[Male << 8 | Available]= pGreen;\r
76         _defaultIcons[Male << 8 | Busy]         = pRed;\r
77         _defaultIcons[Male << 8 | XA]           = pYellow;\r
78         _defaultIcons[Male << 8 | Away]         = pYellow;\r
79 \r
80         //Female\r
81         pNoFrame = new QImage(_defaultFemaleImagePath);\r
82         pRed    = addStatusFrame(pNoFrame, Busy);\r
83         pYellow = addStatusFrame(pNoFrame, Away);\r
84         pGreen  = addStatusFrame(pNoFrame, Available);\r
85         \r
86         _defaultIcons[Female << 8 | Hidden]     = pNoFrame;\r
87         _defaultIcons[Female << 8 | Offline]    = pNoFrame;\r
88         _defaultIcons[Female << 8 | Available]  = pGreen;\r
89         _defaultIcons[Female << 8 | Busy]               = pRed;\r
90         _defaultIcons[Female << 8 | XA]                 = pYellow;\r
91         _defaultIcons[Female << 8 | Away]               = pYellow;\r
92 \r
93         //NotSpecified\r
94         pNoFrame = new QImage(_defaultUnknownImagePath);\r
95         pRed    = addStatusFrame(pNoFrame, Busy);\r
96         pYellow = addStatusFrame(pNoFrame, Away);\r
97         pGreen  = addStatusFrame(pNoFrame, Available);\r
98         \r
99         _defaultIcons[NotSpecified << 8 | Hidden]       = pNoFrame;\r
100         _defaultIcons[NotSpecified << 8 | Offline]      = pNoFrame;\r
101         _defaultIcons[NotSpecified << 8 | Available]= pGreen;\r
102         _defaultIcons[NotSpecified << 8 | Busy]         = pRed;\r
103         _defaultIcons[NotSpecified << 8 | XA]           = pYellow;\r
104         _defaultIcons[NotSpecified << 8 | Away]         = pYellow;\r
105                 \r
106 \r
107         //Initialize _customIcons map from TocSettings\r
108         TocSettings *pSettings = TocSettings::getInstance();\r
109         \r
110         TocContactList *pContacts = pSettings->contactList();\r
111         \r
112         foreach(TocContact* pContact, *pContacts)\r
113         {\r
114                 if(!pContact->customIconPath.isEmpty())\r
115                         setCustomIcon(pContact);\r
116         }\r
117 }\r
118 \r
119 // ---------------------------------------------------------------------------\r
120 // Destructor\r
121 // ---------------------------------------------------------------------------\r
122 //\r
123 IconProvider::~IconProvider()\r
124 {\r
125         QList<int> defaultIconsKeys = _defaultIcons.uniqueKeys();\r
126         \r
127         foreach(int key, defaultIconsKeys)\r
128         {\r
129                 QImage* pImage = _defaultIcons.value(key);\r
130                 if(pImage)\r
131                 {\r
132                         delete pImage;\r
133                 }\r
134         }\r
135         \r
136         \r
137         QList<int> customIconsKeys = _defaultIcons.uniqueKeys();\r
138         \r
139         foreach(int key, customIconsKeys)\r
140         {\r
141                 QImage* pImage = _customIcons.value(key);\r
142                 if(pImage)\r
143                 {\r
144                         delete pImage;\r
145                 }\r
146         }       \r
147 }\r
148 \r
149 // ---------------------------------------------------------------------------\r
150 // matchIcon\r
151 // ---------------------------------------------------------------------------\r
152 //\r
153 QImage* IconProvider::matchIcon(const TocContact* pContact) const\r
154 {\r
155         if(pContact->customIconId)\r
156                 return _customIcons.value(pContact->customIconId << 8 | pContact->presence);\r
157         else\r
158                 return _defaultIcons.value(pContact->gender << 8 | pContact->presence);\r
159 }\r
160 \r
161 // ---------------------------------------------------------------------------\r
162 // matchIcon\r
163 // ---------------------------------------------------------------------------\r
164 //\r
165 QIcon IconProvider::matchIcon(Gender gender) const\r
166 {\r
167         switch( static_cast<int>(gender) ) \r
168         {\r
169 \r
170                 case NotSpecified:\r
171                         return QIcon(_defaultUnknownImagePath);\r
172 \r
173                 case Male:\r
174                         return QIcon(_defaultMaleImagePath);            \r
175 \r
176                 case Female:\r
177                         return QIcon(_defaultFemaleImagePath);          \r
178 \r
179                 default:\r
180                         return QIcon(_defaultUnknownImagePath);\r
181         }\r
182 }\r
183 \r
184 // ---------------------------------------------------------------------------\r
185 // setCustomIcon\r
186 // ---------------------------------------------------------------------------\r
187 //\r
188 void IconProvider::setCustomIcon(TocContact* pContact)\r
189 {\r
190         //Check if there's something to be set\r
191         if(pContact->customIconPath.isEmpty())\r
192         \r
193         //Check if this pContact has some custom icon already associated \r
194         if(_customIcons[pContact->customIconId])\r
195         {\r
196                 //if yes, remove it from the list\r
197                 _customIcons.remove(pContact->customIconId << 8 | Hidden);\r
198                 _customIcons.remove(pContact->customIconId << 8 | Offline);\r
199                 _customIcons.remove(pContact->customIconId << 8 | Available);\r
200                 _customIcons.remove(pContact->customIconId << 8 | Busy);\r
201                 _customIcons.remove(pContact->customIconId << 8 | XA);\r
202                 _customIcons.remove(pContact->customIconId << 8 | Away);\r
203         }\r
204         \r
205         QImage* pNoFrame = new QImage(pContact->customIconPath);\r
206         QImage* pRed    = addStatusFrame(pNoFrame, Busy);\r
207         QImage* pYellow = addStatusFrame(pNoFrame, Away);\r
208         QImage* pGreen  = addStatusFrame(pNoFrame, Available);\r
209                 \r
210         _customIcons[_customIconId << 8 | Hidden]               = pNoFrame;\r
211         _customIcons[_customIconId << 8 | Offline]              = pNoFrame;\r
212         _customIcons[_customIconId << 8 | Available]    = pGreen;\r
213         _customIcons[_customIconId << 8 | Busy]                 = pRed;\r
214         _customIcons[_customIconId << 8 | XA]                   = pYellow;\r
215         _customIcons[_customIconId << 8 | Away]                 = pYellow;\r
216         \r
217         pContact->customIconId = _customIconId++;\r
218 }\r
219 \r
220 // ---------------------------------------------------------------------------\r
221 // addStatusFrame\r
222 // ---------------------------------------------------------------------------\r
223 //\r
224 QImage* IconProvider::addStatusFrame(const QImage *baseImage, Presence presence) const\r
225 {\r
226         QImage contactImage(*baseImage);\r
227         QImage *pResultImage = new QImage(QSize::QSize(72,72), QImage::Format_ARGB32_Premultiplied);\r
228                 \r
229         QImage presenceFrame;\r
230     \r
231         switch(presence)\r
232         {\r
233                 case Hidden:\r
234                 case Offline:\r
235                         break;\r
236                         \r
237                 case Available:\r
238                         presenceFrame = QImage(":greenframe.png");\r
239                         break;\r
240                         \r
241                 case Busy:\r
242                         presenceFrame = QImage(":redframe.png");\r
243                         break;\r
244                         \r
245                 case XA:\r
246                 case Away:\r
247                         presenceFrame = QImage(":yellowframe.png");\r
248         }\r
249         \r
250         QPainter painter(pResultImage);\r
251         \r
252         painter.setCompositionMode(QPainter::CompositionMode_Source);\r
253     painter.fillRect(pResultImage->rect(), Qt::transparent);\r
254     \r
255     painter.setCompositionMode(QPainter::CompositionMode_SourceOver);\r
256     painter.drawImage(0, 0, contactImage);\r
257 \r
258     painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);\r
259     painter.drawImage(0, 0, presenceFrame);\r
260     painter.end();\r
261     \r
262     return pResultImage;\r
263 }\r