[cosmetics] update date in GPL header
[vuplus_xbmc] / xbmc / guilib / GUIListItem.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "GUIListItem.h"
22 #include "GUIListItemLayout.h"
23 #include "utils/Archive.h"
24 #include "utils/CharsetConverter.h"
25 #include "utils/Variant.h"
26
27 using namespace std;
28
29 CGUIListItem::CGUIListItem(const CGUIListItem& item)
30 {
31   m_layout = NULL;
32   m_focusedLayout = NULL;
33   *this = item;
34   SetInvalid();
35 }
36
37 CGUIListItem::CGUIListItem(void)
38 {
39   m_bIsFolder = false;
40   m_strLabel2 = "";
41   m_strLabel = "";
42   m_bSelected = false;
43   m_strIcon = "";
44   m_overlayIcon = ICON_OVERLAY_NONE;
45   m_layout = NULL;
46   m_focusedLayout = NULL;
47 }
48
49 CGUIListItem::CGUIListItem(const CStdString& strLabel)
50 {
51   m_bIsFolder = false;
52   m_strLabel2 = "";
53   m_strLabel = strLabel;
54   SetSortLabel(strLabel);
55   m_bSelected = false;
56   m_strIcon = "";
57   m_overlayIcon = ICON_OVERLAY_NONE;
58   m_layout = NULL;
59   m_focusedLayout = NULL;
60 }
61
62 CGUIListItem::~CGUIListItem(void)
63 {
64   FreeMemory();
65 }
66
67 void CGUIListItem::SetLabel(const CStdString& strLabel)
68 {
69   if (m_strLabel == strLabel)
70     return;
71   m_strLabel = strLabel;
72   if (m_sortLabel.IsEmpty())
73     SetSortLabel(strLabel);
74   SetInvalid();
75 }
76
77 const CStdString& CGUIListItem::GetLabel() const
78 {
79   return m_strLabel;
80 }
81
82
83 void CGUIListItem::SetLabel2(const CStdString& strLabel2)
84 {
85   if (m_strLabel2 == strLabel2)
86     return;
87   m_strLabel2 = strLabel2;
88   SetInvalid();
89 }
90
91 const CStdString& CGUIListItem::GetLabel2() const
92 {
93   return m_strLabel2;
94 }
95
96 void CGUIListItem::SetSortLabel(const CStdString &label)
97 {
98   g_charsetConverter.utf8ToW(label, m_sortLabel, false);
99   // no need to invalidate - this is never shown in the UI
100 }
101
102 void CGUIListItem::SetSortLabel(const CStdStringW &label)
103 {
104   m_sortLabel = label;
105 }
106
107 const CStdStringW& CGUIListItem::GetSortLabel() const
108 {
109   return m_sortLabel;
110 }
111
112 void CGUIListItem::SetArt(const std::string &type, const std::string &url)
113 {
114   ArtMap::iterator i = m_art.find(type);
115   if (i == m_art.end() || i->second != url)
116   {
117     m_art[type] = url;
118     SetInvalid();
119   }
120 }
121
122 void CGUIListItem::SetArt(const ArtMap &art)
123 {
124   m_art = art;
125   SetInvalid();
126 }
127
128 void CGUIListItem::SetArtFallback(const std::string &from, const std::string &to)
129 {
130   m_artFallbacks[from] = to;
131 }
132
133 void CGUIListItem::ClearArt()
134 {
135   m_art.clear();
136   m_artFallbacks.clear();
137 }
138
139 void CGUIListItem::AppendArt(const ArtMap &art, const std::string &prefix)
140 {
141   for (ArtMap::const_iterator i = art.begin(); i != art.end(); ++i)
142     SetArt(prefix.empty() ? i->first : prefix + '.' + i->first, i->second);
143 }
144
145 std::string CGUIListItem::GetArt(const std::string &type) const
146 {
147   ArtMap::const_iterator i = m_art.find(type);
148   if (i != m_art.end())
149     return i->second;
150   i = m_artFallbacks.find(type);
151   if (i != m_artFallbacks.end())
152   {
153     ArtMap::const_iterator j = m_art.find(i->second);
154     if (j != m_art.end())
155       return j->second;
156   }
157   return "";
158 }
159
160 const CGUIListItem::ArtMap &CGUIListItem::GetArt() const
161 {
162   return m_art;
163 }
164
165 bool CGUIListItem::HasArt(const std::string &type) const
166 {
167   return !GetArt(type).empty();
168 }
169
170 void CGUIListItem::SetIconImage(const CStdString& strIcon)
171 {
172   if (m_strIcon == strIcon)
173     return;
174   m_strIcon = strIcon;
175   SetInvalid();
176 }
177
178 const CStdString& CGUIListItem::GetIconImage() const
179 {
180   return m_strIcon;
181 }
182
183 void CGUIListItem::SetOverlayImage(GUIIconOverlay icon, bool bOnOff)
184 {
185   GUIIconOverlay newIcon = (bOnOff) ? GUIIconOverlay((int)(icon)+1) : icon;
186   if (m_overlayIcon == newIcon)
187     return;
188   m_overlayIcon = newIcon;
189   SetInvalid();
190 }
191
192 CStdString CGUIListItem::GetOverlayImage() const
193 {
194   switch (m_overlayIcon)
195   {
196   case ICON_OVERLAY_RAR:
197     return "OverlayRAR.png";
198   case ICON_OVERLAY_ZIP:
199     return "OverlayZIP.png";
200   case ICON_OVERLAY_TRAINED:
201     return "OverlayTrained.png";
202   case ICON_OVERLAY_HAS_TRAINER:
203     return "OverlayHasTrainer.png";
204   case ICON_OVERLAY_LOCKED:
205     return "OverlayLocked.png";
206   case ICON_OVERLAY_UNWATCHED:
207     return "OverlayUnwatched.png";
208   case ICON_OVERLAY_WATCHED:
209     return "OverlayWatched.png";
210   case ICON_OVERLAY_HD:
211     return "OverlayHD.png";
212   default:
213     return "";
214   }
215 }
216
217 void CGUIListItem::Select(bool bOnOff)
218 {
219   m_bSelected = bOnOff;
220 }
221
222 bool CGUIListItem::HasIcon() const
223 {
224   return (m_strIcon.size() != 0);
225 }
226
227 bool CGUIListItem::HasOverlay() const
228 {
229   return (m_overlayIcon != CGUIListItem::ICON_OVERLAY_NONE);
230 }
231
232 bool CGUIListItem::IsSelected() const
233 {
234   return m_bSelected;
235 }
236
237 const CGUIListItem& CGUIListItem::operator =(const CGUIListItem& item)
238 {
239   if (&item == this) return * this;
240   m_strLabel2 = item.m_strLabel2;
241   m_strLabel = item.m_strLabel;
242   m_sortLabel = item.m_sortLabel;
243   FreeMemory();
244   m_bSelected = item.m_bSelected;
245   m_strIcon = item.m_strIcon;
246   m_overlayIcon = item.m_overlayIcon;
247   m_bIsFolder = item.m_bIsFolder;
248   m_mapProperties = item.m_mapProperties;
249   m_art = item.m_art;
250   m_artFallbacks = item.m_artFallbacks;
251   SetInvalid();
252   return *this;
253 }
254
255 void CGUIListItem::Archive(CArchive &ar)
256 {
257   if (ar.IsStoring())
258   {
259     ar << m_bIsFolder;
260     ar << m_strLabel;
261     ar << m_strLabel2;
262     ar << m_sortLabel;
263     ar << m_strIcon;
264     ar << m_bSelected;
265     ar << m_overlayIcon;
266     ar << (int)m_mapProperties.size();
267     for (PropertyMap::const_iterator it = m_mapProperties.begin(); it != m_mapProperties.end(); it++)
268     {
269       ar << it->first;
270       ar << it->second;
271     }
272     ar << (int)m_art.size();
273     for (ArtMap::const_iterator i = m_art.begin(); i != m_art.end(); i++)
274     {
275       ar << i->first;
276       ar << i->second;
277     }
278     ar << (int)m_artFallbacks.size();
279     for (ArtMap::const_iterator i = m_artFallbacks.begin(); i != m_artFallbacks.end(); i++)
280     {
281       ar << i->first;
282       ar << i->second;
283     }
284   }
285   else
286   {
287     ar >> m_bIsFolder;
288     ar >> m_strLabel;
289     ar >> m_strLabel2;
290     ar >> m_sortLabel;
291     ar >> m_strIcon;
292     ar >> m_bSelected;
293
294     int overlayIcon;
295     ar >> overlayIcon;
296     m_overlayIcon = GUIIconOverlay(overlayIcon);
297
298     int mapSize;
299     ar >> mapSize;
300     for (int i = 0; i < mapSize; i++)
301     {
302       std::string key;
303       CVariant value;
304       ar >> key;
305       ar >> value;
306       SetProperty(key, value);
307     }
308     ar >> mapSize;
309     for (int i = 0; i < mapSize; i++)
310     {
311       std::string key, value;
312       ar >> key;
313       ar >> value;
314       m_art.insert(make_pair(key, value));
315     }
316     ar >> mapSize;
317     for (int i = 0; i < mapSize; i++)
318     {
319       std::string key, value;
320       ar >> key;
321       ar >> value;
322       m_artFallbacks.insert(make_pair(key, value));
323     }
324   }
325 }
326 void CGUIListItem::Serialize(CVariant &value)
327 {
328   value["isFolder"] = m_bIsFolder;
329   value["strLabel"] = m_strLabel;
330   value["strLabel2"] = m_strLabel2;
331   value["sortLabel"] = m_sortLabel;
332   value["strIcon"] = m_strIcon;
333   value["selected"] = m_bSelected;
334
335   for (PropertyMap::const_iterator it = m_mapProperties.begin(); it != m_mapProperties.end(); it++)
336   {
337     value["properties"][it->first] = it->second;
338   }
339   for (ArtMap::const_iterator it = m_art.begin(); it != m_art.end(); it++)
340     value["art"][it->first] = it->second;
341 }
342
343 void CGUIListItem::FreeIcons()
344 {
345   FreeMemory();
346   ClearArt();
347   m_strIcon = "";
348   SetInvalid();
349 }
350
351 void CGUIListItem::FreeMemory(bool immediately)
352 {
353   if (m_layout)
354   {
355     m_layout->FreeResources(immediately);
356     delete m_layout;
357     m_layout = NULL;
358   }
359   if (m_focusedLayout)
360   {
361     m_focusedLayout->FreeResources(immediately);
362     delete m_focusedLayout;
363     m_focusedLayout = NULL;
364   }
365 }
366
367 void CGUIListItem::SetLayout(CGUIListItemLayout *layout)
368 {
369   delete m_layout;
370   m_layout = layout;
371 }
372
373 CGUIListItemLayout *CGUIListItem::GetLayout()
374 {
375   return m_layout;
376 }
377
378 void CGUIListItem::SetFocusedLayout(CGUIListItemLayout *layout)
379 {
380   delete m_focusedLayout;
381   m_focusedLayout = layout;
382 }
383
384 CGUIListItemLayout *CGUIListItem::GetFocusedLayout()
385 {
386   return m_focusedLayout;
387 }
388
389 void CGUIListItem::SetInvalid()
390 {
391   if (m_layout) m_layout->SetInvalid();
392   if (m_focusedLayout) m_focusedLayout->SetInvalid();
393 }
394
395 void CGUIListItem::SetProperty(const CStdString &strKey, const CVariant &value)
396 {
397   m_mapProperties[strKey] = value;
398 }
399
400 CVariant CGUIListItem::GetProperty(const CStdString &strKey) const
401 {
402   PropertyMap::const_iterator iter = m_mapProperties.find(strKey);
403   if (iter == m_mapProperties.end())
404     return CVariant(CVariant::VariantTypeNull);
405
406   return iter->second;
407 }
408
409 bool CGUIListItem::HasProperty(const CStdString &strKey) const
410 {
411   PropertyMap::const_iterator iter = m_mapProperties.find(strKey);
412   if (iter == m_mapProperties.end())
413     return false;
414
415   return true;
416 }
417
418 void CGUIListItem::ClearProperty(const CStdString &strKey)
419 {
420   PropertyMap::iterator iter = m_mapProperties.find(strKey);
421   if (iter != m_mapProperties.end())
422     m_mapProperties.erase(iter);
423 }
424
425 void CGUIListItem::ClearProperties()
426 {
427   m_mapProperties.clear();
428 }
429
430 void CGUIListItem::IncrementProperty(const CStdString &strKey, int nVal)
431 {
432   int64_t i = GetProperty(strKey).asInteger();
433   i += nVal;
434   SetProperty(strKey, i);
435 }
436
437 void CGUIListItem::IncrementProperty(const CStdString &strKey, double dVal)
438 {
439   double d = GetProperty(strKey).asDouble();
440   d += dVal;
441   SetProperty(strKey, d);
442 }
443
444 void CGUIListItem::AppendProperties(const CGUIListItem &item)
445 {
446   for (PropertyMap::const_iterator i = item.m_mapProperties.begin(); i != item.m_mapProperties.end(); ++i)
447     SetProperty(i->first, i->second);
448 }