[info] Add selective caching of infobools in list items
[vuplus_xbmc] / xbmc / GUIInfoManager.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://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 "network/Network.h"
22 #include "system.h"
23 #include "GitRevision.h"
24 #include "GUIInfoManager.h"
25 #include "windows/GUIMediaWindow.h"
26 #include "dialogs/GUIDialogProgress.h"
27 #include "Application.h"
28 #include "Util.h"
29 #include "utils/URIUtils.h"
30 #include "utils/Weather.h"
31 #include "PartyModeManager.h"
32 #include "addons/Visualisation.h"
33 #include "input/ButtonTranslator.h"
34 #include "utils/AlarmClock.h"
35 #include "LangInfo.h"
36 #include "utils/SystemInfo.h"
37 #include "guilib/GUITextBox.h"
38 #include "pictures/GUIWindowSlideShow.h"
39 #include "pictures/PictureInfoTag.h"
40 #include "music/tags/MusicInfoTag.h"
41 #include "guilib/IGUIContainer.h"
42 #include "guilib/GUIWindowManager.h"
43 #include "playlists/PlayList.h"
44 #include "profiles/ProfilesManager.h"
45 #include "utils/TuxBoxUtil.h"
46 #include "windowing/WindowingFactory.h"
47 #include "powermanagement/PowerManager.h"
48 #include "settings/AdvancedSettings.h"
49 #include "settings/DisplaySettings.h"
50 #include "settings/MediaSettings.h"
51 #include "settings/Settings.h"
52 #include "settings/SkinSettings.h"
53 #include "guilib/LocalizeStrings.h"
54 #include "guilib/StereoscopicsManager.h"
55 #include "utils/CharsetConverter.h"
56 #include "utils/CPUInfo.h"
57 #include "utils/StringUtils.h"
58 #include "utils/MathUtils.h"
59 #include "utils/SeekHandler.h"
60 #include "URL.h"
61 #include "addons/Skin.h"
62 #include "boost/make_shared.hpp"
63
64 // stuff for current song
65 #include "music/MusicInfoLoader.h"
66
67 #include "GUIUserMessages.h"
68 #include "video/dialogs/GUIDialogVideoInfo.h"
69 #include "music/dialogs/GUIDialogMusicInfo.h"
70 #include "storage/MediaManager.h"
71 #include "utils/TimeUtils.h"
72 #include "threads/SingleLock.h"
73 #include "utils/log.h"
74
75 #include "pvr/PVRManager.h"
76 #include "pvr/channels/PVRChannelGroupsContainer.h"
77 #include "epg/EpgInfoTag.h"
78 #include "pvr/timers/PVRTimers.h"
79 #include "pvr/recordings/PVRRecording.h"
80
81 #include "addons/AddonManager.h"
82 #include "interfaces/info/InfoBool.h"
83 #include "video/VideoThumbLoader.h"
84 #include "music/MusicThumbLoader.h"
85 #include "video/VideoDatabase.h"
86 #include "cores/IPlayer.h"
87 #include "cores/AudioEngine/Utils/AEUtil.h"
88 #include "cores/VideoRenderers/BaseRenderer.h"
89 #include "interfaces/info/InfoExpression.h"
90
91 #if defined(TARGET_DARWIN_OSX)
92 #include "osx/smc.h"
93 #include "linux/LinuxResourceCounter.h"
94 static CLinuxResourceCounter m_resourceCounter;
95 #endif
96
97 #define SYSHEATUPDATEINTERVAL 60000
98
99 using namespace std;
100 using namespace XFILE;
101 using namespace MUSIC_INFO;
102 using namespace ADDON;
103 using namespace PVR;
104 using namespace INFO;
105 using namespace EPG;
106
107 CGUIInfoManager::CGUIInfoManager(void) :
108     Observable()
109 {
110   m_lastSysHeatInfoTime = -SYSHEATUPDATEINTERVAL;  // make sure we grab CPU temp on the first pass
111   m_fanSpeed = 0;
112   m_AfterSeekTimeout = 0;
113   m_seekOffset = 0;
114   m_playerSeeking = false;
115   m_performingSeek = false;
116   m_nextWindowID = WINDOW_INVALID;
117   m_prevWindowID = WINDOW_INVALID;
118   m_stringParameters.push_back("__ZZZZ__");   // to offset the string parameters by 1 to assure that all entries are non-zero
119   m_currentFile = new CFileItem;
120   m_currentSlide = new CFileItem;
121   m_frameCounter = 0;
122   m_lastFPSTime = 0;
123   m_updateTime = 1;
124   m_playerShowTime = false;
125   m_playerShowCodec = false;
126   m_playerShowInfo = false;
127   m_fps = 0.0f;
128   m_AVInfoValid = false;
129   ResetLibraryBools();
130 }
131
132 CGUIInfoManager::~CGUIInfoManager(void)
133 {
134   delete m_currentFile;
135   delete m_currentSlide;
136 }
137
138 bool CGUIInfoManager::OnMessage(CGUIMessage &message)
139 {
140   if (message.GetMessage() == GUI_MSG_NOTIFY_ALL)
141   {
142     if (message.GetParam1() == GUI_MSG_UPDATE_ITEM && message.GetItem())
143     {
144       CFileItemPtr item = boost::static_pointer_cast<CFileItem>(message.GetItem());
145       if (m_currentFile->IsSamePath(item.get()))
146       {
147         m_currentFile->UpdateInfo(*item);
148         return true;
149       }
150     }
151   }
152   return false;
153 }
154
155 /// \brief Translates a string as given by the skin into an int that we use for more
156 /// efficient retrieval of data. Can handle combined strings on the form
157 /// Player.Caching + VideoPlayer.IsFullscreen (Logical and)
158 /// Player.HasVideo | Player.HasAudio (Logical or)
159 int CGUIInfoManager::TranslateString(const CStdString &condition)
160 {
161   // translate $LOCALIZE as required
162   CStdString strCondition(CGUIInfoLabel::ReplaceLocalize(condition));
163   return TranslateSingleString(strCondition);
164 }
165
166 typedef struct
167 {
168   const char *str;
169   int  val;
170 } infomap;
171
172 const infomap player_labels[] =  {{ "hasmedia",         PLAYER_HAS_MEDIA },           // bools from here
173                                   { "hasaudio",         PLAYER_HAS_AUDIO },
174                                   { "hasvideo",         PLAYER_HAS_VIDEO },
175                                   { "playing",          PLAYER_PLAYING },
176                                   { "paused",           PLAYER_PAUSED },
177                                   { "rewinding",        PLAYER_REWINDING },
178                                   { "forwarding",       PLAYER_FORWARDING },
179                                   { "rewinding2x",      PLAYER_REWINDING_2x },
180                                   { "rewinding4x",      PLAYER_REWINDING_4x },
181                                   { "rewinding8x",      PLAYER_REWINDING_8x },
182                                   { "rewinding16x",     PLAYER_REWINDING_16x },
183                                   { "rewinding32x",     PLAYER_REWINDING_32x },
184                                   { "forwarding2x",     PLAYER_FORWARDING_2x },
185                                   { "forwarding4x",     PLAYER_FORWARDING_4x },
186                                   { "forwarding8x",     PLAYER_FORWARDING_8x },
187                                   { "forwarding16x",    PLAYER_FORWARDING_16x },
188                                   { "forwarding32x",    PLAYER_FORWARDING_32x },
189                                   { "canrecord",        PLAYER_CAN_RECORD },
190                                   { "recording",        PLAYER_RECORDING },
191                                   { "displayafterseek", PLAYER_DISPLAY_AFTER_SEEK },
192                                   { "caching",          PLAYER_CACHING },
193                                   { "seekbar",          PLAYER_SEEKBAR },
194                                   { "seeking",          PLAYER_SEEKING },
195                                   { "showtime",         PLAYER_SHOWTIME },
196                                   { "showcodec",        PLAYER_SHOWCODEC },
197                                   { "showinfo",         PLAYER_SHOWINFO },
198                                   { "title",            PLAYER_TITLE },
199                                   { "muted",            PLAYER_MUTED },
200                                   { "hasduration",      PLAYER_HASDURATION },
201                                   { "passthrough",      PLAYER_PASSTHROUGH },
202                                   { "cachelevel",       PLAYER_CACHELEVEL },          // labels from here
203                                   { "progress",         PLAYER_PROGRESS },
204                                   { "progresscache",    PLAYER_PROGRESS_CACHE },
205                                   { "volume",           PLAYER_VOLUME },
206                                   { "subtitledelay",    PLAYER_SUBTITLE_DELAY },
207                                   { "audiodelay",       PLAYER_AUDIO_DELAY },
208                                   { "chapter",          PLAYER_CHAPTER },
209                                   { "chaptercount",     PLAYER_CHAPTERCOUNT },
210                                   { "chaptername",      PLAYER_CHAPTERNAME },
211                                   { "starrating",       PLAYER_STAR_RATING },
212                                   { "folderpath",       PLAYER_PATH },
213                                   { "filenameandpath",  PLAYER_FILEPATH },
214                                   { "filename",         PLAYER_FILENAME },
215                                   { "isinternetstream", PLAYER_ISINTERNETSTREAM },
216                                   { "pauseenabled",     PLAYER_CAN_PAUSE },
217                                   { "seekenabled",      PLAYER_CAN_SEEK }};
218
219 const infomap player_param[] =   {{ "art",              PLAYER_ITEM_ART }};
220
221 const infomap player_times[] =   {{ "seektime",         PLAYER_SEEKTIME },
222                                   { "seekoffset",       PLAYER_SEEKOFFSET },
223                                   { "timeremaining",    PLAYER_TIME_REMAINING },
224                                   { "timespeed",        PLAYER_TIME_SPEED },
225                                   { "time",             PLAYER_TIME },
226                                   { "duration",         PLAYER_DURATION },
227                                   { "finishtime",       PLAYER_FINISH_TIME },
228                                   { "starttime",        PLAYER_START_TIME}};
229
230 const infomap weather[] =        {{ "isfetched",        WEATHER_IS_FETCHED },
231                                   { "conditions",       WEATHER_CONDITIONS },         // labels from here
232                                   { "temperature",      WEATHER_TEMPERATURE },
233                                   { "location",         WEATHER_LOCATION },
234                                   { "fanartcode",       WEATHER_FANART_CODE },
235                                   { "plugin",           WEATHER_PLUGIN }};
236
237 const infomap system_labels[] =  {{ "hasnetwork",       SYSTEM_ETHERNET_LINK_ACTIVE },
238                                   { "hasmediadvd",      SYSTEM_MEDIA_DVD },
239                                   { "dvdready",         SYSTEM_DVDREADY },
240                                   { "trayopen",         SYSTEM_TRAYOPEN },
241                                   { "haslocks",         SYSTEM_HASLOCKS },
242                                   { "hasloginscreen",   SYSTEM_HAS_LOGINSCREEN },
243                                   { "ismaster",         SYSTEM_ISMASTER },
244                                   { "isfullscreen",     SYSTEM_ISFULLSCREEN },
245                                   { "isstandalone",     SYSTEM_ISSTANDALONE },
246                                   { "loggedon",         SYSTEM_LOGGEDON },
247                                   { "showexitbutton",   SYSTEM_SHOW_EXIT_BUTTON },
248                                   { "canpowerdown",     SYSTEM_CAN_POWERDOWN },
249                                   { "cansuspend",       SYSTEM_CAN_SUSPEND },
250                                   { "canhibernate",     SYSTEM_CAN_HIBERNATE },
251                                   { "canreboot",        SYSTEM_CAN_REBOOT },
252                                   { "screensaveractive",SYSTEM_SCREENSAVER_ACTIVE },
253                                   { "cputemperature",   SYSTEM_CPU_TEMPERATURE },     // labels from here
254                                   { "cpuusage",         SYSTEM_CPU_USAGE },
255                                   { "gputemperature",   SYSTEM_GPU_TEMPERATURE },
256                                   { "fanspeed",         SYSTEM_FAN_SPEED },
257                                   { "freespace",        SYSTEM_FREE_SPACE },
258                                   { "usedspace",        SYSTEM_USED_SPACE },
259                                   { "totalspace",       SYSTEM_TOTAL_SPACE },
260                                   { "usedspacepercent", SYSTEM_USED_SPACE_PERCENT },
261                                   { "freespacepercent", SYSTEM_FREE_SPACE_PERCENT },
262                                   { "buildversion",     SYSTEM_BUILD_VERSION },
263                                   { "builddate",        SYSTEM_BUILD_DATE },
264                                   { "fps",              SYSTEM_FPS },
265                                   { "dvdtraystate",     SYSTEM_DVD_TRAY_STATE },
266                                   { "freememory",       SYSTEM_FREE_MEMORY },
267                                   { "language",         SYSTEM_LANGUAGE },
268                                   { "temperatureunits", SYSTEM_TEMPERATURE_UNITS },
269                                   { "screenmode",       SYSTEM_SCREEN_MODE },
270                                   { "screenwidth",      SYSTEM_SCREEN_WIDTH },
271                                   { "screenheight",     SYSTEM_SCREEN_HEIGHT },
272                                   { "currentwindow",    SYSTEM_CURRENT_WINDOW },
273                                   { "currentcontrol",   SYSTEM_CURRENT_CONTROL },
274                                   { "dvdlabel",         SYSTEM_DVD_LABEL },
275                                   { "internetstate",    SYSTEM_INTERNET_STATE },
276                                   { "kernelversion",    SYSTEM_KERNEL_VERSION },
277                                   { "uptime",           SYSTEM_UPTIME },
278                                   { "totaluptime",      SYSTEM_TOTALUPTIME },
279                                   { "cpufrequency",     SYSTEM_CPUFREQUENCY },
280                                   { "screenresolution", SYSTEM_SCREEN_RESOLUTION },
281                                   { "videoencoderinfo", SYSTEM_VIDEO_ENCODER_INFO },
282                                   { "profilename",      SYSTEM_PROFILENAME },
283                                   { "profilethumb",     SYSTEM_PROFILETHUMB },
284                                   { "profilecount",     SYSTEM_PROFILECOUNT },
285                                   { "profileautologin", SYSTEM_PROFILEAUTOLOGIN },
286                                   { "progressbar",      SYSTEM_PROGRESS_BAR },
287                                   { "batterylevel",     SYSTEM_BATTERY_LEVEL },
288                                   { "friendlyname",     SYSTEM_FRIENDLY_NAME },
289                                   { "alarmpos",         SYSTEM_ALARM_POS },
290                                   { "isinhibit",        SYSTEM_ISINHIBIT },
291                                   { "hasshutdown",      SYSTEM_HAS_SHUTDOWN },
292                                   { "haspvr",           SYSTEM_HAS_PVR },
293                                   { "startupwindow",    SYSTEM_STARTUP_WINDOW },
294                                   { "stereoscopicmode", SYSTEM_STEREOSCOPIC_MODE } };
295
296 const infomap system_param[] =   {{ "hasalarm",         SYSTEM_HAS_ALARM },
297                                   { "hascoreid",        SYSTEM_HAS_CORE_ID },
298                                   { "setting",          SYSTEM_SETTING },
299                                   { "hasaddon",         SYSTEM_HAS_ADDON },
300                                   { "coreusage",        SYSTEM_GET_CORE_USAGE }};
301
302 const infomap network_labels[] = {{ "isdhcp",            NETWORK_IS_DHCP },
303                                   { "ipaddress",         NETWORK_IP_ADDRESS }, //labels from here
304                                   { "linkstate",         NETWORK_LINK_STATE },
305                                   { "macaddress",        NETWORK_MAC_ADDRESS },
306                                   { "subnetmask",        NETWORK_SUBNET_MASK },
307                                   { "gatewayaddress",    NETWORK_GATEWAY_ADDRESS },
308                                   { "dns1address",       NETWORK_DNS1_ADDRESS },
309                                   { "dns2address",       NETWORK_DNS2_ADDRESS },
310                                   { "dhcpaddress",       NETWORK_DHCP_ADDRESS }};
311
312 const infomap musicpartymode[] = {{ "enabled",           MUSICPM_ENABLED },
313                                   { "songsplayed",       MUSICPM_SONGSPLAYED },
314                                   { "matchingsongs",     MUSICPM_MATCHINGSONGS },
315                                   { "matchingsongspicked", MUSICPM_MATCHINGSONGSPICKED },
316                                   { "matchingsongsleft", MUSICPM_MATCHINGSONGSLEFT },
317                                   { "relaxedsongspicked",MUSICPM_RELAXEDSONGSPICKED },
318                                   { "randomsongspicked", MUSICPM_RANDOMSONGSPICKED }};
319
320 const infomap musicplayer[] =    {{ "title",            MUSICPLAYER_TITLE },
321                                   { "album",            MUSICPLAYER_ALBUM },
322                                   { "artist",           MUSICPLAYER_ARTIST },
323                                   { "albumartist",      MUSICPLAYER_ALBUM_ARTIST },
324                                   { "year",             MUSICPLAYER_YEAR },
325                                   { "genre",            MUSICPLAYER_GENRE },
326                                   { "duration",         MUSICPLAYER_DURATION },
327                                   { "tracknumber",      MUSICPLAYER_TRACK_NUMBER },
328                                   { "cover",            MUSICPLAYER_COVER },
329                                   { "bitrate",          MUSICPLAYER_BITRATE },
330                                   { "playlistlength",   MUSICPLAYER_PLAYLISTLEN },
331                                   { "playlistposition", MUSICPLAYER_PLAYLISTPOS },
332                                   { "channels",         MUSICPLAYER_CHANNELS },
333                                   { "bitspersample",    MUSICPLAYER_BITSPERSAMPLE },
334                                   { "samplerate",       MUSICPLAYER_SAMPLERATE },
335                                   { "codec",            MUSICPLAYER_CODEC },
336                                   { "discnumber",       MUSICPLAYER_DISC_NUMBER },
337                                   { "rating",           MUSICPLAYER_RATING },
338                                   { "comment",          MUSICPLAYER_COMMENT },
339                                   { "lyrics",           MUSICPLAYER_LYRICS },
340                                   { "playlistplaying",  MUSICPLAYER_PLAYLISTPLAYING },
341                                   { "exists",           MUSICPLAYER_EXISTS },
342                                   { "hasprevious",      MUSICPLAYER_HASPREVIOUS },
343                                   { "hasnext",          MUSICPLAYER_HASNEXT },
344                                   { "playcount",        MUSICPLAYER_PLAYCOUNT },
345                                   { "lastplayed",       MUSICPLAYER_LASTPLAYED },
346                                   { "channelname",      MUSICPLAYER_CHANNEL_NAME },
347                                   { "channelnumber",    MUSICPLAYER_CHANNEL_NUMBER },
348                                   { "channelgroup",     MUSICPLAYER_CHANNEL_GROUP }
349 };
350
351 const infomap videoplayer[] =    {{ "title",            VIDEOPLAYER_TITLE },
352                                   { "genre",            VIDEOPLAYER_GENRE },
353                                   { "country",          VIDEOPLAYER_COUNTRY },
354                                   { "originaltitle",    VIDEOPLAYER_ORIGINALTITLE },
355                                   { "director",         VIDEOPLAYER_DIRECTOR },
356                                   { "year",             VIDEOPLAYER_YEAR },
357                                   { "cover",            VIDEOPLAYER_COVER },
358                                   { "usingoverlays",    VIDEOPLAYER_USING_OVERLAYS },
359                                   { "isfullscreen",     VIDEOPLAYER_ISFULLSCREEN },
360                                   { "hasmenu",          VIDEOPLAYER_HASMENU },
361                                   { "playlistlength",   VIDEOPLAYER_PLAYLISTLEN },
362                                   { "playlistposition", VIDEOPLAYER_PLAYLISTPOS },
363                                   { "plot",             VIDEOPLAYER_PLOT },
364                                   { "plotoutline",      VIDEOPLAYER_PLOT_OUTLINE },
365                                   { "episode",          VIDEOPLAYER_EPISODE },
366                                   { "season",           VIDEOPLAYER_SEASON },
367                                   { "rating",           VIDEOPLAYER_RATING },
368                                   { "ratingandvotes",   VIDEOPLAYER_RATING_AND_VOTES },
369                                   { "votes",            VIDEOPLAYER_VOTES },
370                                   { "tvshowtitle",      VIDEOPLAYER_TVSHOW },
371                                   { "premiered",        VIDEOPLAYER_PREMIERED },
372                                   { "studio",           VIDEOPLAYER_STUDIO },
373                                   { "mpaa",             VIDEOPLAYER_MPAA },
374                                   { "top250",           VIDEOPLAYER_TOP250 },
375                                   { "cast",             VIDEOPLAYER_CAST },
376                                   { "castandrole",      VIDEOPLAYER_CAST_AND_ROLE },
377                                   { "artist",           VIDEOPLAYER_ARTIST },
378                                   { "album",            VIDEOPLAYER_ALBUM },
379                                   { "writer",           VIDEOPLAYER_WRITER },
380                                   { "tagline",          VIDEOPLAYER_TAGLINE },
381                                   { "hasinfo",          VIDEOPLAYER_HAS_INFO },
382                                   { "trailer",          VIDEOPLAYER_TRAILER },
383                                   { "videocodec",       VIDEOPLAYER_VIDEO_CODEC },
384                                   { "videoresolution",  VIDEOPLAYER_VIDEO_RESOLUTION },
385                                   { "videoaspect",      VIDEOPLAYER_VIDEO_ASPECT },
386                                   { "audiocodec",       VIDEOPLAYER_AUDIO_CODEC },
387                                   { "audiochannels",    VIDEOPLAYER_AUDIO_CHANNELS },
388                                   { "audiolanguage",    VIDEOPLAYER_AUDIO_LANG },
389                                   { "hasteletext",      VIDEOPLAYER_HASTELETEXT },
390                                   { "lastplayed",       VIDEOPLAYER_LASTPLAYED },
391                                   { "playcount",        VIDEOPLAYER_PLAYCOUNT },
392                                   { "hassubtitles",     VIDEOPLAYER_HASSUBTITLES },
393                                   { "subtitlesenabled", VIDEOPLAYER_SUBTITLESENABLED },
394                                   { "subtitleslanguage",VIDEOPLAYER_SUBTITLES_LANG },
395                                   { "endtime",          VIDEOPLAYER_ENDTIME },
396                                   { "nexttitle",        VIDEOPLAYER_NEXT_TITLE },
397                                   { "nextgenre",        VIDEOPLAYER_NEXT_GENRE },
398                                   { "nextplot",         VIDEOPLAYER_NEXT_PLOT },
399                                   { "nextplotoutline",  VIDEOPLAYER_NEXT_PLOT_OUTLINE },
400                                   { "nextstarttime",    VIDEOPLAYER_NEXT_STARTTIME },
401                                   { "nextendtime",      VIDEOPLAYER_NEXT_ENDTIME },
402                                   { "nextduration",     VIDEOPLAYER_NEXT_DURATION },
403                                   { "channelname",      VIDEOPLAYER_CHANNEL_NAME },
404                                   { "channelnumber",    VIDEOPLAYER_CHANNEL_NUMBER },
405                                   { "channelgroup",     VIDEOPLAYER_CHANNEL_GROUP },
406                                   { "hasepg",           VIDEOPLAYER_HAS_EPG },
407                                   { "parentalrating",   VIDEOPLAYER_PARENTAL_RATING },
408                                   { "isstereoscopic",   VIDEOPLAYER_IS_STEREOSCOPIC },
409                                   { "stereoscopicmode", VIDEOPLAYER_STEREOSCOPIC_MODE }
410 };
411
412 const infomap mediacontainer[] = {{ "hasfiles",         CONTAINER_HASFILES },
413                                   { "hasfolders",       CONTAINER_HASFOLDERS },
414                                   { "isstacked",        CONTAINER_STACKED },
415                                   { "folderthumb",      CONTAINER_FOLDERTHUMB },
416                                   { "tvshowthumb",      CONTAINER_TVSHOWTHUMB },
417                                   { "seasonthumb",      CONTAINER_SEASONTHUMB },
418                                   { "folderpath",       CONTAINER_FOLDERPATH },
419                                   { "foldername",       CONTAINER_FOLDERNAME },
420                                   { "pluginname",       CONTAINER_PLUGINNAME },
421                                   { "viewmode",         CONTAINER_VIEWMODE },
422                                   { "totaltime",        CONTAINER_TOTALTIME },
423                                   { "hasthumb",         CONTAINER_HAS_THUMB },
424                                   { "sortmethod",       CONTAINER_SORT_METHOD },
425                                   { "showplot",         CONTAINER_SHOWPLOT }};
426
427 const infomap container_bools[] ={{ "onnext",           CONTAINER_MOVE_NEXT },
428                                   { "onprevious",       CONTAINER_MOVE_PREVIOUS },
429                                   { "onscrollnext",     CONTAINER_SCROLL_NEXT },
430                                   { "onscrollprevious", CONTAINER_SCROLL_PREVIOUS },
431                                   { "numpages",         CONTAINER_NUM_PAGES },
432                                   { "numitems",         CONTAINER_NUM_ITEMS },
433                                   { "currentpage",      CONTAINER_CURRENT_PAGE },
434                                   { "scrolling",        CONTAINER_SCROLLING },
435                                   { "hasnext",          CONTAINER_HAS_NEXT },
436                                   { "hasprevious",      CONTAINER_HAS_PREVIOUS },
437                                   { "canfilter",        CONTAINER_CAN_FILTER },
438                                   { "canfilteradvanced",CONTAINER_CAN_FILTERADVANCED },
439                                   { "filtered",         CONTAINER_FILTERED }};
440
441 const infomap container_ints[] = {{ "row",              CONTAINER_ROW },
442                                   { "column",           CONTAINER_COLUMN },
443                                   { "position",         CONTAINER_POSITION },
444                                   { "subitem",          CONTAINER_SUBITEM },
445                                   { "hasfocus",         CONTAINER_HAS_FOCUS }};
446
447 const infomap container_str[]  = {{ "property",         CONTAINER_PROPERTY },
448                                   { "content",          CONTAINER_CONTENT }};
449
450 const infomap listitem_labels[]= {{ "thumb",            LISTITEM_THUMB },
451                                   { "icon",             LISTITEM_ICON },
452                                   { "actualicon",       LISTITEM_ACTUAL_ICON },
453                                   { "overlay",          LISTITEM_OVERLAY },
454                                   { "label",            LISTITEM_LABEL },
455                                   { "label2",           LISTITEM_LABEL2 },
456                                   { "title",            LISTITEM_TITLE },
457                                   { "tracknumber",      LISTITEM_TRACKNUMBER },
458                                   { "artist",           LISTITEM_ARTIST },
459                                   { "album",            LISTITEM_ALBUM },
460                                   { "albumartist",      LISTITEM_ALBUM_ARTIST },
461                                   { "year",             LISTITEM_YEAR },
462                                   { "genre",            LISTITEM_GENRE },
463                                   { "director",         LISTITEM_DIRECTOR },
464                                   { "filename",         LISTITEM_FILENAME },
465                                   { "filenameandpath",  LISTITEM_FILENAME_AND_PATH },
466                                   { "fileextension",    LISTITEM_FILE_EXTENSION },
467                                   { "date",             LISTITEM_DATE },
468                                   { "size",             LISTITEM_SIZE },
469                                   { "rating",           LISTITEM_RATING },
470                                   { "ratingandvotes",   LISTITEM_RATING_AND_VOTES },
471                                   { "votes",            LISTITEM_VOTES },
472                                   { "programcount",     LISTITEM_PROGRAM_COUNT },
473                                   { "duration",         LISTITEM_DURATION },
474                                   { "isselected",       LISTITEM_ISSELECTED },
475                                   { "isplaying",        LISTITEM_ISPLAYING },
476                                   { "plot",             LISTITEM_PLOT },
477                                   { "plotoutline",      LISTITEM_PLOT_OUTLINE },
478                                   { "episode",          LISTITEM_EPISODE },
479                                   { "season",           LISTITEM_SEASON },
480                                   { "tvshowtitle",      LISTITEM_TVSHOW },
481                                   { "premiered",        LISTITEM_PREMIERED },
482                                   { "comment",          LISTITEM_COMMENT },
483                                   { "path",             LISTITEM_PATH },
484                                   { "foldername",       LISTITEM_FOLDERNAME },
485                                   { "folderpath",       LISTITEM_FOLDERPATH },
486                                   { "picturepath",      LISTITEM_PICTURE_PATH },
487                                   { "pictureresolution",LISTITEM_PICTURE_RESOLUTION },
488                                   { "picturedatetime",  LISTITEM_PICTURE_DATETIME },
489                                   { "picturedate",      LISTITEM_PICTURE_DATE },
490                                   { "picturelongdatetime",LISTITEM_PICTURE_LONGDATETIME },
491                                   { "picturelongdate",  LISTITEM_PICTURE_LONGDATE },
492                                   { "picturecomment",   LISTITEM_PICTURE_COMMENT },
493                                   { "picturecaption",   LISTITEM_PICTURE_CAPTION },
494                                   { "picturedesc",      LISTITEM_PICTURE_DESC },
495                                   { "picturekeywords",  LISTITEM_PICTURE_KEYWORDS },
496                                   { "picturecammake",   LISTITEM_PICTURE_CAM_MAKE },
497                                   { "picturecammodel",  LISTITEM_PICTURE_CAM_MODEL },
498                                   { "pictureaperture",  LISTITEM_PICTURE_APERTURE },
499                                   { "picturefocallen",  LISTITEM_PICTURE_FOCAL_LEN },
500                                   { "picturefocusdist", LISTITEM_PICTURE_FOCUS_DIST },
501                                   { "pictureexpmode",   LISTITEM_PICTURE_EXP_MODE },
502                                   { "pictureexptime",   LISTITEM_PICTURE_EXP_TIME },
503                                   { "pictureiso",       LISTITEM_PICTURE_ISO },
504                                   { "pictureauthor",                 LISTITEM_PICTURE_AUTHOR },
505                                   { "picturebyline",                 LISTITEM_PICTURE_BYLINE },
506                                   { "picturebylinetitle",            LISTITEM_PICTURE_BYLINE_TITLE },
507                                   { "picturecategory",               LISTITEM_PICTURE_CATEGORY },
508                                   { "pictureccdwidth",               LISTITEM_PICTURE_CCD_WIDTH },
509                                   { "picturecity",                   LISTITEM_PICTURE_CITY },
510                                   { "pictureurgency",                LISTITEM_PICTURE_URGENCY },
511                                   { "picturecopyrightnotice",        LISTITEM_PICTURE_COPYRIGHT_NOTICE },
512                                   { "picturecountry",                LISTITEM_PICTURE_COUNTRY },
513                                   { "picturecountrycode",            LISTITEM_PICTURE_COUNTRY_CODE },
514                                   { "picturecredit",                 LISTITEM_PICTURE_CREDIT },
515                                   { "pictureiptcdate",               LISTITEM_PICTURE_IPTCDATE },
516                                   { "picturedigitalzoom",            LISTITEM_PICTURE_DIGITAL_ZOOM },
517                                   { "pictureexposure",               LISTITEM_PICTURE_EXPOSURE },
518                                   { "pictureexposurebias",           LISTITEM_PICTURE_EXPOSURE_BIAS },
519                                   { "pictureflashused",              LISTITEM_PICTURE_FLASH_USED },
520                                   { "pictureheadline",               LISTITEM_PICTURE_HEADLINE },
521                                   { "picturecolour",                 LISTITEM_PICTURE_COLOUR },
522                                   { "picturelightsource",            LISTITEM_PICTURE_LIGHT_SOURCE },
523                                   { "picturemeteringmode",           LISTITEM_PICTURE_METERING_MODE },
524                                   { "pictureobjectname",             LISTITEM_PICTURE_OBJECT_NAME },
525                                   { "pictureorientation",            LISTITEM_PICTURE_ORIENTATION },
526                                   { "pictureprocess",                LISTITEM_PICTURE_PROCESS },
527                                   { "picturereferenceservice",       LISTITEM_PICTURE_REF_SERVICE },
528                                   { "picturesource",                 LISTITEM_PICTURE_SOURCE },
529                                   { "picturespecialinstructions",    LISTITEM_PICTURE_SPEC_INSTR },
530                                   { "picturestate",                  LISTITEM_PICTURE_STATE },
531                                   { "picturesupplementalcategories", LISTITEM_PICTURE_SUP_CATEGORIES },
532                                   { "picturetransmissionreference",  LISTITEM_PICTURE_TX_REFERENCE },
533                                   { "picturewhitebalance",           LISTITEM_PICTURE_WHITE_BALANCE },
534                                   { "pictureimagetype",              LISTITEM_PICTURE_IMAGETYPE },
535                                   { "picturesublocation",            LISTITEM_PICTURE_SUBLOCATION },
536                                   { "pictureiptctime",               LISTITEM_PICTURE_TIMECREATED },
537                                   { "picturegpslat",    LISTITEM_PICTURE_GPS_LAT },
538                                   { "picturegpslon",    LISTITEM_PICTURE_GPS_LON },
539                                   { "picturegpsalt",    LISTITEM_PICTURE_GPS_ALT },
540                                   { "studio",           LISTITEM_STUDIO },
541                                   { "country",          LISTITEM_COUNTRY },
542                                   { "mpaa",             LISTITEM_MPAA },
543                                   { "cast",             LISTITEM_CAST },
544                                   { "castandrole",      LISTITEM_CAST_AND_ROLE },
545                                   { "writer",           LISTITEM_WRITER },
546                                   { "tagline",          LISTITEM_TAGLINE },
547                                   { "top250",           LISTITEM_TOP250 },
548                                   { "trailer",          LISTITEM_TRAILER },
549                                   { "starrating",       LISTITEM_STAR_RATING },
550                                   { "sortletter",       LISTITEM_SORT_LETTER },
551                                   { "videocodec",       LISTITEM_VIDEO_CODEC },
552                                   { "videoresolution",  LISTITEM_VIDEO_RESOLUTION },
553                                   { "videoaspect",      LISTITEM_VIDEO_ASPECT },
554                                   { "audiocodec",       LISTITEM_AUDIO_CODEC },
555                                   { "audiochannels",    LISTITEM_AUDIO_CHANNELS },
556                                   { "audiolanguage",    LISTITEM_AUDIO_LANGUAGE },
557                                   { "subtitlelanguage", LISTITEM_SUBTITLE_LANGUAGE },
558                                   { "isresumable",      LISTITEM_IS_RESUMABLE},
559                                   { "percentplayed",    LISTITEM_PERCENT_PLAYED},
560                                   { "isfolder",         LISTITEM_IS_FOLDER },
561                                   { "originaltitle",    LISTITEM_ORIGINALTITLE },
562                                   { "lastplayed",       LISTITEM_LASTPLAYED },
563                                   { "playcount",        LISTITEM_PLAYCOUNT },
564                                   { "discnumber",       LISTITEM_DISC_NUMBER },
565                                   { "starttime",        LISTITEM_STARTTIME },
566                                   { "endtime",          LISTITEM_ENDTIME },
567                                   { "startdate",        LISTITEM_STARTDATE },
568                                   { "enddate",          LISTITEM_ENDDATE },
569                                   { "nexttitle",        LISTITEM_NEXT_TITLE },
570                                   { "nextgenre",        LISTITEM_NEXT_GENRE },
571                                   { "nextplot",         LISTITEM_NEXT_PLOT },
572                                   { "nextplotoutline",  LISTITEM_NEXT_PLOT_OUTLINE },
573                                   { "nextstarttime",    LISTITEM_NEXT_STARTTIME },
574                                   { "nextendtime",      LISTITEM_NEXT_ENDTIME },
575                                   { "nextstartdate",    LISTITEM_NEXT_STARTDATE },
576                                   { "nextenddate",      LISTITEM_NEXT_ENDDATE },
577                                   { "channelname",      LISTITEM_CHANNEL_NAME },
578                                   { "channelnumber",    LISTITEM_CHANNEL_NUMBER },
579                                   { "channelgroup",     LISTITEM_CHANNEL_GROUP },
580                                   { "hasepg",           LISTITEM_HAS_EPG },
581                                   { "hastimer",         LISTITEM_HASTIMER },
582                                   { "isrecording",      LISTITEM_ISRECORDING },
583                                   { "isencrypted",      LISTITEM_ISENCRYPTED },
584                                   { "progress",         LISTITEM_PROGRESS },
585                                   { "dateadded",        LISTITEM_DATE_ADDED },
586                                   { "dbtype",           LISTITEM_DBTYPE },
587                                   { "dbid",             LISTITEM_DBID },
588                                   { "stereoscopicmode", LISTITEM_STEREOSCOPIC_MODE },
589                                   { "isstereoscopic",   LISTITEM_IS_STEREOSCOPIC }};
590
591 const infomap visualisation[] =  {{ "locked",           VISUALISATION_LOCKED },
592                                   { "preset",           VISUALISATION_PRESET },
593                                   { "name",             VISUALISATION_NAME },
594                                   { "enabled",          VISUALISATION_ENABLED }};
595
596 const infomap fanart_labels[] =  {{ "color1",           FANART_COLOR1 },
597                                   { "color2",           FANART_COLOR2 },
598                                   { "color3",           FANART_COLOR3 },
599                                   { "image",            FANART_IMAGE }};
600
601 const infomap skin_labels[] =    {{ "currenttheme",     SKIN_THEME },
602                                   { "currentcolourtheme",SKIN_COLOUR_THEME },
603                                   {"hasvideooverlay",   SKIN_HAS_VIDEO_OVERLAY},
604                                   {"hasmusicoverlay",   SKIN_HAS_MUSIC_OVERLAY},
605                                   {"aspectratio",       SKIN_ASPECT_RATIO}};
606
607 const infomap window_bools[] =   {{ "ismedia",          WINDOW_IS_MEDIA },
608                                   { "isactive",         WINDOW_IS_ACTIVE },
609                                   { "istopmost",        WINDOW_IS_TOPMOST },
610                                   { "isvisible",        WINDOW_IS_VISIBLE },
611                                   { "previous",         WINDOW_PREVIOUS },
612                                   { "next",             WINDOW_NEXT }};
613
614 const infomap control_labels[] = {{ "hasfocus",         CONTROL_HAS_FOCUS },
615                                   { "isvisible",        CONTROL_IS_VISIBLE },
616                                   { "isenabled",        CONTROL_IS_ENABLED },
617                                   { "getlabel",         CONTROL_GET_LABEL }};
618
619 const infomap playlist[] =       {{ "length",           PLAYLIST_LENGTH },
620                                   { "position",         PLAYLIST_POSITION },
621                                   { "random",           PLAYLIST_RANDOM },
622                                   { "repeat",           PLAYLIST_REPEAT },
623                                   { "israndom",         PLAYLIST_ISRANDOM },
624                                   { "isrepeat",         PLAYLIST_ISREPEAT },
625                                   { "isrepeatone",      PLAYLIST_ISREPEATONE }};
626
627 const infomap pvr[] =            {{ "isrecording",              PVR_IS_RECORDING },
628                                   { "hastimer",                 PVR_HAS_TIMER },
629                                   { "hasnonrecordingtimer",     PVR_HAS_NONRECORDING_TIMER },
630                                   { "nowrecordingtitle",        PVR_NOW_RECORDING_TITLE },
631                                   { "nowrecordingdatetime",     PVR_NOW_RECORDING_DATETIME },
632                                   { "nowrecordingchannel",      PVR_NOW_RECORDING_CHANNEL },
633                                   { "nowrecordingchannelicon",  PVR_NOW_RECORDING_CHAN_ICO },
634                                   { "nextrecordingtitle",       PVR_NEXT_RECORDING_TITLE },
635                                   { "nextrecordingdatetime",    PVR_NEXT_RECORDING_DATETIME },
636                                   { "nextrecordingchannel",     PVR_NEXT_RECORDING_CHANNEL },
637                                   { "nextrecordingchannelicon", PVR_NEXT_RECORDING_CHAN_ICO },
638                                   { "backendname",              PVR_BACKEND_NAME },
639                                   { "backendversion",           PVR_BACKEND_VERSION },
640                                   { "backendhost",              PVR_BACKEND_HOST },
641                                   { "backenddiskspace",         PVR_BACKEND_DISKSPACE },
642                                   { "backendchannels",          PVR_BACKEND_CHANNELS },
643                                   { "backendtimers",            PVR_BACKEND_TIMERS },
644                                   { "backendrecordings",        PVR_BACKEND_RECORDINGS },
645                                   { "backendnumber",            PVR_BACKEND_NUMBER },
646                                   { "hasepg",                   PVR_HAS_EPG },
647                                   { "hastxt",                   PVR_HAS_TXT },
648                                   { "hasdirector",              PVR_HAS_DIRECTOR },
649                                   { "totaldiscspace",           PVR_TOTAL_DISKSPACE },
650                                   { "nexttimer",                PVR_NEXT_TIMER },
651                                   { "isplayingtv",              PVR_IS_PLAYING_TV },
652                                   { "isplayingradio",           PVR_IS_PLAYING_RADIO },
653                                   { "isplayingrecording",       PVR_IS_PLAYING_RECORDING },
654                                   { "duration",                 PVR_PLAYING_DURATION },
655                                   { "time",                     PVR_PLAYING_TIME },
656                                   { "progress",                 PVR_PLAYING_PROGRESS },
657                                   { "actstreamclient",          PVR_ACTUAL_STREAM_CLIENT },
658                                   { "actstreamdevice",          PVR_ACTUAL_STREAM_DEVICE },
659                                   { "actstreamstatus",          PVR_ACTUAL_STREAM_STATUS },
660                                   { "actstreamsignal",          PVR_ACTUAL_STREAM_SIG },
661                                   { "actstreamsnr",             PVR_ACTUAL_STREAM_SNR },
662                                   { "actstreamber",             PVR_ACTUAL_STREAM_BER },
663                                   { "actstreamunc",             PVR_ACTUAL_STREAM_UNC },
664                                   { "actstreamvideobitrate",    PVR_ACTUAL_STREAM_VIDEO_BR },
665                                   { "actstreamaudiobitrate",    PVR_ACTUAL_STREAM_AUDIO_BR },
666                                   { "actstreamdolbybitrate",    PVR_ACTUAL_STREAM_DOLBY_BR },
667                                   { "actstreamprogrsignal",     PVR_ACTUAL_STREAM_SIG_PROGR },
668                                   { "actstreamprogrsnr",        PVR_ACTUAL_STREAM_SNR_PROGR },
669                                   { "actstreamisencrypted",     PVR_ACTUAL_STREAM_ENCRYPTED },
670                                   { "actstreamencryptionname",  PVR_ACTUAL_STREAM_CRYPTION },
671                                   { "actstreamservicename",     PVR_ACTUAL_STREAM_SERVICE },
672                                   { "actstreammux",             PVR_ACTUAL_STREAM_MUX },
673                                   { "actstreamprovidername",    PVR_ACTUAL_STREAM_PROVIDER }};
674
675 const infomap slideshow[] =      {{ "ispaused",         SLIDESHOW_ISPAUSED },
676                                   { "isactive",         SLIDESHOW_ISACTIVE },
677                                   { "isvideo",          SLIDESHOW_ISVIDEO },
678                                   { "israndom",         SLIDESHOW_ISRANDOM }};
679
680 const int picture_slide_map[]  = {/* LISTITEM_PICTURE_RESOLUTION => */ SLIDE_RESOLUTION,
681                                   /* LISTITEM_PICTURE_LONGDATE   => */ SLIDE_EXIF_LONG_DATE,
682                                   /* LISTITEM_PICTURE_LONGDATETIME => */ SLIDE_EXIF_LONG_DATE_TIME,
683                                   /* LISTITEM_PICTURE_DATE       => */ SLIDE_EXIF_DATE,
684                                   /* LISTITEM_PICTURE_DATETIME   => */ SLIDE_EXIF_DATE_TIME,
685                                   /* LISTITEM_PICTURE_COMMENT    => */ SLIDE_COMMENT,
686                                   /* LISTITEM_PICTURE_CAPTION    => */ SLIDE_IPTC_CAPTION,
687                                   /* LISTITEM_PICTURE_DESC       => */ SLIDE_EXIF_DESCRIPTION,
688                                   /* LISTITEM_PICTURE_KEYWORDS   => */ SLIDE_IPTC_KEYWORDS,
689                                   /* LISTITEM_PICTURE_CAM_MAKE   => */ SLIDE_EXIF_CAMERA_MAKE,
690                                   /* LISTITEM_PICTURE_CAM_MODEL  => */ SLIDE_EXIF_CAMERA_MODEL,
691                                   /* LISTITEM_PICTURE_APERTURE   => */ SLIDE_EXIF_APERTURE,
692                                   /* LISTITEM_PICTURE_FOCAL_LEN  => */ SLIDE_EXIF_FOCAL_LENGTH,
693                                   /* LISTITEM_PICTURE_FOCUS_DIST => */ SLIDE_EXIF_FOCUS_DIST,
694                                   /* LISTITEM_PICTURE_EXP_MODE   => */ SLIDE_EXIF_EXPOSURE_MODE,
695                                   /* LISTITEM_PICTURE_EXP_TIME   => */ SLIDE_EXIF_EXPOSURE_TIME,
696                                   /* LISTITEM_PICTURE_ISO        => */ SLIDE_EXIF_ISO_EQUIV,
697                                   /* LISTITEM_PICTURE_AUTHOR           => */ SLIDE_IPTC_AUTHOR,
698                                   /* LISTITEM_PICTURE_BYLINE           => */ SLIDE_IPTC_BYLINE,
699                                   /* LISTITEM_PICTURE_BYLINE_TITLE     => */ SLIDE_IPTC_BYLINE_TITLE,
700                                   /* LISTITEM_PICTURE_CATEGORY         => */ SLIDE_IPTC_CATEGORY,
701                                   /* LISTITEM_PICTURE_CCD_WIDTH        => */ SLIDE_EXIF_CCD_WIDTH,
702                                   /* LISTITEM_PICTURE_CITY             => */ SLIDE_IPTC_CITY,
703                                   /* LISTITEM_PICTURE_URGENCY          => */ SLIDE_IPTC_URGENCY,
704                                   /* LISTITEM_PICTURE_COPYRIGHT_NOTICE => */ SLIDE_IPTC_COPYRIGHT_NOTICE,
705                                   /* LISTITEM_PICTURE_COUNTRY          => */ SLIDE_IPTC_COUNTRY,
706                                   /* LISTITEM_PICTURE_COUNTRY_CODE     => */ SLIDE_IPTC_COUNTRY_CODE,
707                                   /* LISTITEM_PICTURE_CREDIT           => */ SLIDE_IPTC_CREDIT,
708                                   /* LISTITEM_PICTURE_IPTCDATE         => */ SLIDE_IPTC_DATE,
709                                   /* LISTITEM_PICTURE_DIGITAL_ZOOM     => */ SLIDE_EXIF_DIGITAL_ZOOM,
710                                   /* LISTITEM_PICTURE_EXPOSURE         => */ SLIDE_EXIF_EXPOSURE,
711                                   /* LISTITEM_PICTURE_EXPOSURE_BIAS    => */ SLIDE_EXIF_EXPOSURE_BIAS,
712                                   /* LISTITEM_PICTURE_FLASH_USED       => */ SLIDE_EXIF_FLASH_USED,
713                                   /* LISTITEM_PICTURE_HEADLINE         => */ SLIDE_IPTC_HEADLINE,
714                                   /* LISTITEM_PICTURE_COLOUR           => */ SLIDE_COLOUR,
715                                   /* LISTITEM_PICTURE_LIGHT_SOURCE     => */ SLIDE_EXIF_LIGHT_SOURCE,
716                                   /* LISTITEM_PICTURE_METERING_MODE    => */ SLIDE_EXIF_METERING_MODE,
717                                   /* LISTITEM_PICTURE_OBJECT_NAME      => */ SLIDE_IPTC_OBJECT_NAME,
718                                   /* LISTITEM_PICTURE_ORIENTATION      => */ SLIDE_EXIF_ORIENTATION,
719                                   /* LISTITEM_PICTURE_PROCESS          => */ SLIDE_PROCESS,
720                                   /* LISTITEM_PICTURE_REF_SERVICE      => */ SLIDE_IPTC_REF_SERVICE,
721                                   /* LISTITEM_PICTURE_SOURCE           => */ SLIDE_IPTC_SOURCE,
722                                   /* LISTITEM_PICTURE_SPEC_INSTR       => */ SLIDE_IPTC_SPEC_INSTR,
723                                   /* LISTITEM_PICTURE_STATE            => */ SLIDE_IPTC_STATE,
724                                   /* LISTITEM_PICTURE_SUP_CATEGORIES   => */ SLIDE_IPTC_SUP_CATEGORIES,
725                                   /* LISTITEM_PICTURE_TX_REFERENCE     => */ SLIDE_IPTC_TX_REFERENCE,
726                                   /* LISTITEM_PICTURE_WHITE_BALANCE    => */ SLIDE_EXIF_WHITE_BALANCE,
727                                   /* LISTITEM_PICTURE_IMAGETYPE        => */ SLIDE_IPTC_IMAGETYPE,
728                                   /* LISTITEM_PICTURE_SUBLOCATION      => */ SLIDE_IPTC_SUBLOCATION,
729                                   /* LISTITEM_PICTURE_TIMECREATED      => */ SLIDE_IPTC_TIMECREATED,
730                                   /* LISTITEM_PICTURE_GPS_LAT    => */ SLIDE_EXIF_GPS_LATITUDE,
731                                   /* LISTITEM_PICTURE_GPS_LON    => */ SLIDE_EXIF_GPS_LONGITUDE,
732                                   /* LISTITEM_PICTURE_GPS_ALT    => */ SLIDE_EXIF_GPS_ALTITUDE };
733
734 CGUIInfoManager::Property::Property(const CStdString &property, const CStdString &parameters)
735 : name(property)
736 {
737   CUtil::SplitParams(parameters, params);
738 }
739
740 const CStdString &CGUIInfoManager::Property::param(unsigned int n /* = 0 */) const
741 {
742   if (n < params.size())
743     return params[n];
744   return StringUtils::EmptyString;
745 }
746
747 unsigned int CGUIInfoManager::Property::num_params() const
748 {
749   return params.size();
750 }
751
752 void CGUIInfoManager::SplitInfoString(const CStdString &infoString, vector<Property> &info)
753 {
754   // our string is of the form:
755   // category[(params)][.info(params).info2(params)] ...
756   // so we need to split on . while taking into account of () pairs
757   unsigned int parentheses = 0;
758   CStdString property;
759   CStdString param;
760   for (size_t i = 0; i < infoString.size(); ++i)
761   {
762     if (infoString[i] == '(')
763     {
764       if (!parentheses++)
765         continue;
766     }
767     else if (infoString[i] == ')')
768     {
769       if (!parentheses)
770         CLog::Log(LOGERROR, "unmatched parentheses in %s", infoString.c_str());
771       else if (!--parentheses)
772         continue;
773     }
774     else if (infoString[i] == '.' && !parentheses)
775     {
776       if (!property.empty()) // add our property and parameters
777       {
778         StringUtils::ToLower(property);
779         info.push_back(Property(property, param));
780       }
781       property.clear();
782       param.clear();
783       continue;
784     }
785     if (parentheses)
786       param += infoString[i];
787     else
788       property += infoString[i];
789   }
790   if (parentheses)
791     CLog::Log(LOGERROR, "unmatched parentheses in %s", infoString.c_str());
792   if (!property.empty())
793   {
794     StringUtils::ToLower(property);
795     info.push_back(Property(property, param));
796   }
797 }
798
799 /// \brief Translates a string as given by the skin into an int that we use for more
800 /// efficient retrieval of data.
801 int CGUIInfoManager::TranslateSingleString(const CStdString &strCondition)
802 {
803   bool listItemDependent;
804   return TranslateSingleString(strCondition, listItemDependent);
805 }
806
807 int CGUIInfoManager::TranslateSingleString(const CStdString &strCondition, bool &listItemDependent)
808 {
809   /* We need to disable caching in INFO::InfoBool::Get if either of the following are true:
810    *  1. if condition is between LISTITEM_START and LISTITEM_END
811    *  2. if condition is STRING_IS_EMPTY, STRING_COMPARE, STRING_STR, INTEGER_GREATER_THAN and the
812    *     corresponding label is between LISTITEM_START and LISTITEM_END
813    *  This is achieved by setting the bool pointed at by listItemDependent, either here or in a recursive call
814    */
815   // trim whitespaces
816   CStdString strTest = strCondition;
817   StringUtils::Trim(strTest);
818
819   vector< Property> info;
820   SplitInfoString(strTest, info);
821
822   if (info.empty())
823     return 0;
824
825   const Property &cat = info[0];
826   if (info.size() == 1)
827   { // single category
828     if (cat.name == "false" || cat.name == "no" || cat.name == "off")
829       return SYSTEM_ALWAYS_FALSE;
830     else if (cat.name == "true" || cat.name == "yes" || cat.name == "on")
831       return SYSTEM_ALWAYS_TRUE;
832     if (cat.name == "isempty" && cat.num_params() == 1)
833       return AddMultiInfo(GUIInfo(STRING_IS_EMPTY, TranslateSingleString(cat.param(), listItemDependent)));
834     else if (cat.name == "stringcompare" && cat.num_params() == 2)
835     {
836       int info = TranslateSingleString(cat.param(0), listItemDependent);
837       int info2 = TranslateSingleString(cat.param(1), listItemDependent);
838       if (info2 > 0)
839         return AddMultiInfo(GUIInfo(STRING_COMPARE, info, -info2));
840       // pipe our original string through the localize parsing then make it lowercase (picks up $LBRACKET etc.)
841       CStdString label = CGUIInfoLabel::GetLabel(cat.param(1));
842       StringUtils::ToLower(label);
843       int compareString = ConditionalStringParameter(label);
844       return AddMultiInfo(GUIInfo(STRING_COMPARE, info, compareString));
845     }
846     else if (cat.name == "integergreaterthan" && cat.num_params() == 2)
847     {
848       int info = TranslateSingleString(cat.param(0), listItemDependent);
849       int compareInt = atoi(cat.param(1).c_str());
850       return AddMultiInfo(GUIInfo(INTEGER_GREATER_THAN, info, compareInt));
851     }
852     else if (cat.name == "substring" && cat.num_params() >= 2)
853     {
854       int info = TranslateSingleString(cat.param(0), listItemDependent);
855       CStdString label = CGUIInfoLabel::GetLabel(cat.param(1));
856       StringUtils::ToLower(label);
857       int compareString = ConditionalStringParameter(label);
858       if (cat.num_params() > 2)
859       {
860         if (StringUtils::EqualsNoCase(cat.param(2), "left"))
861           return AddMultiInfo(GUIInfo(STRING_STR_LEFT, info, compareString));
862         else if (StringUtils::EqualsNoCase(cat.param(2), "right"))
863           return AddMultiInfo(GUIInfo(STRING_STR_RIGHT, info, compareString));
864       }
865       return AddMultiInfo(GUIInfo(STRING_STR, info, compareString));
866     }
867   }
868   else if (info.size() == 2)
869   {
870     const Property &prop = info[1];
871     if (cat.name == "player")
872     {
873       for (size_t i = 0; i < sizeof(player_labels) / sizeof(infomap); i++)
874       {
875         if (prop.name == player_labels[i].str)
876           return player_labels[i].val;
877       }
878       for (size_t i = 0; i < sizeof(player_times) / sizeof(infomap); i++)
879       {
880         if (prop.name == player_times[i].str)
881           return AddMultiInfo(GUIInfo(player_times[i].val, TranslateTimeFormat(prop.param())));
882       }
883       if (prop.num_params() == 1)
884       {
885         for (size_t i = 0; i < sizeof(player_param) / sizeof(infomap); i++)
886         {
887           if (prop.name == player_param[i].str)
888             return AddMultiInfo(GUIInfo(player_param[i].val, ConditionalStringParameter(prop.param())));
889         }
890       }
891     }
892     else if (cat.name == "weather")
893     {
894       for (size_t i = 0; i < sizeof(weather) / sizeof(infomap); i++)
895       {
896         if (prop.name == weather[i].str)
897           return weather[i].val;
898       }
899     }
900     else if (cat.name == "network")
901     {
902       for (size_t i = 0; i < sizeof(network_labels) / sizeof(infomap); i++)
903       {
904         if (prop.name == network_labels[i].str)
905           return network_labels[i].val;
906       }
907     }
908     else if (cat.name == "musicpartymode")
909     {
910       for (size_t i = 0; i < sizeof(musicpartymode) / sizeof(infomap); i++)
911       {
912         if (prop.name == musicpartymode[i].str)
913           return musicpartymode[i].val;
914       }
915     }
916     else if (cat.name == "system")
917     {
918       for (size_t i = 0; i < sizeof(system_labels) / sizeof(infomap); i++)
919       {
920         if (prop.name == system_labels[i].str)
921           return system_labels[i].val;
922       }
923       if (prop.num_params() == 1)
924       {
925         const CStdString &param = prop.param();
926         if (prop.name == "getbool")
927         {
928           std::string paramCopy = param;
929           StringUtils::ToLower(paramCopy);
930           return AddMultiInfo(GUIInfo(SYSTEM_GET_BOOL, ConditionalStringParameter(paramCopy, true)));
931         }
932         for (size_t i = 0; i < sizeof(system_param) / sizeof(infomap); i++)
933         {
934           if (prop.name == system_param[i].str)
935             return AddMultiInfo(GUIInfo(system_param[i].val, ConditionalStringParameter(param)));
936         }
937         if (prop.name == "memory")
938         {
939           if (param == "free") return SYSTEM_FREE_MEMORY;
940           else if (param == "free.percent") return SYSTEM_FREE_MEMORY_PERCENT;
941           else if (param == "used") return SYSTEM_USED_MEMORY;
942           else if (param == "used.percent") return SYSTEM_USED_MEMORY_PERCENT;
943           else if (param == "total") return SYSTEM_TOTAL_MEMORY;
944         }
945         else if (prop.name == "addontitle")
946         {
947           int infoLabel = TranslateSingleString(param, listItemDependent);
948           if (infoLabel > 0)
949             return AddMultiInfo(GUIInfo(SYSTEM_ADDON_TITLE, infoLabel, 0));
950           CStdString label = CGUIInfoLabel::GetLabel(param);
951           StringUtils::ToLower(label);
952           return AddMultiInfo(GUIInfo(SYSTEM_ADDON_TITLE, ConditionalStringParameter(label), 1));
953         }
954         else if (prop.name == "addonicon")
955         {
956           int infoLabel = TranslateSingleString(param, listItemDependent);
957           if (infoLabel > 0)
958             return AddMultiInfo(GUIInfo(SYSTEM_ADDON_ICON, infoLabel, 0));
959           CStdString label = CGUIInfoLabel::GetLabel(param);
960           StringUtils::ToLower(label);
961           return AddMultiInfo(GUIInfo(SYSTEM_ADDON_ICON, ConditionalStringParameter(label), 1));
962         }
963         else if (prop.name == "addonversion")
964         {
965           int infoLabel = TranslateSingleString(param, listItemDependent);
966           if (infoLabel > 0)
967             return AddMultiInfo(GUIInfo(SYSTEM_ADDON_VERSION, infoLabel, 0));
968           CStdString label = CGUIInfoLabel::GetLabel(param);
969           StringUtils::ToLower(label);
970           return AddMultiInfo(GUIInfo(SYSTEM_ADDON_VERSION, ConditionalStringParameter(label), 1));
971         }
972         else if (prop.name == "idletime")
973           return AddMultiInfo(GUIInfo(SYSTEM_IDLE_TIME, atoi(param.c_str())));
974       }
975       if (prop.name == "alarmlessorequal" && prop.num_params() == 2)
976         return AddMultiInfo(GUIInfo(SYSTEM_ALARM_LESS_OR_EQUAL, ConditionalStringParameter(prop.param(0)), ConditionalStringParameter(prop.param(1))));
977       else if (prop.name == "date")
978       {
979         if (prop.num_params() == 2)
980           return AddMultiInfo(GUIInfo(SYSTEM_DATE, StringUtils::DateStringToYYYYMMDD(prop.param(0)) % 10000, StringUtils::DateStringToYYYYMMDD(prop.param(1)) % 10000));
981         else if (prop.num_params() == 1)
982         {
983           int dateformat = StringUtils::DateStringToYYYYMMDD(prop.param(0));
984           if (dateformat <= 0) // not concrete date
985             return AddMultiInfo(GUIInfo(SYSTEM_DATE, ConditionalStringParameter(prop.param(0), true), -1));
986           else
987             return AddMultiInfo(GUIInfo(SYSTEM_DATE, dateformat % 10000));
988         }
989         return SYSTEM_DATE;
990       }
991       else if (prop.name == "time")
992       {
993         if (prop.num_params() == 0)
994           return AddMultiInfo(GUIInfo(SYSTEM_TIME, TIME_FORMAT_GUESS));
995         if (prop.num_params() == 1)
996         {
997           TIME_FORMAT timeFormat = TranslateTimeFormat(prop.param(0));
998           if (timeFormat == TIME_FORMAT_GUESS)
999             return AddMultiInfo(GUIInfo(SYSTEM_TIME, StringUtils::TimeStringToSeconds(prop.param(0))));
1000           return AddMultiInfo(GUIInfo(SYSTEM_TIME, timeFormat));
1001         }
1002         else
1003           return AddMultiInfo(GUIInfo(SYSTEM_TIME, StringUtils::TimeStringToSeconds(prop.param(0)), StringUtils::TimeStringToSeconds(prop.param(1))));
1004       }
1005     }
1006     else if (cat.name == "library")
1007     {
1008       if (prop.name == "isscanning") return LIBRARY_IS_SCANNING;
1009       else if (prop.name == "isscanningvideo") return LIBRARY_IS_SCANNING_VIDEO; // TODO: change to IsScanning(Video)
1010       else if (prop.name == "isscanningmusic") return LIBRARY_IS_SCANNING_MUSIC;
1011       else if (prop.name == "hascontent" && prop.num_params())
1012       {
1013         CStdString cat = prop.param(0);
1014         StringUtils::ToLower(cat);
1015         if (cat == "music") return LIBRARY_HAS_MUSIC;
1016         else if (cat == "video") return LIBRARY_HAS_VIDEO;
1017         else if (cat == "movies") return LIBRARY_HAS_MOVIES;
1018         else if (cat == "tvshows") return LIBRARY_HAS_TVSHOWS;
1019         else if (cat == "musicvideos") return LIBRARY_HAS_MUSICVIDEOS;
1020         else if (cat == "moviesets") return LIBRARY_HAS_MOVIE_SETS;
1021       }
1022     }
1023     else if (cat.name == "musicplayer")
1024     {
1025       for (size_t i = 0; i < sizeof(player_times) / sizeof(infomap); i++) // TODO: remove these, they're repeats
1026       {
1027         if (prop.name == player_times[i].str)
1028           return AddMultiInfo(GUIInfo(player_times[i].val, TranslateTimeFormat(prop.param())));
1029       }
1030       if (prop.name == "property")
1031       {
1032         if (prop.param().Equals("fanart_image"))
1033           return AddMultiInfo(GUIInfo(PLAYER_ITEM_ART, ConditionalStringParameter("fanart")));
1034         return AddListItemProp(prop.param(), MUSICPLAYER_PROPERTY_OFFSET);
1035       }
1036       return TranslateMusicPlayerString(prop.name);
1037     }
1038     else if (cat.name == "videoplayer")
1039     {
1040       for (size_t i = 0; i < sizeof(player_times) / sizeof(infomap); i++) // TODO: remove these, they're repeats
1041       {
1042         if (prop.name == player_times[i].str)
1043           return AddMultiInfo(GUIInfo(player_times[i].val, TranslateTimeFormat(prop.param())));
1044       }
1045       if (prop.name == "content" && prop.num_params())
1046         return AddMultiInfo(GUIInfo(VIDEOPLAYER_CONTENT, ConditionalStringParameter(prop.param()), 0));
1047       for (size_t i = 0; i < sizeof(videoplayer) / sizeof(infomap); i++)
1048       {
1049         if (prop.name == videoplayer[i].str)
1050           return videoplayer[i].val;
1051       }
1052     }
1053     else if (cat.name == "slideshow")
1054     {
1055       for (size_t i = 0; i < sizeof(slideshow) / sizeof(infomap); i++)
1056       {
1057         if (prop.name == slideshow[i].str)
1058           return slideshow[i].val;
1059       }
1060       return CPictureInfoTag::TranslateString(prop.name);
1061     }
1062     else if (cat.name == "container")
1063     {
1064       for (size_t i = 0; i < sizeof(mediacontainer) / sizeof(infomap); i++) // these ones don't have or need an id
1065       {
1066         if (prop.name == mediacontainer[i].str)
1067           return mediacontainer[i].val;
1068       }
1069       int id = atoi(cat.param().c_str());
1070       for (size_t i = 0; i < sizeof(container_bools) / sizeof(infomap); i++) // these ones can have an id (but don't need to?)
1071       {
1072         if (prop.name == container_bools[i].str)
1073           return id ? AddMultiInfo(GUIInfo(container_bools[i].val, id)) : container_bools[i].val;
1074       }
1075       for (size_t i = 0; i < sizeof(container_ints) / sizeof(infomap); i++) // these ones can have an int param on the property
1076       {
1077         if (prop.name == container_ints[i].str)
1078           return AddMultiInfo(GUIInfo(container_ints[i].val, id, atoi(prop.param().c_str())));
1079       }
1080       for (size_t i = 0; i < sizeof(container_str) / sizeof(infomap); i++) // these ones have a string param on the property
1081       {
1082         if (prop.name == container_str[i].str)
1083           return AddMultiInfo(GUIInfo(container_str[i].val, id, ConditionalStringParameter(prop.param())));
1084       }
1085       if (prop.name == "sortdirection")
1086       {
1087         SortOrder order = SortOrderNone;
1088         if (prop.param().Equals("ascending"))
1089           order = SortOrderAscending;
1090         else if (prop.param().Equals("descending"))
1091           order = SortOrderDescending;
1092         return AddMultiInfo(GUIInfo(CONTAINER_SORT_DIRECTION, order));
1093       }
1094       else if (prop.name == "sort")
1095       {
1096         if (prop.param().Equals("songrating"))
1097           return AddMultiInfo(GUIInfo(CONTAINER_SORT_METHOD, SortByRating));
1098       }
1099     }
1100     else if (cat.name == "listitem")
1101     {
1102       int offset = atoi(cat.param().c_str());
1103       int ret = TranslateListItem(prop);
1104       if (ret)
1105         listItemDependent = true;
1106       if (offset)
1107         return AddMultiInfo(GUIInfo(ret, 0, offset, INFOFLAG_LISTITEM_WRAP));
1108       return ret;
1109     }
1110     else if (cat.name == "listitemposition")
1111     {
1112       int offset = atoi(cat.param().c_str());
1113       int ret = TranslateListItem(prop);
1114       if (ret)
1115         listItemDependent = true;
1116       if (offset)
1117         return AddMultiInfo(GUIInfo(ret, 0, offset, INFOFLAG_LISTITEM_POSITION));
1118       return ret;
1119     }
1120     else if (cat.name == "listitemnowrap")
1121     {
1122       int offset = atoi(cat.param().c_str());
1123       int ret = TranslateListItem(prop);
1124       if (ret)
1125         listItemDependent = true;
1126       if (offset)
1127         return AddMultiInfo(GUIInfo(ret, 0, offset));
1128       return ret;
1129     }
1130     else if (cat.name == "visualisation")
1131     {
1132       for (size_t i = 0; i < sizeof(visualisation) / sizeof(infomap); i++)
1133       {
1134         if (prop.name == visualisation[i].str)
1135           return visualisation[i].val;
1136       }
1137     }
1138     else if (cat.name == "fanart")
1139     {
1140       for (size_t i = 0; i < sizeof(fanart_labels) / sizeof(infomap); i++)
1141       {
1142         if (prop.name == fanart_labels[i].str)
1143           return fanart_labels[i].val;
1144       }
1145     }
1146     else if (cat.name == "skin")
1147     {
1148       for (size_t i = 0; i < sizeof(skin_labels) / sizeof(infomap); i++)
1149       {
1150         if (prop.name == skin_labels[i].str)
1151           return skin_labels[i].val;
1152       }
1153       if (prop.num_params())
1154       {
1155         if (prop.name == "string")
1156         {
1157           if (prop.num_params() == 2)
1158             return AddMultiInfo(GUIInfo(SKIN_STRING, CSkinSettings::Get().TranslateString(prop.param(0)), ConditionalStringParameter(prop.param(1))));
1159           else
1160             return AddMultiInfo(GUIInfo(SKIN_STRING, CSkinSettings::Get().TranslateString(prop.param(0))));
1161         }
1162         if (prop.name == "hassetting")
1163           return AddMultiInfo(GUIInfo(SKIN_BOOL, CSkinSettings::Get().TranslateBool(prop.param(0))));
1164         else if (prop.name == "hastheme")
1165           return AddMultiInfo(GUIInfo(SKIN_HAS_THEME, ConditionalStringParameter(prop.param(0))));
1166       }
1167     }
1168     else if (cat.name == "window")
1169     {
1170       if (prop.name == "property" && prop.num_params() == 1)
1171       { // TODO: this doesn't support foo.xml
1172         int winID = cat.param().empty() ? 0 : CButtonTranslator::TranslateWindow(cat.param());
1173         if (winID != WINDOW_INVALID)
1174           return AddMultiInfo(GUIInfo(WINDOW_PROPERTY, winID, ConditionalStringParameter(prop.param())));
1175       }
1176       for (size_t i = 0; i < sizeof(window_bools) / sizeof(infomap); i++)
1177       {
1178         if (prop.name == window_bools[i].str)
1179         { // TODO: The parameter for these should really be on the first not the second property
1180           if (prop.param().find("xml") != std::string::npos)
1181             return AddMultiInfo(GUIInfo(window_bools[i].val, 0, ConditionalStringParameter(prop.param())));
1182           int winID = prop.param().empty() ? 0 : CButtonTranslator::TranslateWindow(prop.param());
1183           if (winID != WINDOW_INVALID)
1184             return AddMultiInfo(GUIInfo(window_bools[i].val, winID, 0));
1185           return 0;
1186         }
1187       }
1188     }
1189     else if (cat.name == "control")
1190     {
1191       for (size_t i = 0; i < sizeof(control_labels) / sizeof(infomap); i++)
1192       {
1193         if (prop.name == control_labels[i].str)
1194         { // TODO: The parameter for these should really be on the first not the second property
1195           int controlID = atoi(prop.param().c_str());
1196           if (controlID)
1197             return AddMultiInfo(GUIInfo(control_labels[i].val, controlID, 0));
1198           return 0;
1199         }
1200       }
1201     }
1202     else if (cat.name == "controlgroup" && prop.name == "hasfocus")
1203     {
1204       int groupID = atoi(cat.param().c_str());
1205       if (groupID)
1206         return AddMultiInfo(GUIInfo(CONTROL_GROUP_HAS_FOCUS, groupID, atoi(prop.param(0).c_str())));
1207     }
1208     else if (cat.name == "playlist")
1209     {
1210       int ret = -1;
1211       for (size_t i = 0; i < sizeof(playlist) / sizeof(infomap); i++)
1212       {
1213         if (prop.name == playlist[i].str)
1214         {
1215           ret = playlist[i].val;
1216           break;
1217         }
1218       }
1219       if (ret >= 0)
1220       {
1221         if (prop.num_params() <= 0)
1222           return ret;
1223         else
1224         {
1225           int playlistid = PLAYLIST_NONE;
1226           if (prop.param().Equals("video"))
1227             playlistid = PLAYLIST_VIDEO;
1228           else if (prop.param().Equals("music"))
1229             playlistid = PLAYLIST_MUSIC;
1230
1231           if (playlistid > PLAYLIST_NONE)
1232             return AddMultiInfo(GUIInfo(ret, playlistid));
1233         }
1234       }
1235     }
1236     else if (cat.name == "pvr")
1237     {
1238       for (size_t i = 0; i < sizeof(pvr) / sizeof(infomap); i++)
1239       {
1240         if (prop.name == pvr[i].str)
1241           return pvr[i].val;
1242       }
1243     }
1244   }
1245   else if (info.size() == 3 || info.size() == 4)
1246   {
1247     if (info[0].name == "system" && info[1].name == "platform")
1248     { // TODO: replace with a single system.platform
1249       CStdString platform = info[2].name;
1250       if (platform == "linux")
1251       {
1252         if (info.size() == 4)
1253         {
1254           CStdString device = info[3].name;
1255           if (device == "raspberrypi") return SYSTEM_PLATFORM_LINUX_RASPBERRY_PI;
1256         }
1257         else return SYSTEM_PLATFORM_LINUX;
1258       }
1259       else if (platform == "windows") return SYSTEM_PLATFORM_WINDOWS;
1260       else if (platform == "darwin")  return SYSTEM_PLATFORM_DARWIN;
1261       else if (platform == "osx")  return SYSTEM_PLATFORM_DARWIN_OSX;
1262       else if (platform == "ios")  return SYSTEM_PLATFORM_DARWIN_IOS;
1263       else if (platform == "atv2") return SYSTEM_PLATFORM_DARWIN_ATV2;
1264       else if (platform == "android") return SYSTEM_PLATFORM_ANDROID;
1265     }
1266     if (info[0].name == "musicplayer")
1267     { // TODO: these two don't allow duration(foo) and also don't allow more than this number of levels...
1268       if (info[1].name == "position")
1269       {
1270         int position = atoi(info[1].param().c_str());
1271         int value = TranslateMusicPlayerString(info[2].name); // musicplayer.position(foo).bar
1272         return AddMultiInfo(GUIInfo(value, 0, position));
1273       }
1274       else if (info[1].name == "offset")
1275       {
1276         int position = atoi(info[1].param().c_str());
1277         int value = TranslateMusicPlayerString(info[2].name); // musicplayer.offset(foo).bar
1278         return AddMultiInfo(GUIInfo(value, 1, position));
1279       }
1280     }
1281     else if (info[0].name == "container")
1282     {
1283       int id = atoi(info[0].param().c_str());
1284       int offset = atoi(info[1].param().c_str());
1285       if (info[1].name == "listitemnowrap")
1286       {
1287         listItemDependent = true;
1288         return AddMultiInfo(GUIInfo(TranslateListItem(info[2]), id, offset));
1289       }
1290       else if (info[1].name == "listitemposition")
1291       {
1292         listItemDependent = true;
1293         return AddMultiInfo(GUIInfo(TranslateListItem(info[2]), id, offset, INFOFLAG_LISTITEM_POSITION));
1294       }
1295       else if (info[1].name == "listitem")
1296       {
1297         listItemDependent = true;
1298         return AddMultiInfo(GUIInfo(TranslateListItem(info[2]), id, offset, INFOFLAG_LISTITEM_WRAP));
1299       }
1300     }
1301   }
1302
1303   return 0;
1304 }
1305
1306 int CGUIInfoManager::TranslateListItem(const Property &info)
1307 {
1308   for (size_t i = 0; i < sizeof(listitem_labels) / sizeof(infomap); i++) // these ones don't have or need an id
1309   {
1310     if (info.name == listitem_labels[i].str)
1311       return listitem_labels[i].val;
1312   }
1313   if (info.name == "property" && info.num_params() == 1)
1314   {
1315     if (info.param().Equals("fanart_image"))
1316       return AddListItemProp("fanart", LISTITEM_ART_OFFSET);
1317     return AddListItemProp(info.param());
1318   }
1319   if (info.name == "art" && info.num_params() == 1)
1320     return AddListItemProp(info.param(), LISTITEM_ART_OFFSET);
1321   return 0;
1322 }
1323
1324 int CGUIInfoManager::TranslateMusicPlayerString(const CStdString &info) const
1325 {
1326   for (size_t i = 0; i < sizeof(musicplayer) / sizeof(infomap); i++)
1327   {
1328     if (info == musicplayer[i].str)
1329       return musicplayer[i].val;
1330   }
1331   return 0;
1332 }
1333
1334 TIME_FORMAT CGUIInfoManager::TranslateTimeFormat(const CStdString &format)
1335 {
1336   if (format.empty()) return TIME_FORMAT_GUESS;
1337   else if (format.Equals("hh")) return TIME_FORMAT_HH;
1338   else if (format.Equals("mm")) return TIME_FORMAT_MM;
1339   else if (format.Equals("ss")) return TIME_FORMAT_SS;
1340   else if (format.Equals("hh:mm")) return TIME_FORMAT_HH_MM;
1341   else if (format.Equals("mm:ss")) return TIME_FORMAT_MM_SS;
1342   else if (format.Equals("hh:mm:ss")) return TIME_FORMAT_HH_MM_SS;
1343   else if (format.Equals("hh:mm:ss xx")) return TIME_FORMAT_HH_MM_SS_XX;
1344   else if (format.Equals("h")) return TIME_FORMAT_H;
1345   else if (format.Equals("h:mm:ss")) return TIME_FORMAT_H_MM_SS;
1346   else if (format.Equals("h:mm:ss xx")) return TIME_FORMAT_H_MM_SS_XX;
1347   else if (format.Equals("xx")) return TIME_FORMAT_XX;
1348   return TIME_FORMAT_GUESS;
1349 }
1350
1351 CStdString CGUIInfoManager::GetLabel(int info, int contextWindow, CStdString *fallback)
1352 {
1353   if (info >= CONDITIONAL_LABEL_START && info <= CONDITIONAL_LABEL_END)
1354     return GetSkinVariableString(info, false);
1355
1356   CStdString strLabel;
1357   if (info >= MULTI_INFO_START && info <= MULTI_INFO_END)
1358     return GetMultiInfoLabel(m_multiInfo[info - MULTI_INFO_START], contextWindow);
1359
1360   if (info >= SLIDE_INFO_START && info <= SLIDE_INFO_END)
1361     return GetPictureLabel(info);
1362
1363   if (info >= LISTITEM_PROPERTY_START+MUSICPLAYER_PROPERTY_OFFSET &&
1364       info - (LISTITEM_PROPERTY_START+MUSICPLAYER_PROPERTY_OFFSET) < (int)m_listitemProperties.size())
1365   { // grab the property
1366     if (!m_currentFile)
1367       return "";
1368
1369     CStdString property = m_listitemProperties[info - LISTITEM_PROPERTY_START-MUSICPLAYER_PROPERTY_OFFSET];
1370     return m_currentFile->GetProperty(property).asString();
1371   }
1372
1373   if (info >= LISTITEM_START && info <= LISTITEM_END)
1374   {
1375     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_HAS_LIST_ITEMS); // true for has list items
1376     if (window)
1377     {
1378       CFileItemPtr item = window->GetCurrentListItem();
1379       strLabel = GetItemLabel(item.get(), info, fallback);
1380     }
1381
1382     return strLabel;
1383   }
1384
1385   switch (info)
1386   {
1387   case PVR_NEXT_RECORDING_CHANNEL:
1388   case PVR_NEXT_RECORDING_CHAN_ICO:
1389   case PVR_NEXT_RECORDING_DATETIME:
1390   case PVR_NEXT_RECORDING_TITLE:
1391   case PVR_NOW_RECORDING_CHANNEL:
1392   case PVR_NOW_RECORDING_CHAN_ICO:
1393   case PVR_NOW_RECORDING_DATETIME:
1394   case PVR_NOW_RECORDING_TITLE:
1395   case PVR_BACKEND_NAME:
1396   case PVR_BACKEND_VERSION:
1397   case PVR_BACKEND_HOST:
1398   case PVR_BACKEND_DISKSPACE:
1399   case PVR_BACKEND_CHANNELS:
1400   case PVR_BACKEND_TIMERS:
1401   case PVR_BACKEND_RECORDINGS:
1402   case PVR_BACKEND_NUMBER:
1403   case PVR_TOTAL_DISKSPACE:
1404   case PVR_NEXT_TIMER:
1405   case PVR_PLAYING_DURATION:
1406   case PVR_PLAYING_TIME:
1407   case PVR_PLAYING_PROGRESS:
1408   case PVR_ACTUAL_STREAM_CLIENT:
1409   case PVR_ACTUAL_STREAM_DEVICE:
1410   case PVR_ACTUAL_STREAM_STATUS:
1411   case PVR_ACTUAL_STREAM_SIG:
1412   case PVR_ACTUAL_STREAM_SNR:
1413   case PVR_ACTUAL_STREAM_SIG_PROGR:
1414   case PVR_ACTUAL_STREAM_SNR_PROGR:
1415   case PVR_ACTUAL_STREAM_BER:
1416   case PVR_ACTUAL_STREAM_UNC:
1417   case PVR_ACTUAL_STREAM_VIDEO_BR:
1418   case PVR_ACTUAL_STREAM_AUDIO_BR:
1419   case PVR_ACTUAL_STREAM_DOLBY_BR:
1420   case PVR_ACTUAL_STREAM_CRYPTION:
1421   case PVR_ACTUAL_STREAM_SERVICE:
1422   case PVR_ACTUAL_STREAM_MUX:
1423   case PVR_ACTUAL_STREAM_PROVIDER:
1424     g_PVRManager.TranslateCharInfo(info, strLabel);
1425     break;
1426   case WEATHER_CONDITIONS:
1427     strLabel = g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_COND);
1428     StringUtils::Trim(strLabel);
1429     break;
1430   case WEATHER_TEMPERATURE:
1431     strLabel = StringUtils::Format("%s%s",
1432                                    g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_TEMP).c_str(),
1433                                    g_langInfo.GetTempUnitString().c_str());
1434     break;
1435   case WEATHER_LOCATION:
1436     strLabel = g_weatherManager.GetInfo(WEATHER_LABEL_LOCATION);
1437     break;
1438   case WEATHER_FANART_CODE:
1439     strLabel = URIUtils::GetFileName(g_weatherManager.GetInfo(WEATHER_IMAGE_CURRENT_ICON));
1440     URIUtils::RemoveExtension(strLabel);
1441     break;
1442   case WEATHER_PLUGIN:
1443     strLabel = CSettings::Get().GetString("weather.addon");
1444     break;
1445   case SYSTEM_DATE:
1446     strLabel = GetDate();
1447     break;
1448   case SYSTEM_FPS:
1449     strLabel = StringUtils::Format("%02.2f", m_fps);
1450     break;
1451   case PLAYER_VOLUME:
1452     strLabel = StringUtils::Format("%2.1f dB", CAEUtil::PercentToGain(g_application.GetVolume(false)));
1453     break;
1454   case PLAYER_SUBTITLE_DELAY:
1455     strLabel = StringUtils::Format("%2.3f s", CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleDelay);
1456     break;
1457   case PLAYER_AUDIO_DELAY:
1458     strLabel = StringUtils::Format("%2.3f s", CMediaSettings::Get().GetCurrentVideoSettings().m_AudioDelay);
1459     break;
1460   case PLAYER_CHAPTER:
1461     if(g_application.m_pPlayer->IsPlaying())
1462       strLabel = StringUtils::Format("%02d", g_application.m_pPlayer->GetChapter());
1463     break;
1464   case PLAYER_CHAPTERCOUNT:
1465     if(g_application.m_pPlayer->IsPlaying())
1466       strLabel = StringUtils::Format("%02d", g_application.m_pPlayer->GetChapterCount());
1467     break;
1468   case PLAYER_CHAPTERNAME:
1469     if(g_application.m_pPlayer->IsPlaying())
1470       g_application.m_pPlayer->GetChapterName(strLabel);
1471     break;
1472   case PLAYER_CACHELEVEL:
1473     {
1474       int iLevel = 0;
1475       if(g_application.m_pPlayer->IsPlaying() && GetInt(iLevel, PLAYER_CACHELEVEL) && iLevel >= 0)
1476         strLabel = StringUtils::Format("%i", iLevel);
1477     }
1478     break;
1479   case PLAYER_TIME:
1480     if(g_application.m_pPlayer->IsPlaying())
1481       strLabel = GetCurrentPlayTime(TIME_FORMAT_HH_MM);
1482     break;
1483   case PLAYER_DURATION:
1484     if(g_application.m_pPlayer->IsPlaying())
1485       strLabel = GetDuration(TIME_FORMAT_HH_MM);
1486     break;
1487   case PLAYER_PATH:
1488   case PLAYER_FILENAME:
1489   case PLAYER_FILEPATH:
1490     if (m_currentFile)
1491     {
1492       if (m_currentFile->HasMusicInfoTag())
1493         strLabel = m_currentFile->GetMusicInfoTag()->GetURL();
1494       else if (m_currentFile->HasVideoInfoTag())
1495         strLabel = m_currentFile->GetVideoInfoTag()->m_strFileNameAndPath;
1496       if (strLabel.empty())
1497         strLabel = m_currentFile->GetPath();
1498     }
1499     if (info == PLAYER_PATH)
1500     {
1501       // do this twice since we want the path outside the archive if this
1502       // is to be of use.
1503       if (URIUtils::IsInArchive(strLabel))
1504         strLabel = URIUtils::GetParentPath(strLabel);
1505       strLabel = URIUtils::GetParentPath(strLabel);
1506     }
1507     else if (info == PLAYER_FILENAME)
1508       strLabel = URIUtils::GetFileName(strLabel);
1509     break;
1510   case PLAYER_TITLE:
1511     {
1512       if(m_currentFile)
1513       {
1514         if (m_currentFile->HasPVRChannelInfoTag())
1515         {
1516           CEpgInfoTag tag;
1517           return m_currentFile->GetPVRChannelInfoTag()->GetEPGNow(tag) ?
1518                    tag.Title() :
1519                    CSettings::Get().GetBool("epg.hidenoinfoavailable") ?
1520                      StringUtils::EmptyString :
1521                      g_localizeStrings.Get(19055); // no information available
1522         }
1523         if (m_currentFile->HasPVRRecordingInfoTag() && !m_currentFile->GetPVRRecordingInfoTag()->m_strTitle.empty())
1524           return m_currentFile->GetPVRRecordingInfoTag()->m_strTitle;
1525         if (m_currentFile->HasVideoInfoTag() && !m_currentFile->GetVideoInfoTag()->m_strTitle.empty())
1526           return m_currentFile->GetVideoInfoTag()->m_strTitle;
1527         if (m_currentFile->HasMusicInfoTag() && !m_currentFile->GetMusicInfoTag()->GetTitle().empty())
1528           return m_currentFile->GetMusicInfoTag()->GetTitle();
1529         // don't have the title, so use dvdplayer, label, or drop down to title from path
1530         if (!g_application.m_pPlayer->GetPlayingTitle().empty())
1531           return g_application.m_pPlayer->GetPlayingTitle();
1532         if (!m_currentFile->GetLabel().empty())
1533           return m_currentFile->GetLabel();
1534         return CUtil::GetTitleFromPath(m_currentFile->GetPath());
1535       }
1536       else
1537       {
1538         if (!g_application.m_pPlayer->GetPlayingTitle().empty())
1539           return g_application.m_pPlayer->GetPlayingTitle();
1540       }
1541     }
1542     break;
1543   case MUSICPLAYER_TITLE:
1544   case MUSICPLAYER_ALBUM:
1545   case MUSICPLAYER_ARTIST:
1546   case MUSICPLAYER_ALBUM_ARTIST:
1547   case MUSICPLAYER_GENRE:
1548   case MUSICPLAYER_YEAR:
1549   case MUSICPLAYER_TRACK_NUMBER:
1550   case MUSICPLAYER_BITRATE:
1551   case MUSICPLAYER_PLAYLISTLEN:
1552   case MUSICPLAYER_PLAYLISTPOS:
1553   case MUSICPLAYER_CHANNELS:
1554   case MUSICPLAYER_BITSPERSAMPLE:
1555   case MUSICPLAYER_SAMPLERATE:
1556   case MUSICPLAYER_CODEC:
1557   case MUSICPLAYER_DISC_NUMBER:
1558   case MUSICPLAYER_RATING:
1559   case MUSICPLAYER_COMMENT:
1560   case MUSICPLAYER_LYRICS:
1561   case MUSICPLAYER_CHANNEL_NAME:
1562   case MUSICPLAYER_CHANNEL_NUMBER:
1563   case MUSICPLAYER_CHANNEL_GROUP:
1564   case MUSICPLAYER_PLAYCOUNT:
1565   case MUSICPLAYER_LASTPLAYED:
1566     strLabel = GetMusicLabel(info);
1567   break;
1568   case VIDEOPLAYER_TITLE:
1569   case VIDEOPLAYER_ORIGINALTITLE:
1570   case VIDEOPLAYER_GENRE:
1571   case VIDEOPLAYER_DIRECTOR:
1572   case VIDEOPLAYER_YEAR:
1573   case VIDEOPLAYER_PLAYLISTLEN:
1574   case VIDEOPLAYER_PLAYLISTPOS:
1575   case VIDEOPLAYER_PLOT:
1576   case VIDEOPLAYER_PLOT_OUTLINE:
1577   case VIDEOPLAYER_EPISODE:
1578   case VIDEOPLAYER_SEASON:
1579   case VIDEOPLAYER_RATING:
1580   case VIDEOPLAYER_RATING_AND_VOTES:
1581   case VIDEOPLAYER_TVSHOW:
1582   case VIDEOPLAYER_PREMIERED:
1583   case VIDEOPLAYER_STUDIO:
1584   case VIDEOPLAYER_COUNTRY:
1585   case VIDEOPLAYER_MPAA:
1586   case VIDEOPLAYER_TOP250:
1587   case VIDEOPLAYER_CAST:
1588   case VIDEOPLAYER_CAST_AND_ROLE:
1589   case VIDEOPLAYER_ARTIST:
1590   case VIDEOPLAYER_ALBUM:
1591   case VIDEOPLAYER_WRITER:
1592   case VIDEOPLAYER_TAGLINE:
1593   case VIDEOPLAYER_TRAILER:
1594   case VIDEOPLAYER_STARTTIME:
1595   case VIDEOPLAYER_ENDTIME:
1596   case VIDEOPLAYER_NEXT_TITLE:
1597   case VIDEOPLAYER_NEXT_GENRE:
1598   case VIDEOPLAYER_NEXT_PLOT:
1599   case VIDEOPLAYER_NEXT_PLOT_OUTLINE:
1600   case VIDEOPLAYER_NEXT_STARTTIME:
1601   case VIDEOPLAYER_NEXT_ENDTIME:
1602   case VIDEOPLAYER_NEXT_DURATION:
1603   case VIDEOPLAYER_CHANNEL_NAME:
1604   case VIDEOPLAYER_CHANNEL_NUMBER:
1605   case VIDEOPLAYER_CHANNEL_GROUP:
1606   case VIDEOPLAYER_PARENTAL_RATING:
1607   case VIDEOPLAYER_PLAYCOUNT:
1608   case VIDEOPLAYER_LASTPLAYED:
1609     strLabel = GetVideoLabel(info);
1610   break;
1611   case VIDEOPLAYER_VIDEO_CODEC:
1612     if(g_application.m_pPlayer->IsPlaying())
1613     {
1614       UpdateAVInfo();
1615       strLabel = m_videoInfo.videoCodecName;
1616     }
1617     break;
1618   case VIDEOPLAYER_VIDEO_RESOLUTION:
1619     if(g_application.m_pPlayer->IsPlaying())
1620     {
1621       UpdateAVInfo();
1622       return CStreamDetails::VideoDimsToResolutionDescription(m_videoInfo.width, m_videoInfo.height);
1623     }
1624     break;
1625   case VIDEOPLAYER_AUDIO_CODEC:
1626     if(g_application.m_pPlayer->IsPlaying())
1627     {
1628       UpdateAVInfo();
1629       strLabel = m_audioInfo.audioCodecName;
1630     }
1631     break;
1632   case VIDEOPLAYER_VIDEO_ASPECT:
1633     if (g_application.m_pPlayer->IsPlaying())
1634     {
1635       UpdateAVInfo();
1636       strLabel = CStreamDetails::VideoAspectToAspectDescription(m_videoInfo.videoAspectRatio);
1637     }
1638     break;
1639   case VIDEOPLAYER_AUDIO_CHANNELS:
1640     if(g_application.m_pPlayer->IsPlaying())
1641     {
1642       UpdateAVInfo();
1643       strLabel = StringUtils::Format("%i", m_audioInfo.channels);
1644     }
1645     break;
1646   case VIDEOPLAYER_AUDIO_LANG:
1647     if(g_application.m_pPlayer->IsPlaying())
1648     {
1649       SPlayerAudioStreamInfo info;
1650       g_application.m_pPlayer->GetAudioStreamInfo(CMediaSettings::Get().GetCurrentVideoSettings().m_AudioStream, info);
1651       strLabel = info.language;
1652     }
1653     break;
1654   case VIDEOPLAYER_STEREOSCOPIC_MODE:
1655     if(g_application.m_pPlayer->IsPlaying())
1656     {
1657       UpdateAVInfo();
1658       strLabel = m_videoInfo.stereoMode;
1659     }
1660     break;
1661   case VIDEOPLAYER_SUBTITLES_LANG:
1662     // use g_settings.m_currentVideoSettings.m_SubtitleOn and g_settings.m_currentVideoSettings.m_SubtitleStream
1663     // instead of g_application.m_pPlayer->GetSubtitleVisible and g_application.m_pPlayer->GetSubtitle()
1664     // because when we switch subtitles there is few frames when weird things happen on subtitles switch with latter:
1665     //  - when we switch from one sub to another, for few frames (time to handle message, close old and open new subs)
1666     //    g_application.m_pPlayer->GetSubtitle() will return last of sub streams (that's how CSelectionStreams::IndexOf work for -1 index)
1667     //  - when we toggle disable/enable subs there will be few frames before message will be handled
1668     if(g_application.m_pPlayer && g_application.m_pPlayer->IsPlaying() && CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleOn)
1669     {
1670       SPlayerSubtitleStreamInfo info;
1671       g_application.m_pPlayer->GetSubtitleStreamInfo(CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleStream, info);
1672       strLabel = info.language;
1673     }
1674     break;
1675   case PLAYLIST_LENGTH:
1676   case PLAYLIST_POSITION:
1677   case PLAYLIST_RANDOM:
1678   case PLAYLIST_REPEAT:
1679     strLabel = GetPlaylistLabel(info);
1680   break;
1681   case MUSICPM_SONGSPLAYED:
1682   case MUSICPM_MATCHINGSONGS:
1683   case MUSICPM_MATCHINGSONGSPICKED:
1684   case MUSICPM_MATCHINGSONGSLEFT:
1685   case MUSICPM_RELAXEDSONGSPICKED:
1686   case MUSICPM_RANDOMSONGSPICKED:
1687     strLabel = GetMusicPartyModeLabel(info);
1688   break;
1689
1690   case SYSTEM_FREE_SPACE:
1691   case SYSTEM_USED_SPACE:
1692   case SYSTEM_TOTAL_SPACE:
1693   case SYSTEM_FREE_SPACE_PERCENT:
1694   case SYSTEM_USED_SPACE_PERCENT:
1695     return g_sysinfo.GetHddSpaceInfo(info);
1696   break;
1697
1698   case SYSTEM_CPU_TEMPERATURE:
1699   case SYSTEM_GPU_TEMPERATURE:
1700   case SYSTEM_FAN_SPEED:
1701   case SYSTEM_CPU_USAGE:
1702     return GetSystemHeatInfo(info);
1703     break;
1704
1705   case SYSTEM_VIDEO_ENCODER_INFO:
1706   case NETWORK_MAC_ADDRESS:
1707   case SYSTEM_KERNEL_VERSION:
1708   case SYSTEM_CPUFREQUENCY:
1709   case SYSTEM_INTERNET_STATE:
1710   case SYSTEM_UPTIME:
1711   case SYSTEM_TOTALUPTIME:
1712   case SYSTEM_BATTERY_LEVEL:
1713     return g_sysinfo.GetInfo(info);
1714     break;
1715
1716   case SYSTEM_SCREEN_RESOLUTION:
1717     if(g_Windowing.IsFullScreen())
1718       strLabel = StringUtils::Format("%ix%i@%.2fHz - %s (%02.2f fps)",
1719         CDisplaySettings::Get().GetCurrentResolutionInfo().iScreenWidth,
1720         CDisplaySettings::Get().GetCurrentResolutionInfo().iScreenHeight,
1721         CDisplaySettings::Get().GetCurrentResolutionInfo().fRefreshRate,
1722         g_localizeStrings.Get(244).c_str(),
1723         GetFPS());
1724     else
1725       strLabel = StringUtils::Format("%ix%i - %s (%02.2f fps)",
1726         CDisplaySettings::Get().GetCurrentResolutionInfo().iScreenWidth,
1727         CDisplaySettings::Get().GetCurrentResolutionInfo().iScreenHeight,
1728         g_localizeStrings.Get(242).c_str(),
1729         GetFPS());
1730     return strLabel;
1731     break;
1732
1733   case CONTAINER_FOLDERPATH:
1734   case CONTAINER_FOLDERNAME:
1735     {
1736       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
1737       if (window)
1738       {
1739         if (info==CONTAINER_FOLDERNAME)
1740           strLabel = ((CGUIMediaWindow*)window)->CurrentDirectory().GetLabel();
1741         else
1742           strLabel = CURL(((CGUIMediaWindow*)window)->CurrentDirectory().GetPath()).GetWithoutUserDetails();
1743       }
1744       break;
1745     }
1746   case CONTAINER_PLUGINNAME:
1747     {
1748       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
1749       if (window)
1750       {
1751         CURL url(((CGUIMediaWindow*)window)->CurrentDirectory().GetPath());
1752         if (url.GetProtocol().Equals("plugin"))
1753         {
1754           strLabel = url.GetFileName();
1755           URIUtils::RemoveSlashAtEnd(strLabel);
1756         }
1757       }
1758       break;
1759     }
1760   case CONTAINER_VIEWMODE:
1761     {
1762       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
1763       if (window)
1764       {
1765         const CGUIControl *control = window->GetControl(window->GetViewContainerID());
1766         if (control && control->IsContainer())
1767           strLabel = ((IGUIContainer *)control)->GetLabel();
1768       }
1769       break;
1770     }
1771   case CONTAINER_SORT_METHOD:
1772     {
1773       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
1774       if (window)
1775       {
1776         const CGUIViewState *viewState = ((CGUIMediaWindow*)window)->GetViewState();
1777         if (viewState)
1778           strLabel = g_localizeStrings.Get(viewState->GetSortMethodLabel());
1779     }
1780     }
1781     break;
1782   case CONTAINER_NUM_PAGES:
1783   case CONTAINER_NUM_ITEMS:
1784   case CONTAINER_CURRENT_PAGE:
1785     return GetMultiInfoLabel(GUIInfo(info), contextWindow);
1786     break;
1787   case CONTAINER_SHOWPLOT:
1788     {
1789       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
1790       if (window)
1791         return ((CGUIMediaWindow *)window)->CurrentDirectory().GetProperty("showplot").asString();
1792     }
1793     break;
1794   case CONTAINER_TOTALTIME:
1795     {
1796       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
1797       if (window)
1798       {
1799         const CFileItemList& items=((CGUIMediaWindow *)window)->CurrentDirectory();
1800         int duration=0;
1801         for (int i=0;i<items.Size();++i)
1802         {
1803           CFileItemPtr item=items.Get(i);
1804           if (item->HasMusicInfoTag())
1805             duration += item->GetMusicInfoTag()->GetDuration();
1806           else if (item->HasVideoInfoTag())
1807             duration += item->GetVideoInfoTag()->m_streamDetails.GetVideoDuration();
1808         }
1809         if (duration > 0)
1810           return StringUtils::SecondsToTimeString(duration);
1811       }
1812     }
1813     break;
1814   case SYSTEM_BUILD_VERSION:
1815     strLabel = GetVersion();
1816     break;
1817   case SYSTEM_BUILD_DATE:
1818     strLabel = GetBuild();
1819     break;
1820   case SYSTEM_FREE_MEMORY:
1821   case SYSTEM_FREE_MEMORY_PERCENT:
1822   case SYSTEM_USED_MEMORY:
1823   case SYSTEM_USED_MEMORY_PERCENT:
1824   case SYSTEM_TOTAL_MEMORY:
1825     {
1826       MEMORYSTATUSEX stat;
1827       stat.dwLength = sizeof(MEMORYSTATUSEX);
1828       GlobalMemoryStatusEx(&stat);
1829       int iMemPercentFree = 100 - ((int)( 100.0f* (stat.ullTotalPhys - stat.ullAvailPhys)/stat.ullTotalPhys + 0.5f ));
1830       int iMemPercentUsed = 100 - iMemPercentFree;
1831
1832       if (info == SYSTEM_FREE_MEMORY)
1833         strLabel = StringUtils::Format("%luMB", (ULONG)(stat.ullAvailPhys/MB));
1834       else if (info == SYSTEM_FREE_MEMORY_PERCENT)
1835         strLabel = StringUtils::Format("%i%%", iMemPercentFree);
1836       else if (info == SYSTEM_USED_MEMORY)
1837         strLabel = StringUtils::Format("%luMB", (ULONG)((stat.ullTotalPhys - stat.ullAvailPhys)/MB));
1838       else if (info == SYSTEM_USED_MEMORY_PERCENT)
1839         strLabel = StringUtils::Format("%i%%", iMemPercentUsed);
1840       else if (info == SYSTEM_TOTAL_MEMORY)
1841         strLabel = StringUtils::Format("%luMB", (ULONG)(stat.ullTotalPhys/MB));
1842     }
1843     break;
1844   case SYSTEM_SCREEN_MODE:
1845     strLabel = g_graphicsContext.GetResInfo().strMode;
1846     break;
1847   case SYSTEM_SCREEN_WIDTH:
1848     strLabel = StringUtils::Format("%i", g_graphicsContext.GetResInfo().iScreenWidth);
1849     break;
1850   case SYSTEM_SCREEN_HEIGHT:
1851     strLabel = StringUtils::Format("%i", g_graphicsContext.GetResInfo().iScreenHeight);
1852     break;
1853   case SYSTEM_CURRENT_WINDOW:
1854     return g_localizeStrings.Get(g_windowManager.GetFocusedWindow());
1855     break;
1856   case SYSTEM_STARTUP_WINDOW:
1857     strLabel = StringUtils::Format("%i", CSettings::Get().GetInt("lookandfeel.startupwindow"));
1858     break;
1859   case SYSTEM_CURRENT_CONTROL:
1860     {
1861       CGUIWindow *window = g_windowManager.GetWindow(g_windowManager.GetFocusedWindow());
1862       if (window)
1863       {
1864         CGUIControl *control = window->GetFocusedControl();
1865         if (control)
1866           strLabel = control->GetDescription();
1867       }
1868     }
1869     break;
1870 #ifdef HAS_DVD_DRIVE
1871   case SYSTEM_DVD_LABEL:
1872     strLabel = g_mediaManager.GetDiskLabel();
1873     break;
1874 #endif
1875   case SYSTEM_ALARM_POS:
1876     if (g_alarmClock.GetRemaining("shutdowntimer") == 0.f)
1877       strLabel = "";
1878     else
1879     {
1880       double fTime = g_alarmClock.GetRemaining("shutdowntimer");
1881       if (fTime > 60.f)
1882         strLabel = StringUtils::Format(g_localizeStrings.Get(13213).c_str(), g_alarmClock.GetRemaining("shutdowntimer")/60.f);
1883       else
1884         strLabel = StringUtils::Format(g_localizeStrings.Get(13214).c_str(), g_alarmClock.GetRemaining("shutdowntimer"));
1885     }
1886     break;
1887   case SYSTEM_PROFILENAME:
1888     strLabel = CProfilesManager::Get().GetCurrentProfile().getName();
1889     break;
1890   case SYSTEM_PROFILECOUNT:
1891     strLabel = StringUtils::Format("%i", CProfilesManager::Get().GetNumberOfProfiles());
1892     break;
1893   case SYSTEM_PROFILEAUTOLOGIN:
1894     {
1895       int profileId = CProfilesManager::Get().GetAutoLoginProfileId();
1896       if ((profileId < 0) || (!CProfilesManager::Get().GetProfileName(profileId, strLabel)))
1897         strLabel = g_localizeStrings.Get(37014); // Last used profile
1898     }
1899     break;
1900   case SYSTEM_LANGUAGE:
1901     strLabel = CSettings::Get().GetString("locale.language");
1902     break;
1903   case SYSTEM_TEMPERATURE_UNITS:
1904     strLabel = g_langInfo.GetTempUnitString();
1905     break;
1906   case SYSTEM_PROGRESS_BAR:
1907     {
1908       int percent;
1909       if (GetInt(percent, SYSTEM_PROGRESS_BAR) && percent > 0)
1910         strLabel = StringUtils::Format("%i", percent);
1911     }
1912     break;
1913   case SYSTEM_FRIENDLY_NAME:
1914     {
1915       CStdString friendlyName = CSettings::Get().GetString("services.devicename");
1916       if (friendlyName.Equals("XBMC"))
1917         strLabel = StringUtils::Format("%s (%s)", friendlyName.c_str(), g_application.getNetwork().GetHostName().c_str());
1918       else
1919         strLabel = friendlyName;
1920     }
1921     break;
1922   case SYSTEM_STEREOSCOPIC_MODE:
1923     {
1924       int stereoMode = CSettings::Get().GetInt("videoscreen.stereoscopicmode");
1925       strLabel = StringUtils::Format("%i", stereoMode);
1926     }
1927     break;
1928
1929   case SKIN_THEME:
1930     strLabel = CSettings::Get().GetString("lookandfeel.skintheme");
1931     break;
1932   case SKIN_COLOUR_THEME:
1933     strLabel = CSettings::Get().GetString("lookandfeel.skincolors");
1934     break;
1935   case SKIN_ASPECT_RATIO:
1936     if (g_SkinInfo)
1937       strLabel = g_SkinInfo->GetCurrentAspect();
1938     break;
1939   case NETWORK_IP_ADDRESS:
1940     {
1941       CNetworkInterface* iface = g_application.getNetwork().GetFirstConnectedInterface();
1942       if (iface)
1943         return iface->GetCurrentIPAddress();
1944     }
1945     break;
1946   case NETWORK_SUBNET_MASK:
1947     {
1948       CNetworkInterface* iface = g_application.getNetwork().GetFirstConnectedInterface();
1949       if (iface)
1950         return iface->GetCurrentNetmask();
1951     }
1952     break;
1953   case NETWORK_GATEWAY_ADDRESS:
1954     {
1955       CNetworkInterface* iface = g_application.getNetwork().GetFirstConnectedInterface();
1956       if (iface)
1957         return iface->GetCurrentDefaultGateway();
1958     }
1959     break;
1960   case NETWORK_DNS1_ADDRESS:
1961     {
1962       vector<CStdString> nss = g_application.getNetwork().GetNameServers();
1963       if (nss.size() >= 1)
1964         return nss[0];
1965     }
1966     break;
1967   case NETWORK_DNS2_ADDRESS:
1968     {
1969       vector<CStdString> nss = g_application.getNetwork().GetNameServers();
1970       if (nss.size() >= 2)
1971         return nss[1];
1972     }
1973     break;
1974   case NETWORK_DHCP_ADDRESS:
1975     {
1976       CStdString dhcpserver;
1977       return dhcpserver;
1978     }
1979     break;
1980   case NETWORK_LINK_STATE:
1981     {
1982       CStdString linkStatus = g_localizeStrings.Get(151);
1983       linkStatus += " ";
1984       CNetworkInterface* iface = g_application.getNetwork().GetFirstConnectedInterface();
1985       if (iface && iface->IsConnected())
1986         linkStatus += g_localizeStrings.Get(15207);
1987       else
1988         linkStatus += g_localizeStrings.Get(15208);
1989       return linkStatus;
1990     }
1991     break;
1992
1993   case VISUALISATION_PRESET:
1994     {
1995       CGUIMessage msg(GUI_MSG_GET_VISUALISATION, 0, 0);
1996       g_windowManager.SendMessage(msg);
1997       if (msg.GetPointer())
1998       {
1999         CVisualisation* viz = NULL;
2000         viz = (CVisualisation*)msg.GetPointer();
2001         if (viz)
2002         {
2003           strLabel = viz->GetPresetName();
2004           URIUtils::RemoveExtension(strLabel);
2005         }
2006       }
2007     }
2008     break;
2009   case VISUALISATION_NAME:
2010     {
2011       AddonPtr addon;
2012       strLabel = CSettings::Get().GetString("musicplayer.visualisation");
2013       if (CAddonMgr::Get().GetAddon(strLabel,addon) && addon)
2014         strLabel = addon->Name();
2015     }
2016     break;
2017   case FANART_COLOR1:
2018     {
2019       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2020       if (window)
2021         return ((CGUIMediaWindow *)window)->CurrentDirectory().GetProperty("fanart_color1").asString();
2022     }
2023     break;
2024   case FANART_COLOR2:
2025     {
2026       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2027       if (window)
2028         return ((CGUIMediaWindow *)window)->CurrentDirectory().GetProperty("fanart_color2").asString();
2029     }
2030     break;
2031   case FANART_COLOR3:
2032     {
2033       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2034       if (window)
2035         return ((CGUIMediaWindow *)window)->CurrentDirectory().GetProperty("fanart_color3").asString();
2036     }
2037     break;
2038   case FANART_IMAGE:
2039     {
2040       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2041       if (window)
2042         return ((CGUIMediaWindow *)window)->CurrentDirectory().GetArt("fanart");
2043     }
2044     break;
2045   case SYSTEM_RENDER_VENDOR:
2046     strLabel = g_Windowing.GetRenderVendor();
2047     break;
2048   case SYSTEM_RENDER_RENDERER:
2049     strLabel = g_Windowing.GetRenderRenderer();
2050     break;
2051   case SYSTEM_RENDER_VERSION:
2052     strLabel = g_Windowing.GetRenderVersionString();
2053     break;
2054   }
2055
2056   return strLabel;
2057 }
2058
2059 // tries to get a integer value for use in progressbars/sliders and such
2060 bool CGUIInfoManager::GetInt(int &value, int info, int contextWindow, const CGUIListItem *item /* = NULL */) const
2061 {
2062   if (info >= MULTI_INFO_START && info <= MULTI_INFO_END)
2063     return GetMultiInfoInt(value, m_multiInfo[info - MULTI_INFO_START], contextWindow);
2064
2065   if (info >= LISTITEM_START && info <= LISTITEM_END)
2066     return GetItemInt(value, item, info);
2067
2068   value = 0;
2069   switch( info )
2070   {
2071     case PLAYER_VOLUME:
2072       value = (int)g_application.GetVolume();
2073       return true;
2074     case PLAYER_SUBTITLE_DELAY:
2075       value = g_application.GetSubtitleDelay();
2076       return true;
2077     case PLAYER_AUDIO_DELAY:
2078       value = g_application.GetAudioDelay();
2079       return true;
2080     case PLAYER_PROGRESS:
2081     case PLAYER_PROGRESS_CACHE:
2082     case PLAYER_SEEKBAR:
2083     case PLAYER_CACHELEVEL:
2084     case PLAYER_CHAPTER:
2085     case PLAYER_CHAPTERCOUNT:
2086       {
2087         if( g_application.m_pPlayer->IsPlaying())
2088         {
2089           switch( info )
2090           {
2091           case PLAYER_PROGRESS:
2092             value = (int)(g_application.GetPercentage());
2093             break;
2094           case PLAYER_PROGRESS_CACHE:
2095             value = (int)(g_application.GetCachePercentage());
2096             break;
2097           case PLAYER_SEEKBAR:
2098             value = (int)g_application.GetSeekHandler()->GetPercent();
2099             break;
2100           case PLAYER_CACHELEVEL:
2101             value = (int)(g_application.m_pPlayer->GetCacheLevel());
2102             break;
2103           case PLAYER_CHAPTER:
2104             value = g_application.m_pPlayer->GetChapter();
2105             break;
2106           case PLAYER_CHAPTERCOUNT:
2107             value = g_application.m_pPlayer->GetChapterCount();
2108             break;
2109           }
2110         }
2111       }
2112       return true;
2113     case SYSTEM_FREE_MEMORY:
2114     case SYSTEM_USED_MEMORY:
2115       {
2116         MEMORYSTATUSEX stat;
2117         stat.dwLength = sizeof(MEMORYSTATUSEX);
2118         GlobalMemoryStatusEx(&stat);
2119         int memPercentUsed = (int)( 100.0f* (stat.ullTotalPhys - stat.ullAvailPhys)/stat.ullTotalPhys + 0.5f );
2120         if (info == SYSTEM_FREE_MEMORY)
2121           value = 100 - memPercentUsed;
2122         else
2123           value = memPercentUsed;
2124         return true;
2125       }
2126     case SYSTEM_PROGRESS_BAR:
2127       {
2128         CGUIDialogProgress *bar = (CGUIDialogProgress *)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
2129         if (bar && bar->IsDialogRunning())
2130           value = bar->GetPercentage();
2131         return true;
2132       }
2133     case SYSTEM_FREE_SPACE:
2134     case SYSTEM_USED_SPACE:
2135       {
2136         g_sysinfo.GetHddSpaceInfo(value, info, true);
2137         return true;
2138       }
2139     case SYSTEM_CPU_USAGE:
2140       value = g_cpuInfo.getUsedPercentage();
2141       return true;
2142     case PVR_PLAYING_PROGRESS:
2143     case PVR_ACTUAL_STREAM_SIG_PROGR:
2144     case PVR_ACTUAL_STREAM_SNR_PROGR:
2145       value = g_PVRManager.TranslateIntInfo(info);
2146       return true;
2147     case SYSTEM_BATTERY_LEVEL:
2148       value = g_powerManager.BatteryLevel();
2149       return true;
2150   }
2151   return false;
2152 }
2153
2154 // functor for comparison InfoPtr's
2155 struct InfoBoolFinder
2156 {
2157   InfoBoolFinder(const std::string &expression, int context) : m_bool(expression, context) {};
2158   bool operator() (const InfoPtr &right) const { return m_bool == *right; };
2159   InfoBool m_bool;
2160 };
2161
2162 INFO::InfoPtr CGUIInfoManager::Register(const CStdString &expression, int context)
2163 {
2164   CStdString condition(CGUIInfoLabel::ReplaceLocalize(expression));
2165   StringUtils::Trim(condition);
2166   StringUtils::ToLower(condition);
2167
2168   if (condition.empty())
2169     return INFO::InfoPtr();
2170
2171   CSingleLock lock(m_critInfo);
2172   // do we have the boolean expression already registered?
2173   vector<InfoPtr>::const_iterator i = find_if(m_bools.begin(), m_bools.end(), InfoBoolFinder(condition, context));
2174   if (i != m_bools.end())
2175     return *i;
2176
2177   if (condition.find_first_of("|+[]!") != condition.npos)
2178     m_bools.push_back(boost::make_shared<InfoExpression>(condition, context));
2179   else
2180     m_bools.push_back(boost::make_shared<InfoSingle>(condition, context));
2181
2182   return m_bools.back();
2183 }
2184
2185 bool CGUIInfoManager::EvaluateBool(const CStdString &expression, int contextWindow)
2186 {
2187   bool result = false;
2188   INFO::InfoPtr info = Register(expression, contextWindow);
2189   if (info)
2190     result = GetBoolValue(info);
2191   return result;
2192 }
2193
2194 bool CGUIInfoManager::GetBoolValue(const INFO::InfoPtr &expression, const CGUIListItem *item)
2195 {
2196   if (expression)
2197     return expression->Get(m_updateTime, item);
2198   return false;
2199 }
2200
2201 // checks the condition and returns it as necessary.  Currently used
2202 // for toggle button controls and visibility of images.
2203 bool CGUIInfoManager::GetBool(int condition1, int contextWindow, const CGUIListItem *item)
2204 {
2205   bool bReturn = false;
2206   int condition = abs(condition1);
2207
2208   if (condition >= LISTITEM_START && condition < LISTITEM_END)
2209   {
2210     if (item)
2211       bReturn = GetItemBool(item, condition);
2212     else
2213     {
2214       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_HAS_LIST_ITEMS); // true for has list items
2215       if (window)
2216       {
2217         CFileItemPtr item = window->GetCurrentListItem();
2218         bReturn = GetItemBool(item.get(), condition);
2219       }
2220     }
2221   }
2222   // Ethernet Link state checking
2223   // Will check if system has a Ethernet Link connection! [Cable in!]
2224   // This can used for the skinner to switch off Network or Inter required functions
2225   else if ( condition == SYSTEM_ALWAYS_TRUE)
2226     bReturn = true;
2227   else if (condition == SYSTEM_ALWAYS_FALSE)
2228     bReturn = false;
2229   else if (condition == SYSTEM_ETHERNET_LINK_ACTIVE)
2230     bReturn = true;
2231   else if (condition == WINDOW_IS_MEDIA)
2232   { // note: This doesn't return true for dialogs (content, favourites, login, videoinfo)
2233     CGUIWindow *pWindow = g_windowManager.GetWindow(g_windowManager.GetActiveWindow());
2234     bReturn = (pWindow && pWindow->IsMediaWindow());
2235   }
2236   else if (condition == PLAYER_MUTED)
2237     bReturn = g_application.IsMuted();
2238   else if (condition >= LIBRARY_HAS_MUSIC && condition <= LIBRARY_HAS_MUSICVIDEOS)
2239     bReturn = GetLibraryBool(condition);
2240   else if (condition == LIBRARY_IS_SCANNING)
2241   {
2242     if (g_application.IsMusicScanning() || g_application.IsVideoScanning())
2243       bReturn = true;
2244     else
2245       bReturn = false;
2246   }
2247   else if (condition == LIBRARY_IS_SCANNING_VIDEO)
2248   {
2249     bReturn = g_application.IsVideoScanning();
2250   }
2251   else if (condition == LIBRARY_IS_SCANNING_MUSIC)
2252   {
2253     bReturn = g_application.IsMusicScanning();
2254   }
2255   else if (condition == SYSTEM_PLATFORM_LINUX)
2256 #if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
2257     bReturn = true;
2258 #else
2259     bReturn = false;
2260 #endif
2261   else if (condition == SYSTEM_PLATFORM_WINDOWS)
2262 #ifdef TARGET_WINDOWS
2263     bReturn = true;
2264 #else
2265     bReturn = false;
2266 #endif
2267   else if (condition == SYSTEM_PLATFORM_DARWIN)
2268 #ifdef TARGET_DARWIN
2269     bReturn = true;
2270 #else
2271     bReturn = false;
2272 #endif
2273   else if (condition == SYSTEM_PLATFORM_DARWIN_OSX)
2274 #ifdef TARGET_DARWIN_OSX
2275     bReturn = true;
2276 #else
2277     bReturn = false;
2278 #endif
2279   else if (condition == SYSTEM_PLATFORM_DARWIN_IOS)
2280 #ifdef TARGET_DARWIN_IOS
2281     bReturn = true;
2282 #else
2283     bReturn = false;
2284 #endif
2285   else if (condition == SYSTEM_PLATFORM_DARWIN_ATV2)
2286 #ifdef TARGET_DARWIN_IOS_ATV2
2287     bReturn = true;
2288 #else
2289     bReturn = false;
2290 #endif
2291   else if (condition == SYSTEM_PLATFORM_ANDROID)
2292 #if defined(TARGET_ANDROID)
2293     bReturn = true;
2294 #else
2295     bReturn = false;
2296 #endif
2297   else if (condition == SYSTEM_PLATFORM_LINUX_RASPBERRY_PI)
2298 #if defined(TARGET_RASPBERRY_PI)
2299     bReturn = true;
2300 #else
2301     bReturn = false;
2302 #endif
2303   else if (condition == SYSTEM_MEDIA_DVD)
2304     bReturn = g_mediaManager.IsDiscInDrive();
2305 #ifdef HAS_DVD_DRIVE
2306   else if (condition == SYSTEM_DVDREADY)
2307     bReturn = g_mediaManager.GetDriveStatus() != DRIVE_NOT_READY;
2308   else if (condition == SYSTEM_TRAYOPEN)
2309     bReturn = g_mediaManager.GetDriveStatus() == DRIVE_OPEN;
2310 #endif
2311   else if (condition == SYSTEM_CAN_POWERDOWN)
2312     bReturn = g_powerManager.CanPowerdown();
2313   else if (condition == SYSTEM_CAN_SUSPEND)
2314     bReturn = g_powerManager.CanSuspend();
2315   else if (condition == SYSTEM_CAN_HIBERNATE)
2316     bReturn = g_powerManager.CanHibernate();
2317   else if (condition == SYSTEM_CAN_REBOOT)
2318     bReturn = g_powerManager.CanReboot();
2319   else if (condition == SYSTEM_SCREENSAVER_ACTIVE)
2320     bReturn = g_application.IsInScreenSaver();
2321
2322   else if (condition == PLAYER_SHOWINFO)
2323     bReturn = m_playerShowInfo;
2324   else if (condition == PLAYER_SHOWCODEC)
2325     bReturn = m_playerShowCodec;
2326   else if (condition >= MULTI_INFO_START && condition <= MULTI_INFO_END)
2327   {
2328     return GetMultiInfoBool(m_multiInfo[condition - MULTI_INFO_START], contextWindow, item);
2329   }
2330   else if (condition == SYSTEM_HASLOCKS)
2331     bReturn = CProfilesManager::Get().GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE;
2332   else if (condition == SYSTEM_HAS_PVR)
2333     bReturn = true;
2334   else if (condition == SYSTEM_ISMASTER)
2335     bReturn = CProfilesManager::Get().GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE && g_passwordManager.bMasterUser;
2336   else if (condition == SYSTEM_ISFULLSCREEN)
2337     bReturn = g_Windowing.IsFullScreen();
2338   else if (condition == SYSTEM_ISSTANDALONE)
2339     bReturn = g_application.IsStandAlone();
2340   else if (condition == SYSTEM_ISINHIBIT)
2341     bReturn = g_application.IsIdleShutdownInhibited();
2342   else if (condition == SYSTEM_HAS_SHUTDOWN)
2343     bReturn = (CSettings::Get().GetInt("powermanagement.shutdowntime") > 0);
2344   else if (condition == SYSTEM_LOGGEDON)
2345     bReturn = !(g_windowManager.GetActiveWindow() == WINDOW_LOGIN_SCREEN);
2346   else if (condition == SYSTEM_SHOW_EXIT_BUTTON)
2347     bReturn = g_advancedSettings.m_showExitButton;
2348   else if (condition == SYSTEM_HAS_LOGINSCREEN)
2349     bReturn = CProfilesManager::Get().UsingLoginScreen();
2350   else if (condition == WEATHER_IS_FETCHED)
2351     bReturn = g_weatherManager.IsFetched();
2352   else if (condition >= PVR_CONDITIONS_START && condition <= PVR_CONDITIONS_END)
2353     bReturn = g_PVRManager.TranslateBoolInfo(condition);
2354
2355   else if (condition == SYSTEM_INTERNET_STATE)
2356   {
2357     g_sysinfo.GetInfo(condition);
2358     bReturn = g_sysinfo.HasInternet();
2359   }
2360   else if (condition == SKIN_HAS_VIDEO_OVERLAY)
2361   {
2362     bReturn = g_windowManager.IsOverlayAllowed() && g_application.m_pPlayer->IsPlayingVideo();
2363   }
2364   else if (condition == SKIN_HAS_MUSIC_OVERLAY)
2365   {
2366     bReturn = g_windowManager.IsOverlayAllowed() && g_application.m_pPlayer->IsPlayingAudio();
2367   }
2368   else if (condition == CONTAINER_HASFILES || condition == CONTAINER_HASFOLDERS)
2369   {
2370     CGUIWindow *pWindow = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2371     if (pWindow)
2372     {
2373       const CFileItemList& items=((CGUIMediaWindow*)pWindow)->CurrentDirectory();
2374       for (int i=0;i<items.Size();++i)
2375       {
2376         CFileItemPtr item=items.Get(i);
2377         if (!item->m_bIsFolder && condition == CONTAINER_HASFILES)
2378         {
2379           bReturn=true;
2380           break;
2381         }
2382         else if (item->m_bIsFolder && !item->IsParentFolder() && condition == CONTAINER_HASFOLDERS)
2383         {
2384           bReturn=true;
2385           break;
2386         }
2387       }
2388     }
2389   }
2390   else if (condition == CONTAINER_STACKED)
2391   {
2392     CGUIWindow *pWindow = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2393     if (pWindow)
2394       bReturn = ((CGUIMediaWindow*)pWindow)->CurrentDirectory().GetProperty("isstacked").asBoolean();
2395   }
2396   else if (condition == CONTAINER_HAS_THUMB)
2397   {
2398     CGUIWindow *pWindow = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2399     if (pWindow)
2400       bReturn = ((CGUIMediaWindow*)pWindow)->CurrentDirectory().HasArt("thumb");
2401   }
2402   else if (condition == CONTAINER_HAS_NEXT || condition == CONTAINER_HAS_PREVIOUS || condition == CONTAINER_SCROLLING)
2403   {
2404     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2405     if (window)
2406     {
2407       const CGUIControl* control = window->GetControl(window->GetViewContainerID());
2408       if (control)
2409         bReturn = control->GetCondition(condition, 0);
2410     }
2411   }
2412   else if (condition == CONTAINER_CAN_FILTER)
2413   {
2414     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2415     if (window)
2416       bReturn = !((CGUIMediaWindow*)window)->CanFilterAdvanced();
2417   }
2418   else if (condition == CONTAINER_CAN_FILTERADVANCED)
2419   {
2420     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2421     if (window)
2422       bReturn = ((CGUIMediaWindow*)window)->CanFilterAdvanced();
2423   }
2424   else if (condition == CONTAINER_FILTERED)
2425   {
2426     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2427     if (window)
2428       bReturn = ((CGUIMediaWindow*)window)->IsFiltered();
2429   }
2430   else if (condition == VIDEOPLAYER_HAS_INFO)
2431     bReturn = ((m_currentFile->HasVideoInfoTag() && !m_currentFile->GetVideoInfoTag()->IsEmpty()) ||
2432                (m_currentFile->HasPVRChannelInfoTag()  && !m_currentFile->GetPVRChannelInfoTag()->IsEmpty()));
2433   else if (condition >= CONTAINER_SCROLL_PREVIOUS && condition <= CONTAINER_SCROLL_NEXT)
2434   {
2435     // no parameters, so we assume it's just requested for a media window.  It therefore
2436     // can only happen if the list has focus.
2437     CGUIWindow *pWindow = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2438     if (pWindow)
2439     {
2440       map<int,int>::const_iterator it = m_containerMoves.find(pWindow->GetViewContainerID());
2441       if (it != m_containerMoves.end())
2442       {
2443         if (condition > CONTAINER_STATIC) // moving up
2444           bReturn = it->second >= std::max(condition - CONTAINER_STATIC, 1);
2445         else
2446           bReturn = it->second <= std::min(condition - CONTAINER_STATIC, -1);
2447       }
2448     }
2449   }
2450   else if (condition == SLIDESHOW_ISPAUSED)
2451   {
2452     CGUIWindowSlideShow *slideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
2453     bReturn = (slideShow && slideShow->IsPaused());
2454   }
2455   else if (condition == SLIDESHOW_ISRANDOM)
2456   {
2457     CGUIWindowSlideShow *slideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
2458     bReturn = (slideShow && slideShow->IsShuffled());
2459   }
2460   else if (condition == SLIDESHOW_ISACTIVE)
2461   {
2462     CGUIWindowSlideShow *slideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
2463     bReturn = (slideShow && slideShow->InSlideShow());
2464   }
2465   else if (condition == SLIDESHOW_ISVIDEO)
2466   {
2467     CGUIWindowSlideShow *slideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
2468     bReturn = (slideShow && slideShow->GetCurrentSlide() && slideShow->GetCurrentSlide()->IsVideo());
2469   }
2470   else if (g_application.m_pPlayer->IsPlaying())
2471   {
2472     switch (condition)
2473     {
2474     case PLAYER_HAS_MEDIA:
2475       bReturn = true;
2476       break;
2477     case PLAYER_HAS_AUDIO:
2478       bReturn = g_application.m_pPlayer->IsPlayingAudio();
2479       break;
2480     case PLAYER_HAS_VIDEO:
2481       bReturn = g_application.m_pPlayer->IsPlayingVideo();
2482       break;
2483     case PLAYER_PLAYING:
2484       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && (g_application.m_pPlayer->GetPlaySpeed() == 1);
2485       break;
2486     case PLAYER_PAUSED:
2487       bReturn = g_application.m_pPlayer->IsPausedPlayback();
2488       break;
2489     case PLAYER_REWINDING:
2490       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() < 1;
2491       break;
2492     case PLAYER_FORWARDING:
2493       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() > 1;
2494       break;
2495     case PLAYER_REWINDING_2x:
2496       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == -2;
2497       break;
2498     case PLAYER_REWINDING_4x:
2499       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == -4;
2500       break;
2501     case PLAYER_REWINDING_8x:
2502       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == -8;
2503       break;
2504     case PLAYER_REWINDING_16x:
2505       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == -16;
2506       break;
2507     case PLAYER_REWINDING_32x:
2508       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == -32;
2509       break;
2510     case PLAYER_FORWARDING_2x:
2511       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == 2;
2512       break;
2513     case PLAYER_FORWARDING_4x:
2514       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == 4;
2515       break;
2516     case PLAYER_FORWARDING_8x:
2517       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == 8;
2518       break;
2519     case PLAYER_FORWARDING_16x:
2520       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == 16;
2521       break;
2522     case PLAYER_FORWARDING_32x:
2523       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == 32;
2524       break;
2525     case PLAYER_CAN_RECORD:
2526       bReturn = g_application.m_pPlayer->CanRecord();
2527       break;
2528     case PLAYER_CAN_PAUSE:
2529       bReturn = g_application.m_pPlayer->CanPause();
2530       break;
2531     case PLAYER_CAN_SEEK:
2532       bReturn = g_application.m_pPlayer->CanSeek();
2533       break;
2534     case PLAYER_RECORDING:
2535       bReturn = g_application.m_pPlayer->IsRecording();
2536     break;
2537     case PLAYER_DISPLAY_AFTER_SEEK:
2538       bReturn = GetDisplayAfterSeek();
2539     break;
2540     case PLAYER_CACHING:
2541       bReturn = g_application.m_pPlayer->IsCaching();
2542     break;
2543     case PLAYER_SEEKBAR:
2544       {
2545         CGUIDialog *seekBar = (CGUIDialog*)g_windowManager.GetWindow(WINDOW_DIALOG_SEEK_BAR);
2546         bReturn = seekBar ? seekBar->IsDialogRunning() : false;
2547       }
2548     break;
2549     case PLAYER_SEEKING:
2550       bReturn = m_playerSeeking;
2551     break;
2552     case PLAYER_SHOWTIME:
2553       bReturn = m_playerShowTime;
2554     break;
2555     case PLAYER_PASSTHROUGH:
2556       bReturn = g_application.m_pPlayer->IsPassthrough();
2557       break;
2558     case PLAYER_ISINTERNETSTREAM:
2559       bReturn = m_currentFile && URIUtils::IsInternetStream(m_currentFile->GetPath());
2560       break;
2561     case MUSICPM_ENABLED:
2562       bReturn = g_partyModeManager.IsEnabled();
2563     break;
2564     case MUSICPLAYER_HASPREVIOUS:
2565       {
2566         // requires current playlist be PLAYLIST_MUSIC
2567         bReturn = false;
2568         if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_MUSIC)
2569           bReturn = (g_playlistPlayer.GetCurrentSong() > 0); // not first song
2570       }
2571       break;
2572     case MUSICPLAYER_HASNEXT:
2573       {
2574         // requires current playlist be PLAYLIST_MUSIC
2575         bReturn = false;
2576         if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_MUSIC)
2577           bReturn = (g_playlistPlayer.GetCurrentSong() < (g_playlistPlayer.GetPlaylist(PLAYLIST_MUSIC).size() - 1)); // not last song
2578       }
2579       break;
2580     case MUSICPLAYER_PLAYLISTPLAYING:
2581       {
2582         bReturn = false;
2583         if (g_application.m_pPlayer->IsPlayingAudio() && g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_MUSIC)
2584           bReturn = true;
2585       }
2586       break;
2587     case VIDEOPLAYER_USING_OVERLAYS:
2588       bReturn = (CSettings::Get().GetInt("videoplayer.rendermethod") == RENDER_OVERLAYS);
2589     break;
2590     case VIDEOPLAYER_ISFULLSCREEN:
2591       bReturn = g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO;
2592     break;
2593     case VIDEOPLAYER_HASMENU:
2594       bReturn = g_application.m_pPlayer->HasMenu();
2595     break;
2596     case PLAYLIST_ISRANDOM:
2597       bReturn = g_playlistPlayer.IsShuffled(g_playlistPlayer.GetCurrentPlaylist());
2598     break;
2599     case PLAYLIST_ISREPEAT:
2600       bReturn = g_playlistPlayer.GetRepeat(g_playlistPlayer.GetCurrentPlaylist()) == PLAYLIST::REPEAT_ALL;
2601     break;
2602     case PLAYLIST_ISREPEATONE:
2603       bReturn = g_playlistPlayer.GetRepeat(g_playlistPlayer.GetCurrentPlaylist()) == PLAYLIST::REPEAT_ONE;
2604     break;
2605     case PLAYER_HASDURATION:
2606       bReturn = g_application.GetTotalTime() > 0;
2607       break;
2608     case VIDEOPLAYER_HASTELETEXT:
2609       if (g_application.m_pPlayer->GetTeletextCache())
2610         bReturn = true;
2611       break;
2612     case VIDEOPLAYER_HASSUBTITLES:
2613       bReturn = g_application.m_pPlayer->GetSubtitleCount() > 0;
2614       break;
2615     case VIDEOPLAYER_SUBTITLESENABLED:
2616       bReturn = g_application.m_pPlayer->GetSubtitleVisible();
2617       break;
2618     case VISUALISATION_LOCKED:
2619       {
2620         CGUIMessage msg(GUI_MSG_GET_VISUALISATION, 0, 0);
2621         g_windowManager.SendMessage(msg);
2622         if (msg.GetPointer())
2623         {
2624           CVisualisation *pVis = (CVisualisation *)msg.GetPointer();
2625           bReturn = pVis->IsLocked();
2626         }
2627       }
2628     break;
2629     case VISUALISATION_ENABLED:
2630       bReturn = !CSettings::Get().GetString("musicplayer.visualisation").empty();
2631     break;
2632     case VIDEOPLAYER_HAS_EPG:
2633       if (m_currentFile->HasPVRChannelInfoTag())
2634       {
2635         CEpgInfoTag epgTag;
2636         bReturn = m_currentFile->GetPVRChannelInfoTag()->GetEPGNow(epgTag);
2637       }
2638     break;
2639     case VIDEOPLAYER_IS_STEREOSCOPIC:
2640       if(g_application.m_pPlayer->IsPlaying())
2641       {
2642         UpdateAVInfo();
2643         bReturn = !m_videoInfo.stereoMode.empty();
2644       }
2645       break;
2646     default: // default, use integer value different from 0 as true
2647       {
2648         int val;
2649         bReturn = GetInt(val, condition) && val != 0;
2650       }
2651     }
2652   }
2653   if (condition1 < 0)
2654     bReturn = !bReturn;
2655   return bReturn;
2656 }
2657
2658 /// \brief Examines the multi information sent and returns true or false accordingly.
2659 bool CGUIInfoManager::GetMultiInfoBool(const GUIInfo &info, int contextWindow, const CGUIListItem *item)
2660 {
2661   bool bReturn = false;
2662   int condition = abs(info.m_info);
2663
2664   if (condition >= LISTITEM_START && condition <= LISTITEM_END)
2665   {
2666     if (!item)
2667     {
2668       CGUIWindow *window = NULL;
2669       int data1 = info.GetData1();
2670       if (!data1) // No container specified, so we lookup the current view container
2671       {
2672         window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_HAS_LIST_ITEMS);
2673         if (window && window->IsMediaWindow())
2674           data1 = ((CGUIMediaWindow*)(window))->GetViewContainerID();
2675       }
2676
2677       if (!window) // If we don't have a window already (from lookup above), get one
2678         window = GetWindowWithCondition(contextWindow, 0);
2679
2680       if (window)
2681       {
2682         const CGUIControl *control = window->GetControl(data1);
2683         if (control && control->IsContainer())
2684           item = ((IGUIContainer *)control)->GetListItem(info.GetData2(), info.GetInfoFlag()).get();
2685       }
2686     }
2687     if (item) // If we got a valid item, do the lookup
2688       bReturn = GetItemBool(item, condition); // Image prioritizes images over labels (in the case of music item ratings for instance)
2689   }
2690   else
2691   {
2692     switch (condition)
2693     {
2694       case SKIN_BOOL:
2695         {
2696           bReturn = CSkinSettings::Get().GetBool(info.GetData1());
2697         }
2698         break;
2699       case SKIN_STRING:
2700         {
2701           if (info.GetData2())
2702             bReturn = StringUtils::EqualsNoCase(CSkinSettings::Get().GetString(info.GetData1()), m_stringParameters[info.GetData2()]);
2703           else
2704             bReturn = !CSkinSettings::Get().GetString(info.GetData1()).empty();
2705         }
2706         break;
2707       case SKIN_HAS_THEME:
2708         {
2709           CStdString theme = CSettings::Get().GetString("lookandfeel.skintheme");
2710           StringUtils::ToLower(theme);
2711           URIUtils::RemoveExtension(theme);
2712           bReturn = theme.Equals(m_stringParameters[info.GetData1()]);
2713         }
2714         break;
2715       case STRING_IS_EMPTY:
2716         // note: Get*Image() falls back to Get*Label(), so this should cover all of them
2717         if (item && item->IsFileItem() && info.GetData1() >= LISTITEM_START && info.GetData1() < LISTITEM_END)
2718           bReturn = GetItemImage((const CFileItem *)item, info.GetData1()).empty();
2719         else
2720           bReturn = GetImage(info.GetData1(), contextWindow).empty();
2721         break;
2722       case STRING_COMPARE:
2723         {
2724           CStdString compare;
2725           if (info.GetData2() < 0) // info labels are stored with negative numbers
2726           {
2727             int info2 = -info.GetData2();
2728             if (item && item->IsFileItem() && info2 >= LISTITEM_START && info2 < LISTITEM_END)
2729               compare = GetItemImage((const CFileItem *)item, info2);
2730             else
2731               compare = GetImage(info2, contextWindow);
2732           }
2733           else if (info.GetData2() < (int)m_stringParameters.size())
2734           { // conditional string
2735             compare = m_stringParameters[info.GetData2()];
2736           }
2737           if (item && item->IsFileItem() && info.GetData1() >= LISTITEM_START && info.GetData1() < LISTITEM_END)
2738             bReturn = GetItemImage((const CFileItem *)item, info.GetData1()).Equals(compare);
2739           else
2740             bReturn = GetImage(info.GetData1(), contextWindow).Equals(compare);
2741         }
2742         break;
2743       case INTEGER_GREATER_THAN:
2744         {
2745           int integer;
2746           if (GetInt(integer, info.GetData1(), contextWindow, item))
2747             bReturn = integer > info.GetData2();
2748           else
2749           {
2750             CStdString value;
2751
2752             if (item && item->IsFileItem() && info.GetData1() >= LISTITEM_START && info.GetData1() < LISTITEM_END)
2753               value = GetItemImage((const CFileItem *)item, info.GetData1());
2754             else
2755               value = GetImage(info.GetData1(), contextWindow);
2756
2757             // Handle the case when a value contains time separator (:). This makes IntegerGreaterThan
2758             // useful for Player.Time* members without adding a separate set of members returning time in seconds
2759             if ( value.find_first_of( ':' ) != value.npos )
2760               bReturn = StringUtils::TimeStringToSeconds( value ) > info.GetData2();
2761             else
2762               bReturn = atoi( value.c_str() ) > info.GetData2();
2763           }
2764         }
2765         break;
2766       case STRING_STR:
2767       case STRING_STR_LEFT:
2768       case STRING_STR_RIGHT:
2769         {
2770           CStdString compare = m_stringParameters[info.GetData2()];
2771           // our compare string is already in lowercase, so lower case our label as well
2772           // as CStdString::Find() is case sensitive
2773           CStdString label;
2774           if (item && item->IsFileItem() && info.GetData1() >= LISTITEM_START && info.GetData1() < LISTITEM_END)
2775           {
2776             label = GetItemImage((const CFileItem *)item, info.GetData1());
2777             StringUtils::ToLower(label);
2778           }
2779           else
2780           {
2781             label = GetImage(info.GetData1(), contextWindow);
2782             StringUtils::ToLower(label);
2783           }
2784           if (condition == STRING_STR_LEFT)
2785             bReturn = StringUtils::StartsWith(label, compare);
2786           else if (condition == STRING_STR_RIGHT)
2787             bReturn = StringUtils::EndsWith(label, compare);
2788           else
2789             bReturn = label.find(compare) != std::string::npos;
2790         }
2791         break;
2792       case SYSTEM_ALARM_LESS_OR_EQUAL:
2793         {
2794           int time = lrint(g_alarmClock.GetRemaining(m_stringParameters[info.GetData1()]));
2795           int timeCompare = atoi(m_stringParameters[info.GetData2()]);
2796           if (time > 0)
2797             bReturn = timeCompare >= time;
2798           else
2799             bReturn = false;
2800         }
2801         break;
2802       case SYSTEM_IDLE_TIME:
2803         bReturn = g_application.GlobalIdleTime() >= (int)info.GetData1();
2804         break;
2805       case CONTROL_GROUP_HAS_FOCUS:
2806         {
2807           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2808           if (window)
2809             bReturn = window->ControlGroupHasFocus(info.GetData1(), info.GetData2());
2810         }
2811         break;
2812       case CONTROL_IS_VISIBLE:
2813         {
2814           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2815           if (window)
2816           {
2817             // Note: This'll only work for unique id's
2818             const CGUIControl *control = window->GetControl(info.GetData1());
2819             if (control)
2820               bReturn = control->IsVisible();
2821           }
2822         }
2823         break;
2824       case CONTROL_IS_ENABLED:
2825         {
2826           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2827           if (window)
2828           {
2829             // Note: This'll only work for unique id's
2830             const CGUIControl *control = window->GetControl(info.GetData1());
2831             if (control)
2832               bReturn = !control->IsDisabled();
2833           }
2834         }
2835         break;
2836       case CONTROL_HAS_FOCUS:
2837         {
2838           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2839           if (window)
2840             bReturn = (window->GetFocusedControlID() == (int)info.GetData1());
2841         }
2842         break;
2843       case WINDOW_NEXT:
2844         if (info.GetData1())
2845           bReturn = ((int)info.GetData1() == m_nextWindowID);
2846         else
2847         {
2848           CGUIWindow *window = g_windowManager.GetWindow(m_nextWindowID);
2849           if (window && URIUtils::GetFileName(window->GetProperty("xmlfile").asString()).Equals(m_stringParameters[info.GetData2()]))
2850             bReturn = true;
2851         }
2852         break;
2853       case WINDOW_PREVIOUS:
2854         if (info.GetData1())
2855           bReturn = ((int)info.GetData1() == m_prevWindowID);
2856         else
2857         {
2858           CGUIWindow *window = g_windowManager.GetWindow(m_prevWindowID);
2859           if (window && URIUtils::GetFileName(window->GetProperty("xmlfile").asString()).Equals(m_stringParameters[info.GetData2()]))
2860             bReturn = true;
2861         }
2862         break;
2863       case WINDOW_IS_VISIBLE:
2864         if (info.GetData1())
2865           bReturn = g_windowManager.IsWindowVisible(info.GetData1());
2866         else
2867           bReturn = g_windowManager.IsWindowVisible(m_stringParameters[info.GetData2()]);
2868         break;
2869       case WINDOW_IS_TOPMOST:
2870         if (info.GetData1())
2871           bReturn = g_windowManager.IsWindowTopMost(info.GetData1());
2872         else
2873           bReturn = g_windowManager.IsWindowTopMost(m_stringParameters[info.GetData2()]);
2874         break;
2875       case WINDOW_IS_ACTIVE:
2876         if (info.GetData1())
2877           bReturn = g_windowManager.IsWindowActive(info.GetData1());
2878         else
2879           bReturn = g_windowManager.IsWindowActive(m_stringParameters[info.GetData2()]);
2880         break;
2881       case SYSTEM_HAS_ALARM:
2882         bReturn = g_alarmClock.HasAlarm(m_stringParameters[info.GetData1()]);
2883         break;
2884       case SYSTEM_GET_BOOL:
2885         bReturn = CSettings::Get().GetBool(m_stringParameters[info.GetData1()]);
2886         break;
2887       case SYSTEM_HAS_CORE_ID:
2888         bReturn = g_cpuInfo.HasCoreId(info.GetData1());
2889         break;
2890       case SYSTEM_SETTING:
2891         {
2892           if ( m_stringParameters[info.GetData1()].Equals("hidewatched") )
2893           {
2894             CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2895             if (window)
2896               bReturn = CMediaSettings::Get().GetWatchedMode(((CGUIMediaWindow *)window)->CurrentDirectory().GetContent()) == WatchedModeUnwatched;
2897           }
2898         }
2899         break;
2900       case SYSTEM_HAS_ADDON:
2901       {
2902         AddonPtr addon;
2903         bReturn = CAddonMgr::Get().GetAddon(m_stringParameters[info.GetData1()],addon) && addon;
2904         break;
2905       }
2906       case CONTAINER_SCROLL_PREVIOUS:
2907       case CONTAINER_MOVE_PREVIOUS:
2908       case CONTAINER_MOVE_NEXT:
2909       case CONTAINER_SCROLL_NEXT:
2910         {
2911           map<int,int>::const_iterator it = m_containerMoves.find(info.GetData1());
2912           if (it != m_containerMoves.end())
2913           {
2914             if (condition > CONTAINER_STATIC) // moving up
2915               bReturn = it->second >= std::max(condition - CONTAINER_STATIC, 1);
2916             else
2917               bReturn = it->second <= std::min(condition - CONTAINER_STATIC, -1);
2918           }
2919         }
2920         break;
2921       case CONTAINER_CONTENT:
2922         {
2923           CStdString content;
2924           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2925           if (window)
2926           {
2927             if (window->GetID() == WINDOW_DIALOG_MUSIC_INFO)
2928               content = ((CGUIDialogMusicInfo *)window)->CurrentDirectory().GetContent();
2929             else if (window->GetID() == WINDOW_DIALOG_VIDEO_INFO)
2930               content = ((CGUIDialogVideoInfo *)window)->CurrentDirectory().GetContent();
2931           }
2932           if (content.empty())
2933           {
2934             window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2935             if (window)
2936               content = ((CGUIMediaWindow *)window)->CurrentDirectory().GetContent();
2937           }
2938           bReturn = m_stringParameters[info.GetData2()].Equals(content);
2939         }
2940         break;
2941       case CONTAINER_ROW:
2942       case CONTAINER_COLUMN:
2943       case CONTAINER_POSITION:
2944       case CONTAINER_HAS_NEXT:
2945       case CONTAINER_HAS_PREVIOUS:
2946       case CONTAINER_SCROLLING:
2947       case CONTAINER_SUBITEM:
2948         {
2949           const CGUIControl *control = NULL;
2950           if (info.GetData1())
2951           { // container specified
2952             CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2953             if (window)
2954               control = window->GetControl(info.GetData1());
2955           }
2956           else
2957           { // no container specified - assume a mediawindow
2958             CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2959             if (window)
2960               control = window->GetControl(window->GetViewContainerID());
2961           }
2962           if (control)
2963             bReturn = control->GetCondition(condition, info.GetData2());
2964         }
2965         break;
2966       case CONTAINER_HAS_FOCUS:
2967         { // grab our container
2968           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2969           if (window)
2970           {
2971             const CGUIControl *control = window->GetControl(info.GetData1());
2972             if (control && control->IsContainer())
2973             {
2974               CFileItemPtr item = boost::static_pointer_cast<CFileItem>(((IGUIContainer *)control)->GetListItem(0));
2975               if (item && item->m_iprogramCount == info.GetData2())  // programcount used to store item id
2976                 bReturn = true;
2977             }
2978           }
2979           break;
2980         }
2981       case VIDEOPLAYER_CONTENT:
2982         {
2983           CStdString strContent="movies";
2984           if (!m_currentFile->HasVideoInfoTag() || m_currentFile->GetVideoInfoTag()->IsEmpty())
2985             strContent = "files";
2986           if (m_currentFile->HasVideoInfoTag() && m_currentFile->GetVideoInfoTag()->m_iSeason > -1) // episode
2987             strContent = "episodes";
2988           if (m_currentFile->HasVideoInfoTag() && !m_currentFile->GetVideoInfoTag()->m_artist.empty())
2989             strContent = "musicvideos";
2990           if (m_currentFile->HasVideoInfoTag() && m_currentFile->GetVideoInfoTag()->m_strStatus == "livetv")
2991             strContent = "livetv";
2992           if (m_currentFile->HasPVRChannelInfoTag())
2993             strContent = "livetv";
2994           bReturn = m_stringParameters[info.GetData1()].Equals(strContent);
2995         }
2996         break;
2997       case CONTAINER_SORT_METHOD:
2998       {
2999         CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
3000         if (window)
3001         {
3002           const CGUIViewState *viewState = ((CGUIMediaWindow*)window)->GetViewState();
3003           if (viewState)
3004             bReturn = ((unsigned int)viewState->GetSortMethod().sortBy == info.GetData1());
3005         }
3006         break;
3007       }
3008       case CONTAINER_SORT_DIRECTION:
3009       {
3010         CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
3011         if (window)
3012         {
3013           const CGUIViewState *viewState = ((CGUIMediaWindow*)window)->GetViewState();
3014           if (viewState)
3015             bReturn = ((unsigned int)viewState->GetDisplaySortOrder() == info.GetData1());
3016         }
3017         break;
3018       }
3019       case SYSTEM_DATE:
3020         {
3021           if (info.GetData2() == -1) // info doesn't contain valid startDate
3022             return false;
3023           CDateTime date = CDateTime::GetCurrentDateTime();
3024           int currentDate = date.GetMonth()*100+date.GetDay();
3025           int startDate = info.GetData1();
3026           int stopDate = info.GetData2();
3027
3028           if (stopDate < startDate)
3029             bReturn = currentDate >= startDate || currentDate < stopDate;
3030           else
3031             bReturn = currentDate >= startDate && currentDate < stopDate;
3032         }
3033         break;
3034       case SYSTEM_TIME:
3035         {
3036           CDateTime time=CDateTime::GetCurrentDateTime();
3037           int currentTime = time.GetMinuteOfDay();
3038           int startTime = info.GetData1();
3039           int stopTime = info.GetData2();
3040
3041           if (stopTime < startTime)
3042             bReturn = currentTime >= startTime || currentTime < stopTime;
3043           else
3044             bReturn = currentTime >= startTime && currentTime < stopTime;
3045         }
3046         break;
3047       case MUSICPLAYER_EXISTS:
3048         {
3049           int index = info.GetData2();
3050           if (info.GetData1() == 1)
3051           { // relative index
3052             if (g_playlistPlayer.GetCurrentPlaylist() != PLAYLIST_MUSIC)
3053             {
3054               bReturn = false;
3055               break;
3056             }
3057             index += g_playlistPlayer.GetCurrentSong();
3058           }
3059           bReturn = (index >= 0 && index < g_playlistPlayer.GetPlaylist(PLAYLIST_MUSIC).size());
3060         }
3061         break;
3062
3063       case PLAYLIST_ISRANDOM:
3064         {
3065           int playlistid = info.GetData1();
3066           if (playlistid > PLAYLIST_NONE)
3067             bReturn = g_playlistPlayer.IsShuffled(playlistid);
3068         }
3069         break;
3070
3071       case PLAYLIST_ISREPEAT:
3072         {
3073           int playlistid = info.GetData1();
3074           if (playlistid > PLAYLIST_NONE)
3075             bReturn = g_playlistPlayer.GetRepeat(playlistid) == PLAYLIST::REPEAT_ALL;
3076         }
3077         break;
3078
3079       case PLAYLIST_ISREPEATONE:
3080         {
3081           int playlistid = info.GetData1();
3082           if (playlistid > PLAYLIST_NONE)
3083             bReturn = g_playlistPlayer.GetRepeat(playlistid) == PLAYLIST::REPEAT_ONE;
3084         }
3085         break;
3086     }
3087   }
3088   return (info.m_info < 0) ? !bReturn : bReturn;
3089 }
3090
3091 bool CGUIInfoManager::GetMultiInfoInt(int &value, const GUIInfo &info, int contextWindow) const
3092 {
3093   if (info.m_info >= LISTITEM_START && info.m_info <= LISTITEM_END)
3094   {
3095     CFileItemPtr item;
3096     CGUIWindow *window = NULL;
3097
3098     int data1 = info.GetData1();
3099     if (!data1) // No container specified, so we lookup the current view container
3100     {
3101       window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_HAS_LIST_ITEMS);
3102       if (window && window->IsMediaWindow())
3103         data1 = ((CGUIMediaWindow*)(window))->GetViewContainerID();
3104     }
3105
3106     if (!window) // If we don't have a window already (from lookup above), get one
3107       window = GetWindowWithCondition(contextWindow, 0);
3108
3109     if (window)
3110     {
3111       const CGUIControl *control = window->GetControl(data1);
3112       if (control && control->IsContainer())
3113         item = boost::static_pointer_cast<CFileItem>(((IGUIContainer *)control)->GetListItem(info.GetData2(), info.GetInfoFlag()));
3114     }
3115
3116     if (item) // If we got a valid item, do the lookup
3117       return GetItemInt(value, item.get(), info.m_info);
3118   }
3119
3120   return 0;
3121 }
3122
3123 /// \brief Examines the multi information sent and returns the string as appropriate
3124 CStdString CGUIInfoManager::GetMultiInfoLabel(const GUIInfo &info, int contextWindow, CStdString *fallback)
3125 {
3126   if (info.m_info == SKIN_STRING)
3127   {
3128     return CSkinSettings::Get().GetString(info.GetData1());
3129   }
3130   else if (info.m_info == SKIN_BOOL)
3131   {
3132     bool bInfo = CSkinSettings::Get().GetBool(info.GetData1());
3133     if (bInfo)
3134       return g_localizeStrings.Get(20122);
3135   }
3136   if (info.m_info >= LISTITEM_START && info.m_info <= LISTITEM_END)
3137   {
3138     CFileItemPtr item;
3139     CGUIWindow *window = NULL;
3140
3141     int data1 = info.GetData1();
3142     if (!data1) // No container specified, so we lookup the current view container
3143     {
3144       window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_HAS_LIST_ITEMS);
3145       if (window && window->IsMediaWindow())
3146         data1 = ((CGUIMediaWindow*)(window))->GetViewContainerID();
3147     }
3148
3149     if (!window) // If we don't have a window already (from lookup above), get one
3150       window = GetWindowWithCondition(contextWindow, 0);
3151
3152     if (window)
3153     {
3154       const CGUIControl *control = window->GetControl(data1);
3155       if (control && control->IsContainer())
3156         item = boost::static_pointer_cast<CFileItem>(((IGUIContainer *)control)->GetListItem(info.GetData2(), info.GetInfoFlag()));
3157     }
3158
3159     if (item) // If we got a valid item, do the lookup
3160       return GetItemImage(item.get(), info.m_info, fallback); // Image prioritizes images over labels (in the case of music item ratings for instance)
3161   }
3162   else if (info.m_info == PLAYER_TIME)
3163   {
3164     return GetCurrentPlayTime((TIME_FORMAT)info.GetData1());
3165   }
3166   else if (info.m_info == PLAYER_TIME_REMAINING)
3167   {
3168     return GetCurrentPlayTimeRemaining((TIME_FORMAT)info.GetData1());
3169   }
3170   else if (info.m_info == PLAYER_FINISH_TIME)
3171   {
3172     CDateTime time;
3173     CEpgInfoTag currentTag;
3174     if (GetEpgInfoTag(currentTag))
3175       time = currentTag.EndAsLocalTime();
3176     else
3177     {
3178       time = CDateTime::GetCurrentDateTime();
3179       time += CDateTimeSpan(0, 0, 0, GetPlayTimeRemaining());
3180     }
3181     return LocalizeTime(time, (TIME_FORMAT)info.GetData1());
3182   }
3183   else if (info.m_info == PLAYER_START_TIME)
3184   {
3185     CDateTime time;
3186     CEpgInfoTag currentTag;
3187     if (GetEpgInfoTag(currentTag))
3188       time = currentTag.StartAsLocalTime();
3189     else
3190     {
3191       time = CDateTime::GetCurrentDateTime();
3192       time -= CDateTimeSpan(0, 0, 0, (int)GetPlayTime());
3193     }
3194     return LocalizeTime(time, (TIME_FORMAT)info.GetData1());
3195   }
3196   else if (info.m_info == PLAYER_TIME_SPEED)
3197   {
3198     CStdString strTime;
3199     if (g_application.m_pPlayer->GetPlaySpeed() != 1)
3200       strTime = StringUtils::Format("%s (%ix)", GetCurrentPlayTime((TIME_FORMAT)info.GetData1()).c_str(), g_application.m_pPlayer->GetPlaySpeed());
3201     else
3202       strTime = GetCurrentPlayTime();
3203     return strTime;
3204   }
3205   else if (info.m_info == PLAYER_DURATION)
3206   {
3207     return GetDuration((TIME_FORMAT)info.GetData1());
3208   }
3209   else if (info.m_info == PLAYER_SEEKTIME)
3210   {
3211     return GetCurrentSeekTime((TIME_FORMAT)info.GetData1());
3212   }
3213   else if (info.m_info == PLAYER_SEEKOFFSET)
3214   {
3215     CStdString seekOffset = StringUtils::SecondsToTimeString(abs(m_seekOffset), (TIME_FORMAT)info.GetData1());
3216     if (m_seekOffset < 0)
3217       return "-" + seekOffset;
3218     if (m_seekOffset > 0)
3219       return "+" + seekOffset;
3220   }
3221   else if (info.m_info == PLAYER_ITEM_ART)
3222   {
3223     return m_currentFile->GetArt(m_stringParameters[info.GetData1()]);
3224   }
3225   else if (info.m_info == SYSTEM_TIME)
3226   {
3227     return GetTime((TIME_FORMAT)info.GetData1());
3228   }
3229   else if (info.m_info == SYSTEM_DATE)
3230   {
3231     CDateTime time=CDateTime::GetCurrentDateTime();
3232     return time.GetAsLocalizedDate(m_stringParameters[info.GetData1()],false);
3233   }
3234   else if (info.m_info == CONTAINER_NUM_PAGES || info.m_info == CONTAINER_CURRENT_PAGE ||
3235            info.m_info == CONTAINER_NUM_ITEMS || info.m_info == CONTAINER_POSITION)
3236   {
3237     const CGUIControl *control = NULL;
3238     if (info.GetData1())
3239     { // container specified
3240       CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
3241       if (window)
3242         control = window->GetControl(info.GetData1());
3243     }
3244     else
3245     { // no container specified - assume a mediawindow
3246       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
3247       if (window)
3248         control = window->GetControl(window->GetViewContainerID());
3249     }
3250     if (control)
3251     {
3252       if (control->IsContainer())
3253         return ((IGUIContainer *)control)->GetLabel(info.m_info);
3254       else if (control->GetControlType() == CGUIControl::GUICONTROL_TEXTBOX)
3255         return ((CGUITextBox *)control)->GetLabel(info.m_info);
3256     }
3257   }
3258   else if (info.m_info == SYSTEM_GET_CORE_USAGE)
3259   {
3260     CStdString strCpu = StringUtils::Format("%4.2f", g_cpuInfo.GetCoreInfo(atoi(m_stringParameters[info.GetData1()].c_str())).m_fPct);
3261     return strCpu;
3262   }
3263   else if (info.m_info >= MUSICPLAYER_TITLE && info.m_info <= MUSICPLAYER_ALBUM_ARTIST)
3264     return GetMusicPlaylistInfo(info);
3265   else if (info.m_info == CONTAINER_PROPERTY)
3266   {
3267     CGUIWindow *window = NULL;
3268     if (info.GetData1())
3269     { // container specified
3270       window = GetWindowWithCondition(contextWindow, 0);
3271     }
3272     else
3273     { // no container specified - assume a mediawindow
3274       window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
3275     }
3276     if (window)
3277       return ((CGUIMediaWindow *)window)->CurrentDirectory().GetProperty(m_stringParameters[info.GetData2()]).asString();
3278   }
3279   else if (info.m_info == CONTROL_GET_LABEL)
3280   {
3281     CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
3282     if (window)
3283     {
3284       const CGUIControl *control = window->GetControl(info.GetData1());
3285       if (control)
3286         return control->GetDescription();
3287     }
3288   }
3289   else if (info.m_info == WINDOW_PROPERTY)
3290   {
3291     CGUIWindow *window = NULL;
3292     if (info.GetData1())
3293     { // window specified
3294       window = g_windowManager.GetWindow(info.GetData1());//GetWindowWithCondition(contextWindow, 0);
3295     }
3296     else
3297     { // no window specified - assume active
3298       window = GetWindowWithCondition(contextWindow, 0);
3299     }
3300
3301     if (window)
3302       return window->GetProperty(m_stringParameters[info.GetData2()]).asString();
3303   }
3304   else if (info.m_info == SYSTEM_ADDON_TITLE ||
3305            info.m_info == SYSTEM_ADDON_ICON ||
3306            info.m_info == SYSTEM_ADDON_VERSION)
3307   {
3308     // This logic does not check/care whether an addon has been disabled/marked as broken,
3309     // it simply retrieves it's name or icon that means if an addon is placed on the home screen it
3310     // will stay there even if it's disabled/marked as broken. This might need to be changed/fixed
3311     // in the future.
3312     AddonPtr addon;
3313     if (info.GetData2() == 0)
3314       CAddonMgr::Get().GetAddon(const_cast<CGUIInfoManager*>(this)->GetLabel(info.GetData1(), contextWindow),addon,ADDON_UNKNOWN,false);
3315     else
3316       CAddonMgr::Get().GetAddon(m_stringParameters[info.GetData1()],addon,ADDON_UNKNOWN,false);
3317     if (addon && info.m_info == SYSTEM_ADDON_TITLE)
3318       return addon->Name();
3319     if (addon && info.m_info == SYSTEM_ADDON_ICON)
3320       return addon->Icon();
3321     if (addon && info.m_info == SYSTEM_ADDON_VERSION)
3322       return addon->Version().c_str();
3323   }
3324   else if (info.m_info == PLAYLIST_LENGTH ||
3325            info.m_info == PLAYLIST_POSITION ||
3326            info.m_info == PLAYLIST_RANDOM ||
3327            info.m_info == PLAYLIST_REPEAT)
3328   {
3329     int playlistid = info.GetData1();
3330     if (playlistid > PLAYLIST_NONE)
3331       return GetPlaylistLabel(info.m_info, playlistid);
3332   }
3333
3334   return StringUtils::EmptyString;
3335 }
3336
3337 /// \brief Obtains the filename of the image to show from whichever subsystem is needed
3338 CStdString CGUIInfoManager::GetImage(int info, int contextWindow, CStdString *fallback)
3339 {
3340   if (info >= CONDITIONAL_LABEL_START && info <= CONDITIONAL_LABEL_END)
3341     return GetSkinVariableString(info, true);
3342
3343   if (info >= MULTI_INFO_START && info <= MULTI_INFO_END)
3344   {
3345     return GetMultiInfoLabel(m_multiInfo[info - MULTI_INFO_START], contextWindow, fallback);
3346   }
3347   else if (info == WEATHER_CONDITIONS)
3348     return g_weatherManager.GetInfo(WEATHER_IMAGE_CURRENT_ICON);
3349   else if (info == SYSTEM_PROFILETHUMB)
3350   {
3351     CStdString thumb = CProfilesManager::Get().GetCurrentProfile().getThumb();
3352     if (thumb.empty())
3353       thumb = "unknown-user.png";
3354     return thumb;
3355   }
3356   else if (info == MUSICPLAYER_COVER)
3357   {
3358     if (!g_application.m_pPlayer->IsPlayingAudio()) return "";
3359     if (fallback)
3360       *fallback = "DefaultAlbumCover.png";
3361     return m_currentFile->HasArt("thumb") ? m_currentFile->GetArt("thumb") : "DefaultAlbumCover.png";
3362   }
3363   else if (info == MUSICPLAYER_RATING)
3364   {
3365     if (!g_application.m_pPlayer->IsPlayingAudio()) return "";
3366     return GetItemImage(m_currentFile, LISTITEM_RATING);
3367   }
3368   else if (info == PLAYER_STAR_RATING)
3369   {
3370     if (!g_application.m_pPlayer->IsPlaying()) return "";
3371     return GetItemImage(m_currentFile, LISTITEM_STAR_RATING);
3372   }
3373   else if (info == VIDEOPLAYER_COVER)
3374   {
3375     if (!g_application.m_pPlayer->IsPlayingVideo()) return "";
3376     if (fallback)
3377       *fallback = "DefaultVideoCover.png";
3378     if(m_currentMovieThumb.empty())
3379       return m_currentFile->HasArt("thumb") ? m_currentFile->GetArt("thumb") : "DefaultVideoCover.png";
3380     else return m_currentMovieThumb;
3381   }
3382   else if (info == CONTAINER_FOLDERTHUMB)
3383   {
3384     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
3385     if (window)
3386       return GetItemImage(&const_cast<CFileItemList&>(((CGUIMediaWindow*)window)->CurrentDirectory()), LISTITEM_THUMB, fallback);
3387   }
3388   else if (info == CONTAINER_TVSHOWTHUMB)
3389   {
3390     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
3391     if (window)
3392       return ((CGUIMediaWindow *)window)->CurrentDirectory().GetArt("tvshow.thumb");
3393   }
3394   else if (info == CONTAINER_SEASONTHUMB)
3395   {
3396     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
3397     if (window)
3398       return ((CGUIMediaWindow *)window)->CurrentDirectory().GetArt("season.thumb");
3399   }
3400   else if (info == LISTITEM_THUMB || info == LISTITEM_ICON || info == LISTITEM_ACTUAL_ICON ||
3401           info == LISTITEM_OVERLAY || info == LISTITEM_RATING || info == LISTITEM_STAR_RATING)
3402   {
3403     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_HAS_LIST_ITEMS);
3404     if (window)
3405     {
3406       CFileItemPtr item = window->GetCurrentListItem();
3407       if (item)
3408         return GetItemImage(item.get(), info, fallback);
3409     }
3410   }
3411   return GetLabel(info, contextWindow, fallback);
3412 }
3413
3414 CStdString CGUIInfoManager::GetDate(bool bNumbersOnly)
3415 {
3416   CDateTime time=CDateTime::GetCurrentDateTime();
3417   return time.GetAsLocalizedDate(!bNumbersOnly);
3418 }
3419
3420 CStdString CGUIInfoManager::GetTime(TIME_FORMAT format) const
3421 {
3422   CDateTime time=CDateTime::GetCurrentDateTime();
3423   return LocalizeTime(time, format);
3424 }
3425
3426 CStdString CGUIInfoManager::LocalizeTime(const CDateTime &time, TIME_FORMAT format) const
3427 {
3428   const CStdString timeFormat = g_langInfo.GetTimeFormat();
3429   bool use12hourclock = timeFormat.find('h') != std::string::npos;
3430   switch (format)
3431   {
3432   case TIME_FORMAT_GUESS:
3433     return time.GetAsLocalizedTime("", false);
3434   case TIME_FORMAT_SS:
3435     return time.GetAsLocalizedTime("ss", true);
3436   case TIME_FORMAT_MM:
3437     return time.GetAsLocalizedTime("mm", true);
3438   case TIME_FORMAT_MM_SS:
3439     return time.GetAsLocalizedTime("mm:ss", true);
3440   case TIME_FORMAT_HH:  // this forces it to a 12 hour clock
3441     return time.GetAsLocalizedTime(use12hourclock ? "h" : "HH", false);
3442   case TIME_FORMAT_HH_MM:
3443     return time.GetAsLocalizedTime(use12hourclock ? "h:mm" : "HH:mm", false);
3444   case TIME_FORMAT_HH_MM_XX:
3445       return time.GetAsLocalizedTime(use12hourclock ? "h:mm xx" : "HH:mm", false);
3446   case TIME_FORMAT_HH_MM_SS:
3447     return time.GetAsLocalizedTime(use12hourclock ? "hh:mm:ss" : "HH:mm:ss", true);
3448   case TIME_FORMAT_HH_MM_SS_XX:
3449     return time.GetAsLocalizedTime(use12hourclock ? "hh:mm:ss xx" : "HH:mm:ss", true);
3450   case TIME_FORMAT_H:
3451     return time.GetAsLocalizedTime("h", false);
3452   case TIME_FORMAT_H_MM_SS:
3453     return time.GetAsLocalizedTime("h:mm:ss", true);
3454   case TIME_FORMAT_H_MM_SS_XX:
3455     return time.GetAsLocalizedTime("h:mm:ss xx", true);
3456   case TIME_FORMAT_XX:
3457     return use12hourclock ? time.GetAsLocalizedTime("xx", false) : "";
3458   default:
3459     break;
3460   }
3461   return time.GetAsLocalizedTime("", false);
3462 }
3463
3464 CStdString CGUIInfoManager::GetDuration(TIME_FORMAT format) const
3465 {
3466   if (g_application.m_pPlayer->IsPlayingAudio() && m_currentFile->HasMusicInfoTag())
3467   {
3468     const CMusicInfoTag& tag = *m_currentFile->GetMusicInfoTag();
3469     if (tag.GetDuration() > 0)
3470       return StringUtils::SecondsToTimeString(tag.GetDuration(), format);
3471   }
3472   if (g_application.m_pPlayer->IsPlayingVideo() && !m_currentMovieDuration.empty())
3473     return m_currentMovieDuration;  // for tuxbox
3474   unsigned int iTotal = (unsigned int)g_application.GetTotalTime();
3475   if (iTotal > 0)
3476     return StringUtils::SecondsToTimeString(iTotal, format);
3477   return "";
3478 }
3479
3480 CStdString CGUIInfoManager::GetMusicPartyModeLabel(int item)
3481 {
3482   // get song counts
3483   if (item >= MUSICPM_SONGSPLAYED && item <= MUSICPM_RANDOMSONGSPICKED)
3484   {
3485     int iSongs = -1;
3486     switch (item)
3487     {
3488     case MUSICPM_SONGSPLAYED:
3489       {
3490         iSongs = g_partyModeManager.GetSongsPlayed();
3491         break;
3492       }
3493     case MUSICPM_MATCHINGSONGS:
3494       {
3495         iSongs = g_partyModeManager.GetMatchingSongs();
3496         break;
3497       }
3498     case MUSICPM_MATCHINGSONGSPICKED:
3499       {
3500         iSongs = g_partyModeManager.GetMatchingSongsPicked();
3501         break;
3502       }
3503     case MUSICPM_MATCHINGSONGSLEFT:
3504       {
3505         iSongs = g_partyModeManager.GetMatchingSongsLeft();
3506         break;
3507       }
3508     case MUSICPM_RELAXEDSONGSPICKED:
3509       {
3510         iSongs = g_partyModeManager.GetRelaxedSongs();
3511         break;
3512       }
3513     case MUSICPM_RANDOMSONGSPICKED:
3514       {
3515         iSongs = g_partyModeManager.GetRandomSongs();
3516         break;
3517       }
3518     }
3519     if (iSongs < 0)
3520       return "";
3521     CStdString strLabel = StringUtils::Format("%i", iSongs);
3522     return strLabel;
3523   }
3524   return "";
3525 }
3526
3527 const CStdString CGUIInfoManager::GetMusicPlaylistInfo(const GUIInfo& info)
3528 {
3529   PLAYLIST::CPlayList& playlist = g_playlistPlayer.GetPlaylist(PLAYLIST_MUSIC);
3530   if (playlist.size() < 1)
3531     return "";
3532   int index = info.GetData2();
3533   if (info.GetData1() == 1)
3534   { // relative index (requires current playlist is PLAYLIST_MUSIC)
3535     if (g_playlistPlayer.GetCurrentPlaylist() != PLAYLIST_MUSIC)
3536       return "";
3537     index = g_playlistPlayer.GetNextSong(index);
3538   }
3539   if (index < 0 || index >= playlist.size())
3540     return "";
3541   CFileItemPtr playlistItem = playlist[index];
3542   if (!playlistItem->GetMusicInfoTag()->Loaded())
3543   {
3544     playlistItem->LoadMusicTag();
3545     playlistItem->GetMusicInfoTag()->SetLoaded();
3546   }
3547   // try to set a thumbnail
3548   if (!playlistItem->HasArt("thumb"))
3549   {
3550     CMusicThumbLoader loader;
3551     loader.LoadItem(playlistItem.get());
3552     // still no thumb? then just the set the default cover
3553     if (!playlistItem->HasArt("thumb"))
3554       playlistItem->SetArt("thumb", "DefaultAlbumCover.png");
3555   }
3556   if (info.m_info == MUSICPLAYER_PLAYLISTPOS)
3557   {
3558     CStdString strPosition = StringUtils::Format("%i", index + 1);
3559     return strPosition;
3560   }
3561   else if (info.m_info == MUSICPLAYER_COVER)
3562     return playlistItem->GetArt("thumb");
3563   return GetMusicTagLabel(info.m_info, playlistItem.get());
3564 }
3565
3566 CStdString CGUIInfoManager::GetPlaylistLabel(int item, int playlistid /* = PLAYLIST_NONE */) const
3567 {
3568   if (playlistid <= PLAYLIST_NONE && !g_application.m_pPlayer->IsPlaying())
3569     return "";
3570
3571   int iPlaylist = playlistid == PLAYLIST_NONE ? g_playlistPlayer.GetCurrentPlaylist() : playlistid;
3572   switch (item)
3573   {
3574   case PLAYLIST_LENGTH:
3575     {
3576       return StringUtils::Format("%i", g_playlistPlayer.GetPlaylist(iPlaylist).size());;
3577     }
3578   case PLAYLIST_POSITION:
3579     {
3580       return StringUtils::Format("%i", g_playlistPlayer.GetCurrentSong() + 1);
3581     }
3582   case PLAYLIST_RANDOM:
3583     {
3584       if (g_playlistPlayer.IsShuffled(iPlaylist))
3585         return g_localizeStrings.Get(590); // 590: Random
3586       else
3587         return g_localizeStrings.Get(591); // 591: Off
3588     }
3589   case PLAYLIST_REPEAT:
3590     {
3591       PLAYLIST::REPEAT_STATE state = g_playlistPlayer.GetRepeat(iPlaylist);
3592       if (state == PLAYLIST::REPEAT_ONE)
3593         return g_localizeStrings.Get(592); // 592: One
3594       else if (state == PLAYLIST::REPEAT_ALL)
3595         return g_localizeStrings.Get(593); // 593: All
3596       else
3597         return g_localizeStrings.Get(594); // 594: Off
3598     }
3599   }
3600   return "";
3601 }
3602
3603 CStdString CGUIInfoManager::GetMusicLabel(int item)
3604 {
3605   if (!g_application.m_pPlayer->IsPlaying() || !m_currentFile->HasMusicInfoTag()) return "";
3606
3607   UpdateAVInfo();
3608   switch (item)
3609   {
3610   case MUSICPLAYER_PLAYLISTLEN:
3611     {
3612       if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_MUSIC)
3613         return GetPlaylistLabel(PLAYLIST_LENGTH);
3614     }
3615     break;
3616   case MUSICPLAYER_PLAYLISTPOS:
3617     {
3618       if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_MUSIC)
3619         return GetPlaylistLabel(PLAYLIST_POSITION);
3620     }
3621     break;
3622   case MUSICPLAYER_BITRATE:
3623     {
3624       CStdString strBitrate = "";
3625       if (m_audioInfo.bitrate > 0)
3626         strBitrate = StringUtils::Format("%i", MathUtils::round_int((double)m_audioInfo.bitrate / 1000.0));
3627       return strBitrate;
3628     }
3629     break;
3630   case MUSICPLAYER_CHANNELS:
3631     {
3632       CStdString strChannels = "";
3633       if (m_audioInfo.channels > 0)
3634       {
3635         strChannels = StringUtils::Format("%i", m_audioInfo.channels);
3636       }
3637       return strChannels;
3638     }
3639     break;
3640   case MUSICPLAYER_BITSPERSAMPLE:
3641     {
3642       CStdString strBitsPerSample = "";
3643       if (m_audioInfo.bitspersample > 0)
3644         strBitsPerSample = StringUtils::Format("%i", m_audioInfo.bitspersample);
3645       return strBitsPerSample;
3646     }
3647     break;
3648   case MUSICPLAYER_SAMPLERATE:
3649     {
3650       CStdString strSampleRate = "";
3651       if (m_audioInfo.samplerate > 0)
3652         strSampleRate = StringUtils::Format("%.5g", ((double)m_audioInfo.samplerate / 1000.0));
3653       return strSampleRate;
3654     }
3655     break;
3656   case MUSICPLAYER_CODEC:
3657     {
3658       return StringUtils::Format("%s", m_audioInfo.audioCodecName.c_str());
3659     }
3660     break;
3661   case MUSICPLAYER_LYRICS:
3662     return GetItemLabel(m_currentFile, AddListItemProp("lyrics"));
3663   }
3664   return GetMusicTagLabel(item, m_currentFile);
3665 }
3666
3667 CStdString CGUIInfoManager::GetMusicTagLabel(int info, const CFileItem *item)
3668 {
3669   if (!item->HasMusicInfoTag()) return "";
3670   const CMusicInfoTag &tag = *item->GetMusicInfoTag();
3671   switch (info)
3672   {
3673   case MUSICPLAYER_TITLE:
3674     if (tag.GetTitle().size()) { return tag.GetTitle(); }
3675     break;
3676   case MUSICPLAYER_ALBUM:
3677     if (tag.GetAlbum().size()) { return tag.GetAlbum(); }
3678     break;
3679   case MUSICPLAYER_ARTIST:
3680     if (tag.GetArtist().size()) { return StringUtils::Join(tag.GetArtist(), g_advancedSettings.m_musicItemSeparator); }
3681     break;
3682   case MUSICPLAYER_ALBUM_ARTIST:
3683     if (tag.GetAlbumArtist().size()) { return StringUtils::Join(tag.GetAlbumArtist(), g_advancedSettings.m_musicItemSeparator); }
3684     break;
3685   case MUSICPLAYER_YEAR:
3686     if (tag.GetYear()) { return tag.GetYearString(); }
3687     break;
3688   case MUSICPLAYER_GENRE:
3689     if (tag.GetGenre().size()) { return StringUtils::Join(tag.GetGenre(), g_advancedSettings.m_musicItemSeparator); }
3690     break;
3691   case MUSICPLAYER_LYRICS:
3692     if (tag.GetLyrics().size()) { return tag.GetLyrics(); }
3693   break;
3694   case MUSICPLAYER_TRACK_NUMBER:
3695     {
3696       CStdString strTrack;
3697       if (tag.Loaded() && tag.GetTrackNumber() > 0)
3698       {
3699         return StringUtils::Format("%02i", tag.GetTrackNumber());
3700       }
3701     }
3702     break;
3703   case MUSICPLAYER_DISC_NUMBER:
3704     return GetItemLabel(item, LISTITEM_DISC_NUMBER);
3705   case MUSICPLAYER_RATING:
3706     return GetItemLabel(item, LISTITEM_RATING);
3707   case MUSICPLAYER_COMMENT:
3708     return GetItemLabel(item, LISTITEM_COMMENT);
3709   case MUSICPLAYER_DURATION:
3710     return GetItemLabel(item, LISTITEM_DURATION);
3711   case MUSICPLAYER_CHANNEL_NAME:
3712     {
3713       CPVRChannel* channeltag = m_currentFile->GetPVRChannelInfoTag();
3714       if (channeltag)
3715         return channeltag->ChannelName();
3716     }
3717     break;
3718   case MUSICPLAYER_CHANNEL_NUMBER:
3719     {
3720       CPVRChannel* channeltag = m_currentFile->GetPVRChannelInfoTag();
3721       if (channeltag)
3722       {
3723         return StringUtils::Format("%i", channeltag->ChannelNumber());
3724       }
3725     }
3726     break;
3727   case MUSICPLAYER_CHANNEL_GROUP:
3728     {
3729       CPVRChannel* channeltag = m_currentFile->GetPVRChannelInfoTag();
3730       if (channeltag && channeltag->IsRadio())
3731         return g_PVRManager.GetPlayingGroup(true)->GroupName();
3732     }
3733     break;
3734   case MUSICPLAYER_PLAYCOUNT:
3735     return GetItemLabel(item, LISTITEM_PLAYCOUNT);
3736   case MUSICPLAYER_LASTPLAYED:
3737     return GetItemLabel(item, LISTITEM_LASTPLAYED);
3738   }
3739   return "";
3740 }
3741
3742 CStdString CGUIInfoManager::GetVideoLabel(int item)
3743 {
3744   if (!g_application.m_pPlayer->IsPlaying())
3745     return "";
3746
3747   if (item == VIDEOPLAYER_TITLE)
3748   {
3749     if(g_application.m_pPlayer->IsPlayingVideo())
3750        return GetLabel(PLAYER_TITLE);
3751   }
3752   else if (item == VIDEOPLAYER_PLAYLISTLEN)
3753   {
3754     if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_VIDEO)
3755       return GetPlaylistLabel(PLAYLIST_LENGTH);
3756   }
3757   else if (item == VIDEOPLAYER_PLAYLISTPOS)
3758   {
3759     if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_VIDEO)
3760       return GetPlaylistLabel(PLAYLIST_POSITION);
3761   }
3762   else if (m_currentFile->HasPVRChannelInfoTag())
3763   {
3764     CPVRChannel* tag = m_currentFile->GetPVRChannelInfoTag();
3765     CEpgInfoTag epgTag;
3766
3767     switch (item)
3768     {
3769     /* Now playing infos */
3770     case VIDEOPLAYER_ORIGINALTITLE:
3771       return tag->GetEPGNow(epgTag) ?
3772           epgTag.Title() :
3773           CSettings::Get().GetBool("epg.hidenoinfoavailable") ?
3774               StringUtils::EmptyString :
3775               g_localizeStrings.Get(19055); // no information available
3776     case VIDEOPLAYER_GENRE:
3777       return tag->GetEPGNow(epgTag) ? StringUtils::Join(epgTag.Genre(), g_advancedSettings.m_videoItemSeparator) : StringUtils::EmptyString;
3778     case VIDEOPLAYER_PLOT:
3779       return tag->GetEPGNow(epgTag) ? epgTag.Plot() : StringUtils::EmptyString;
3780     case VIDEOPLAYER_PLOT_OUTLINE:
3781       return tag->GetEPGNow(epgTag) ? epgTag.PlotOutline() : StringUtils::EmptyString;
3782     case VIDEOPLAYER_STARTTIME:
3783       return tag->GetEPGNow(epgTag) ? epgTag.StartAsLocalTime().GetAsLocalizedTime("", false) : CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
3784     case VIDEOPLAYER_ENDTIME:
3785       return tag->GetEPGNow(epgTag) ? epgTag.EndAsLocalTime().GetAsLocalizedTime("", false) : CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
3786
3787     /* Next playing infos */
3788     case VIDEOPLAYER_NEXT_TITLE:
3789       return tag->GetEPGNext(epgTag) ?
3790           epgTag.Title() :
3791           CSettings::Get().GetBool("epg.hidenoinfoavailable") ?
3792               StringUtils::EmptyString :
3793               g_localizeStrings.Get(19055); // no information available
3794     case VIDEOPLAYER_NEXT_GENRE:
3795       return tag->GetEPGNext(epgTag) ? StringUtils::Join(epgTag.Genre(), g_advancedSettings.m_videoItemSeparator) : StringUtils::EmptyString;
3796     case VIDEOPLAYER_NEXT_PLOT:
3797       return tag->GetEPGNext(epgTag) ? epgTag.Plot() : StringUtils::EmptyString;
3798     case VIDEOPLAYER_NEXT_PLOT_OUTLINE:
3799       return tag->GetEPGNext(epgTag) ? epgTag.PlotOutline() : StringUtils::EmptyString;
3800     case VIDEOPLAYER_NEXT_STARTTIME:
3801       return tag->GetEPGNext(epgTag) ? epgTag.StartAsLocalTime().GetAsLocalizedTime("", false) : CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
3802     case VIDEOPLAYER_NEXT_ENDTIME:
3803       return tag->GetEPGNext(epgTag) ? epgTag.EndAsLocalTime().GetAsLocalizedTime("", false) : CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
3804     case VIDEOPLAYER_NEXT_DURATION:
3805       {
3806         CStdString duration;
3807         if (tag->GetEPGNext(epgTag) && epgTag.GetDuration() > 0)
3808           duration = StringUtils::SecondsToTimeString(epgTag.GetDuration());
3809         return duration;
3810       }
3811
3812     case VIDEOPLAYER_PARENTAL_RATING:
3813       {
3814         CStdString rating;
3815         if (tag->GetEPGNow(epgTag) && epgTag.ParentalRating() > 0)
3816           rating = StringUtils::Format("%i", epgTag.ParentalRating());
3817         return rating;
3818       }
3819       break;
3820
3821     /* General channel infos */
3822     case VIDEOPLAYER_CHANNEL_NAME:
3823       return tag->ChannelName();
3824     case VIDEOPLAYER_CHANNEL_NUMBER:
3825       {
3826         return StringUtils::Format("%i", tag->ChannelNumber());;
3827       }
3828     case VIDEOPLAYER_CHANNEL_GROUP:
3829       {
3830         if (tag && !tag->IsRadio())
3831           return g_PVRManager.GetPlayingGroup(false)->GroupName();
3832       }
3833     }
3834   }
3835   else if (m_currentFile->HasVideoInfoTag())
3836   {
3837     switch (item)
3838     {
3839     case VIDEOPLAYER_ORIGINALTITLE:
3840       return m_currentFile->GetVideoInfoTag()->m_strOriginalTitle;
3841       break;
3842     case VIDEOPLAYER_GENRE:
3843       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_genre, g_advancedSettings.m_videoItemSeparator);
3844       break;
3845     case VIDEOPLAYER_DIRECTOR:
3846       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_director, g_advancedSettings.m_videoItemSeparator);
3847       break;
3848     case VIDEOPLAYER_RATING:
3849       {
3850         CStdString strRating;
3851         if (m_currentFile->GetVideoInfoTag()->m_fRating > 0.f)
3852           strRating = StringUtils::Format("%.1f", m_currentFile->GetVideoInfoTag()->m_fRating);
3853         return strRating;
3854       }
3855       break;
3856     case VIDEOPLAYER_RATING_AND_VOTES:
3857       {
3858         CStdString strRatingAndVotes;
3859         if (m_currentFile->GetVideoInfoTag()->m_fRating > 0.f)
3860         {
3861           if (m_currentFile->GetVideoInfoTag()->m_strVotes.empty())
3862             strRatingAndVotes = StringUtils::Format("%.1f",
3863                                                     m_currentFile->GetVideoInfoTag()->m_fRating);
3864           else
3865             strRatingAndVotes = StringUtils::Format("%.1f (%s %s)",
3866                                                     m_currentFile->GetVideoInfoTag()->m_fRating,
3867                                                     m_currentFile->GetVideoInfoTag()->m_strVotes.c_str(),
3868                                                     g_localizeStrings.Get(20350).c_str());
3869         }
3870         return strRatingAndVotes;
3871       }
3872       break;
3873     case VIDEOPLAYER_VOTES:
3874       return m_currentFile->GetVideoInfoTag()->m_strVotes;
3875     case VIDEOPLAYER_YEAR:
3876       {
3877         CStdString strYear;
3878         if (m_currentFile->GetVideoInfoTag()->m_iYear > 0)
3879           strYear = StringUtils::Format("%i", m_currentFile->GetVideoInfoTag()->m_iYear);
3880         return strYear;
3881       }
3882       break;
3883     case VIDEOPLAYER_PREMIERED:
3884       {
3885         CDateTime dateTime;
3886         if (m_currentFile->GetVideoInfoTag()->m_firstAired.IsValid())
3887           dateTime = m_currentFile->GetVideoInfoTag()->m_firstAired;
3888         else if (m_currentFile->GetVideoInfoTag()->m_premiered.IsValid())
3889           dateTime = m_currentFile->GetVideoInfoTag()->m_premiered;
3890
3891         if (dateTime.IsValid())
3892           return dateTime.GetAsLocalizedDate();
3893         break;
3894       }
3895       break;
3896     case VIDEOPLAYER_PLOT:
3897       return m_currentFile->GetVideoInfoTag()->m_strPlot;
3898     case VIDEOPLAYER_TRAILER:
3899       return m_currentFile->GetVideoInfoTag()->m_strTrailer;
3900     case VIDEOPLAYER_PLOT_OUTLINE:
3901       return m_currentFile->GetVideoInfoTag()->m_strPlotOutline;
3902     case VIDEOPLAYER_EPISODE:
3903       if (m_currentFile->GetVideoInfoTag()->m_iEpisode > 0)
3904       {
3905         CStdString strEpisode;
3906         if (m_currentFile->GetVideoInfoTag()->m_iSeason == 0) // prefix episode with 'S'
3907           strEpisode = StringUtils::Format("S%i", m_currentFile->GetVideoInfoTag()->m_iEpisode);
3908         else 
3909           strEpisode = StringUtils::Format("%i", m_currentFile->GetVideoInfoTag()->m_iEpisode);
3910         return strEpisode;
3911       }
3912       break;
3913     case VIDEOPLAYER_SEASON:
3914       if (m_currentFile->GetVideoInfoTag()->m_iSeason > 0)
3915       {
3916         return StringUtils::Format("%i", m_currentFile->GetVideoInfoTag()->m_iSeason);
3917       }
3918       break;
3919     case VIDEOPLAYER_TVSHOW:
3920       return m_currentFile->GetVideoInfoTag()->m_strShowTitle;
3921
3922     case VIDEOPLAYER_STUDIO:
3923       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_studio, g_advancedSettings.m_videoItemSeparator);
3924     case VIDEOPLAYER_COUNTRY:
3925       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_country, g_advancedSettings.m_videoItemSeparator);
3926     case VIDEOPLAYER_MPAA:
3927       return m_currentFile->GetVideoInfoTag()->m_strMPAARating;
3928     case VIDEOPLAYER_TOP250:
3929       {
3930         CStdString strTop250;
3931         if (m_currentFile->GetVideoInfoTag()->m_iTop250 > 0)
3932           strTop250 = StringUtils::Format("%i", m_currentFile->GetVideoInfoTag()->m_iTop250);
3933         return strTop250;
3934       }
3935       break;
3936     case VIDEOPLAYER_CAST:
3937       return m_currentFile->GetVideoInfoTag()->GetCast();
3938     case VIDEOPLAYER_CAST_AND_ROLE:
3939       return m_currentFile->GetVideoInfoTag()->GetCast(true);
3940     case VIDEOPLAYER_ARTIST:
3941       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator);
3942     case VIDEOPLAYER_ALBUM:
3943       return m_currentFile->GetVideoInfoTag()->m_strAlbum;
3944     case VIDEOPLAYER_WRITER:
3945       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_writingCredits, g_advancedSettings.m_videoItemSeparator);
3946     case VIDEOPLAYER_TAGLINE:
3947       return m_currentFile->GetVideoInfoTag()->m_strTagLine;
3948     case VIDEOPLAYER_LASTPLAYED:
3949       {
3950         if (m_currentFile->GetVideoInfoTag()->m_lastPlayed.IsValid())
3951           return m_currentFile->GetVideoInfoTag()->m_lastPlayed.GetAsLocalizedDateTime();
3952         break;
3953       }
3954     case VIDEOPLAYER_PLAYCOUNT:
3955       {
3956         CStdString strPlayCount;
3957         if (m_currentFile->GetVideoInfoTag()->m_playCount > 0)
3958           strPlayCount = StringUtils::Format("%i", m_currentFile->GetVideoInfoTag()->m_playCount);
3959         return strPlayCount;
3960       }
3961     }
3962   }
3963   return "";
3964 }
3965
3966 int64_t CGUIInfoManager::GetPlayTime() const
3967 {
3968   if (g_application.m_pPlayer->IsPlaying())
3969   {
3970     int64_t lPTS = (int64_t)(g_application.GetTime() * 1000);
3971     if (lPTS < 0) lPTS = 0;
3972     return lPTS;
3973   }
3974   return 0;
3975 }
3976
3977 CStdString CGUIInfoManager::GetCurrentPlayTime(TIME_FORMAT format) const
3978 {
3979   if (format == TIME_FORMAT_GUESS && GetTotalPlayTime() >= 3600)
3980     format = TIME_FORMAT_HH_MM_SS;
3981   if (g_application.m_pPlayer->IsPlaying())
3982     return StringUtils::SecondsToTimeString((int)(GetPlayTime()/1000), format);
3983   return "";
3984 }
3985
3986 CStdString CGUIInfoManager::GetCurrentSeekTime(TIME_FORMAT format) const
3987 {
3988   if (format == TIME_FORMAT_GUESS && GetTotalPlayTime() >= 3600)
3989     format = TIME_FORMAT_HH_MM_SS;
3990   float time = GetTotalPlayTime() * g_application.GetSeekHandler()->GetPercent() * 0.01f;
3991   return StringUtils::SecondsToTimeString((int)time, format);
3992 }
3993
3994 int CGUIInfoManager::GetTotalPlayTime() const
3995 {
3996   int iTotalTime = (int)g_application.GetTotalTime();
3997   return iTotalTime > 0 ? iTotalTime : 0;
3998 }
3999
4000 int CGUIInfoManager::GetPlayTimeRemaining() const
4001 {
4002   int iReverse = GetTotalPlayTime() - (int)g_application.GetTime();
4003   return iReverse > 0 ? iReverse : 0;
4004 }
4005
4006 CStdString CGUIInfoManager::GetCurrentPlayTimeRemaining(TIME_FORMAT format) const
4007 {
4008   if (format == TIME_FORMAT_GUESS && GetTotalPlayTime() >= 3600)
4009     format = TIME_FORMAT_HH_MM_SS;
4010   int timeRemaining = GetPlayTimeRemaining();
4011   if (timeRemaining && g_application.m_pPlayer->IsPlaying())
4012     return StringUtils::SecondsToTimeString(timeRemaining, format);
4013   return "";
4014 }
4015
4016 void CGUIInfoManager::ResetCurrentItem()
4017 {
4018   m_currentFile->Reset();
4019   m_currentMovieThumb = "";
4020   m_currentMovieDuration = "";
4021 }
4022
4023 void CGUIInfoManager::SetCurrentItem(CFileItem &item)
4024 {
4025   ResetCurrentItem();
4026
4027   if (item.IsAudio())
4028     SetCurrentSong(item);
4029   else
4030     SetCurrentMovie(item);
4031
4032   if (item.HasEPGInfoTag())
4033     *m_currentFile->GetEPGInfoTag() = *item.GetEPGInfoTag();
4034   else if (item.HasPVRChannelInfoTag())
4035   {
4036     CEpgInfoTag tag;
4037     if (item.GetPVRChannelInfoTag()->GetEPGNow(tag))
4038       *m_currentFile->GetEPGInfoTag() = tag;
4039   }
4040
4041   SetChanged();
4042   NotifyObservers(ObservableMessageCurrentItem);
4043 }
4044
4045 void CGUIInfoManager::SetCurrentAlbumThumb(const CStdString thumbFileName)
4046 {
4047   if (CFile::Exists(thumbFileName))
4048     m_currentFile->SetArt("thumb", thumbFileName);
4049   else
4050   {
4051     m_currentFile->SetArt("thumb", "");
4052     m_currentFile->FillInDefaultIcon();
4053   }
4054 }
4055
4056 void CGUIInfoManager::SetCurrentSong(CFileItem &item)
4057 {
4058   CLog::Log(LOGDEBUG,"CGUIInfoManager::SetCurrentSong(%s)",item.GetPath().c_str());
4059   *m_currentFile = item;
4060
4061   m_currentFile->LoadMusicTag();
4062   if (m_currentFile->GetMusicInfoTag()->GetTitle().empty())
4063   {
4064     // No title in tag, show filename only
4065     m_currentFile->GetMusicInfoTag()->SetTitle(CUtil::GetTitleFromPath(m_currentFile->GetPath()));
4066   }
4067   m_currentFile->GetMusicInfoTag()->SetLoaded(true);
4068
4069   // find a thumb for this file.
4070   if (m_currentFile->IsInternetStream())
4071   {
4072     if (!g_application.m_strPlayListFile.empty())
4073     {
4074       CLog::Log(LOGDEBUG,"Streaming media detected... using %s to find a thumb", g_application.m_strPlayListFile.c_str());
4075       CFileItem streamingItem(g_application.m_strPlayListFile,false);
4076
4077       CMusicThumbLoader loader;
4078       loader.FillThumb(streamingItem);
4079       if (streamingItem.HasArt("thumb"))
4080         m_currentFile->SetArt("thumb", streamingItem.GetArt("thumb"));
4081     }
4082   }
4083   else
4084   {
4085     CMusicThumbLoader loader;
4086     loader.LoadItem(m_currentFile);
4087   }
4088   m_currentFile->FillInDefaultIcon();
4089
4090   CMusicInfoLoader::LoadAdditionalTagInfo(m_currentFile);
4091 }
4092
4093 void CGUIInfoManager::SetCurrentMovie(CFileItem &item)
4094 {
4095   CLog::Log(LOGDEBUG,"CGUIInfoManager::SetCurrentMovie(%s)", CURL::GetRedacted(item.GetPath()).c_str());
4096   *m_currentFile = item;
4097
4098   /* also call GetMovieInfo() when a VideoInfoTag is already present or additional info won't be present in the tag */
4099   if (!m_currentFile->HasPVRChannelInfoTag())
4100   {
4101     CVideoDatabase dbs;
4102     if (dbs.Open())
4103     {
4104       CStdString path = item.GetPath();
4105       CStdString videoInfoTagPath(item.GetVideoInfoTag()->m_strFileNameAndPath);
4106       if (videoInfoTagPath.find("removable://") == 0)
4107         path = videoInfoTagPath;
4108       dbs.LoadVideoInfo(path, *m_currentFile->GetVideoInfoTag());
4109       dbs.Close();
4110     }
4111   }
4112
4113   // Find a thumb for this file.
4114   if (!item.HasArt("thumb"))
4115   {
4116     CVideoThumbLoader loader;
4117     loader.LoadItem(m_currentFile);
4118   }
4119
4120   // find a thumb for this stream
4121   if (item.IsInternetStream())
4122   {
4123     // case where .strm is used to start an audio stream
4124     if (g_application.m_pPlayer->IsPlayingAudio())
4125     {
4126       SetCurrentSong(item);
4127       return;
4128     }
4129
4130     // else its a video
4131     if (!g_application.m_strPlayListFile.empty())
4132     {
4133       CLog::Log(LOGDEBUG,"Streaming media detected... using %s to find a thumb", g_application.m_strPlayListFile.c_str());
4134       CFileItem thumbItem(g_application.m_strPlayListFile,false);
4135
4136       CVideoThumbLoader loader;
4137       if (loader.FillThumb(thumbItem))
4138         item.SetArt("thumb", thumbItem.GetArt("thumb"));
4139     }
4140   }
4141
4142   item.FillInDefaultIcon();
4143   m_currentMovieThumb = item.GetArt("thumb");
4144 }
4145
4146 string CGUIInfoManager::GetSystemHeatInfo(int info)
4147 {
4148   if (CTimeUtils::GetFrameTime() - m_lastSysHeatInfoTime >= SYSHEATUPDATEINTERVAL)
4149   { // update our variables
4150     m_lastSysHeatInfoTime = CTimeUtils::GetFrameTime();
4151 #if defined(TARGET_POSIX)
4152     g_cpuInfo.getTemperature(m_cpuTemp);
4153     m_gpuTemp = GetGPUTemperature();
4154 #endif
4155   }
4156
4157   CStdString text;
4158   switch(info)
4159   {
4160     case SYSTEM_CPU_TEMPERATURE:
4161       return m_cpuTemp.IsValid() ? m_cpuTemp.ToString() : "?";
4162       break;
4163     case SYSTEM_GPU_TEMPERATURE:
4164       return m_gpuTemp.IsValid() ? m_gpuTemp.ToString() : "?";
4165       break;
4166     case SYSTEM_FAN_SPEED:
4167       text = StringUtils::Format("%i%%", m_fanSpeed * 2);
4168       break;
4169     case SYSTEM_CPU_USAGE:
4170 #if defined(TARGET_DARWIN_OSX)
4171       text = StringUtils::Format("%4.2f%%", m_resourceCounter.GetCPUUsage());
4172 #elif defined(TARGET_DARWIN) || defined(TARGET_WINDOWS)
4173       text = StringUtils::Format("%d%%", g_cpuInfo.getUsedPercentage());
4174 #else
4175       text = StringUtils::Format("%s", g_cpuInfo.GetCoresUsageString().c_str());
4176 #endif
4177       break;
4178   }
4179   return text;
4180 }
4181
4182 CTemperature CGUIInfoManager::GetGPUTemperature()
4183 {
4184   int  value = 0;
4185   char scale = 0;
4186
4187 #if defined(TARGET_DARWIN_OSX)
4188   value = SMCGetTemperature(SMC_KEY_GPU_TEMP);
4189   return CTemperature::CreateFromCelsius(value);
4190 #else
4191   CStdString  cmd   = g_advancedSettings.m_gpuTempCmd;
4192   int         ret   = 0;
4193   FILE        *p    = NULL;
4194
4195   if (cmd.empty() || !(p = popen(cmd.c_str(), "r")))
4196     return CTemperature();
4197
4198   ret = fscanf(p, "%d %c", &value, &scale);
4199   pclose(p);
4200
4201   if (ret != 2)
4202     return CTemperature();
4203 #endif
4204
4205   if (scale == 'C' || scale == 'c')
4206     return CTemperature::CreateFromCelsius(value);
4207   if (scale == 'F' || scale == 'f')
4208     return CTemperature::CreateFromFahrenheit(value);
4209   return CTemperature();
4210 }
4211
4212 // Version string MUST NOT contain spaces.  It is used
4213 // in the HTTP request user agent.
4214 CStdString CGUIInfoManager::GetVersion()
4215 {
4216   CStdString tmp;
4217   if (GetXbmcGitRevision())
4218     tmp = StringUtils::Format("%d.%d%s Git:%s", VERSION_MAJOR, VERSION_MINOR, VERSION_TAG, GetXbmcGitRevision());
4219   else
4220     tmp = StringUtils::Format("%d.%d%s", VERSION_MAJOR, VERSION_MINOR, VERSION_TAG);
4221   return tmp;
4222 }
4223
4224 CStdString CGUIInfoManager::GetBuild()
4225 {
4226   return StringUtils::Format("%s", __DATE__);
4227 }
4228
4229 void CGUIInfoManager::SetDisplayAfterSeek(unsigned int timeOut, int seekOffset)
4230 {
4231   g_infoManager.m_performingSeek = false;
4232   if (timeOut>0)
4233   {
4234     m_AfterSeekTimeout = CTimeUtils::GetFrameTime() +  timeOut;
4235     if (seekOffset)
4236       m_seekOffset = seekOffset;
4237   }
4238   else
4239     m_AfterSeekTimeout = 0;
4240 }
4241
4242 bool CGUIInfoManager::GetDisplayAfterSeek()
4243 {
4244   if (CTimeUtils::GetFrameTime() < m_AfterSeekTimeout)
4245     return true;
4246   m_seekOffset = 0;
4247   return false;
4248 }
4249
4250 void CGUIInfoManager::Clear()
4251 {
4252   CSingleLock lock(m_critInfo);
4253   m_skinVariableStrings.clear();
4254
4255   /*
4256     Erase any info bools that are unused. We do this repeatedly as each run
4257     will remove those bools that are no longer dependencies of other bools
4258     in the vector.
4259    */
4260   vector<InfoPtr>::iterator i = remove_if(m_bools.begin(), m_bools.end(), std::mem_fun_ref(&InfoPtr::unique));
4261   while (i != m_bools.end())
4262   {
4263     m_bools.erase(i, m_bools.end());
4264     i = remove_if(m_bools.begin(), m_bools.end(), std::mem_fun_ref(&InfoPtr::unique));
4265   }
4266   // log which ones are used - they should all be gone by now
4267   for (vector<InfoPtr>::const_iterator i = m_bools.begin(); i != m_bools.end(); ++i)
4268     CLog::Log(LOGDEBUG, "Infobool '%s' still used by %u instances", (*i)->GetExpression().c_str(), (unsigned int) i->use_count());
4269 }
4270
4271 void CGUIInfoManager::UpdateFPS()
4272 {
4273   m_frameCounter++;
4274   unsigned int curTime = CTimeUtils::GetFrameTime();
4275
4276   float fTimeSpan = (float)(curTime - m_lastFPSTime);
4277   if (fTimeSpan >= 1000.0f)
4278   {
4279     fTimeSpan /= 1000.0f;
4280     m_fps = m_frameCounter / fTimeSpan;
4281     m_lastFPSTime = curTime;
4282     m_frameCounter = 0;
4283   }
4284 }
4285
4286 void CGUIInfoManager::UpdateAVInfo()
4287 {
4288   if(g_application.m_pPlayer->IsPlaying())
4289   {
4290     if (!m_AVInfoValid)
4291     {
4292       SPlayerVideoStreamInfo video;
4293       SPlayerAudioStreamInfo audio;
4294
4295       g_application.m_pPlayer->GetVideoStreamInfo(video);
4296       g_application.m_pPlayer->GetAudioStreamInfo(g_application.m_pPlayer->GetAudioStream(), audio);
4297
4298       m_videoInfo = video;
4299       m_audioInfo = audio;
4300       m_AVInfoValid = true;
4301     }
4302   }
4303 }
4304
4305 int CGUIInfoManager::AddListItemProp(const CStdString &str, int offset)
4306 {
4307   for (int i=0; i < (int)m_listitemProperties.size(); i++)
4308     if (m_listitemProperties[i] == str)
4309       return (LISTITEM_PROPERTY_START+offset + i);
4310
4311   if (m_listitemProperties.size() < LISTITEM_PROPERTY_END - LISTITEM_PROPERTY_START)
4312   {
4313     m_listitemProperties.push_back(str);
4314     return LISTITEM_PROPERTY_START + offset + m_listitemProperties.size() - 1;
4315   }
4316
4317   CLog::Log(LOGERROR,"%s - not enough listitem property space!", __FUNCTION__);
4318   return 0;
4319 }
4320
4321 int CGUIInfoManager::AddMultiInfo(const GUIInfo &info)
4322 {
4323   // check to see if we have this info already
4324   for (unsigned int i = 0; i < m_multiInfo.size(); i++)
4325     if (m_multiInfo[i] == info)
4326       return (int)i + MULTI_INFO_START;
4327   // return the new offset
4328   m_multiInfo.push_back(info);
4329   int id = (int)m_multiInfo.size() + MULTI_INFO_START - 1;
4330   if (id > MULTI_INFO_END)
4331     CLog::Log(LOGERROR, "%s - too many multiinfo bool/labels in this skin", __FUNCTION__);
4332   return id;
4333 }
4334
4335 int CGUIInfoManager::ConditionalStringParameter(const CStdString &parameter, bool caseSensitive /*= false*/)
4336 {
4337   // check to see if we have this parameter already
4338   for (unsigned int i = 0; i < m_stringParameters.size(); i++)
4339     if (parameter.Equals(m_stringParameters[i], caseSensitive))
4340       return (int)i;
4341   // return the new offset
4342   m_stringParameters.push_back(parameter);
4343   return (int)m_stringParameters.size() - 1;
4344 }
4345
4346 bool CGUIInfoManager::GetItemInt(int &value, const CGUIListItem *item, int info) const
4347 {
4348   if (!item)
4349   {
4350     value = 0;
4351     return false;
4352   }
4353
4354   if (info >= LISTITEM_PROPERTY_START && info - LISTITEM_PROPERTY_START < (int)m_listitemProperties.size())
4355   { // grab the property
4356     CStdString property = m_listitemProperties[info - LISTITEM_PROPERTY_START];
4357     CStdString val = item->GetProperty(property).asString();
4358     value = atoi(val);
4359     return true;
4360   }
4361
4362   switch (info)
4363   {
4364     case LISTITEM_PROGRESS:
4365     {
4366       value = 0;
4367       if (item->IsFileItem())
4368       {
4369         const CFileItem *pItem = (const CFileItem *)item;
4370         if (pItem && pItem->HasPVRChannelInfoTag())
4371         {
4372           CEpgInfoTag epgNow;
4373           if (pItem->GetPVRChannelInfoTag()->GetEPGNow(epgNow))
4374             value = (int) epgNow.ProgressPercentage();
4375         }
4376         else if (pItem && pItem->HasEPGInfoTag())
4377         {
4378           value = (int) pItem->GetEPGInfoTag()->ProgressPercentage();
4379         }
4380       }
4381
4382       return true;
4383     }
4384     break;
4385   case LISTITEM_PERCENT_PLAYED:
4386     if (item->IsFileItem() && ((const CFileItem *)item)->HasVideoInfoTag() && ((const CFileItem *)item)->GetVideoInfoTag()->m_resumePoint.IsPartWay())
4387       value = (int)(100 * ((const CFileItem *)item)->GetVideoInfoTag()->m_resumePoint.timeInSeconds / ((const CFileItem *)item)->GetVideoInfoTag()->m_resumePoint.totalTimeInSeconds);
4388     else if (item->IsFileItem() && ((const CFileItem *)item)->HasPVRRecordingInfoTag() && ((const CFileItem *)item)->GetPVRRecordingInfoTag()->m_resumePoint.IsPartWay())
4389       value = (int)(100 * ((const CFileItem *)item)->GetPVRRecordingInfoTag()->m_resumePoint.timeInSeconds / ((const CFileItem *)item)->GetPVRRecordingInfoTag()->m_resumePoint.totalTimeInSeconds);
4390     else
4391       value = 0;
4392     return true;
4393   }
4394
4395   value = 0;
4396   return false;
4397 }
4398
4399 CStdString CGUIInfoManager::GetItemLabel(const CFileItem *item, int info, CStdString *fallback)
4400 {
4401   if (!item) return "";
4402
4403   if (info >= CONDITIONAL_LABEL_START && info <= CONDITIONAL_LABEL_END)
4404     return GetSkinVariableString(info, false, item);
4405
4406   if (info >= LISTITEM_PROPERTY_START + LISTITEM_ART_OFFSET && info - (LISTITEM_PROPERTY_START + LISTITEM_ART_OFFSET) < (int)m_listitemProperties.size())
4407   { // grab the art
4408     std::string art = m_listitemProperties[info - (LISTITEM_PROPERTY_START + LISTITEM_ART_OFFSET)];
4409     return item->GetArt(art);
4410   }
4411
4412   if (info >= LISTITEM_PROPERTY_START && info - LISTITEM_PROPERTY_START < (int)m_listitemProperties.size())
4413   { // grab the property
4414     CStdString property = m_listitemProperties[info - LISTITEM_PROPERTY_START];
4415     return item->GetProperty(property).asString();
4416   }
4417
4418   if (info >= LISTITEM_PICTURE_START && info <= LISTITEM_PICTURE_END && item->HasPictureInfoTag())
4419     return item->GetPictureInfoTag()->GetInfo(picture_slide_map[info - LISTITEM_PICTURE_START]);
4420
4421   switch (info)
4422   {
4423   case LISTITEM_LABEL:
4424     return item->GetLabel();
4425   case LISTITEM_LABEL2:
4426     return item->GetLabel2();
4427   case LISTITEM_TITLE:
4428     if (item->HasPVRChannelInfoTag())
4429     {
4430       CEpgInfoTag epgTag;
4431       return item->GetPVRChannelInfoTag()->GetEPGNow(epgTag) ?
4432           epgTag.Title() :
4433           CSettings::Get().GetBool("epg.hidenoinfoavailable") ?
4434               StringUtils::EmptyString :
4435               g_localizeStrings.Get(19055); // no information available
4436     }
4437     if (item->HasPVRRecordingInfoTag())
4438       return item->GetPVRRecordingInfoTag()->m_strTitle;
4439     if (item->HasEPGInfoTag())
4440       return item->GetEPGInfoTag()->Title();
4441     if (item->HasPVRTimerInfoTag())
4442       return item->GetPVRTimerInfoTag()->Title();
4443     if (item->HasVideoInfoTag())
4444       return item->GetVideoInfoTag()->m_strTitle;
4445     if (item->HasMusicInfoTag())
4446       return item->GetMusicInfoTag()->GetTitle();
4447     break;
4448   case LISTITEM_ORIGINALTITLE:
4449     if (item->HasVideoInfoTag())
4450       return item->GetVideoInfoTag()->m_strOriginalTitle;
4451     break;
4452   case LISTITEM_PLAYCOUNT:
4453     {
4454       CStdString strPlayCount;
4455       if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_playCount > 0)
4456         strPlayCount = StringUtils::Format("%i", item->GetVideoInfoTag()->m_playCount);
4457       if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetPlayCount() > 0)
4458         strPlayCount = StringUtils::Format("%i", item->GetMusicInfoTag()->GetPlayCount());
4459       return strPlayCount;
4460     }
4461   case LISTITEM_LASTPLAYED:
4462     {
4463       CDateTime dateTime;
4464       if (item->HasVideoInfoTag())
4465         dateTime = item->GetVideoInfoTag()->m_lastPlayed;
4466       else if (item->HasMusicInfoTag())
4467         dateTime = item->GetMusicInfoTag()->GetLastPlayed();
4468
4469       if (dateTime.IsValid())
4470         return dateTime.GetAsLocalizedDate();
4471       break;
4472     }
4473   case LISTITEM_TRACKNUMBER:
4474     {
4475       CStdString track;
4476       if (item->HasMusicInfoTag())
4477         track = StringUtils::Format("%i", item->GetMusicInfoTag()->GetTrackNumber());
4478
4479       return track;
4480     }
4481   case LISTITEM_DISC_NUMBER:
4482     {
4483       CStdString disc;
4484       if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetDiscNumber() > 0)
4485         disc = StringUtils::Format("%i", item->GetMusicInfoTag()->GetDiscNumber());
4486       return disc;
4487     }
4488   case LISTITEM_ARTIST:
4489     if (item->HasVideoInfoTag())
4490       return StringUtils::Join(item->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator);
4491     if (item->HasMusicInfoTag())
4492       return StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator);
4493     break;
4494   case LISTITEM_ALBUM_ARTIST:
4495     if (item->HasMusicInfoTag())
4496       return StringUtils::Join(item->GetMusicInfoTag()->GetAlbumArtist(), g_advancedSettings.m_musicItemSeparator);
4497     break;
4498   case LISTITEM_DIRECTOR:
4499     if (item->HasVideoInfoTag())
4500       return StringUtils::Join(item->GetVideoInfoTag()->m_director, g_advancedSettings.m_videoItemSeparator);
4501     break;
4502   case LISTITEM_ALBUM:
4503     if (item->HasVideoInfoTag())
4504       return item->GetVideoInfoTag()->m_strAlbum;
4505     if (item->HasMusicInfoTag())
4506       return item->GetMusicInfoTag()->GetAlbum();
4507     break;
4508   case LISTITEM_YEAR:
4509     if (item->HasVideoInfoTag())
4510     {
4511       CStdString strResult;
4512       if (item->GetVideoInfoTag()->m_iYear > 0)
4513         strResult = StringUtils::Format("%i",item->GetVideoInfoTag()->m_iYear);
4514       return strResult;
4515     }
4516     if (item->HasMusicInfoTag())
4517       return item->GetMusicInfoTag()->GetYearString();
4518     break;
4519   case LISTITEM_PREMIERED:
4520     if (item->HasVideoInfoTag())
4521     {
4522       CDateTime dateTime;
4523       if (item->GetVideoInfoTag()->m_firstAired.IsValid())
4524         dateTime = item->GetVideoInfoTag()->m_firstAired;
4525       else if (item->GetVideoInfoTag()->m_premiered.IsValid())
4526         dateTime = item->GetVideoInfoTag()->m_premiered;
4527
4528       if (dateTime.IsValid())
4529         return dateTime.GetAsLocalizedDate();
4530       break;
4531     }
4532     break;
4533   case LISTITEM_GENRE:
4534     if (item->HasVideoInfoTag())
4535       return StringUtils::Join(item->GetVideoInfoTag()->m_genre, g_advancedSettings.m_videoItemSeparator);
4536     if (item->HasMusicInfoTag())
4537       return StringUtils::Join(item->GetMusicInfoTag()->GetGenre(), g_advancedSettings.m_musicItemSeparator);
4538     if (item->HasPVRChannelInfoTag())
4539     {
4540       CEpgInfoTag epgTag;
4541       return item->GetPVRChannelInfoTag()->GetEPGNow(epgTag) ? StringUtils::Join(epgTag.Genre(), g_advancedSettings.m_videoItemSeparator) : StringUtils::EmptyString;
4542     }
4543     if (item->HasPVRRecordingInfoTag())
4544       return StringUtils::Join(item->GetPVRRecordingInfoTag()->m_genre, g_advancedSettings.m_videoItemSeparator);
4545     if (item->HasEPGInfoTag())
4546       return StringUtils::Join(item->GetEPGInfoTag()->Genre(), g_advancedSettings.m_videoItemSeparator);
4547     break;
4548   case LISTITEM_FILENAME:
4549   case LISTITEM_FILE_EXTENSION:
4550     {
4551       CStdString strFile;
4552       if (item->IsMusicDb() && item->HasMusicInfoTag())
4553         strFile = URIUtils::GetFileName(item->GetMusicInfoTag()->GetURL());
4554       else if (item->IsVideoDb() && item->HasVideoInfoTag())
4555         strFile = URIUtils::GetFileName(item->GetVideoInfoTag()->m_strFileNameAndPath);
4556       else
4557         strFile = URIUtils::GetFileName(item->GetPath());
4558
4559       if (info==LISTITEM_FILE_EXTENSION)
4560       {
4561         CStdString strExtension = URIUtils::GetExtension(strFile);
4562         return StringUtils::TrimLeft(strExtension, ".");
4563       }
4564       return strFile;
4565     }
4566     break;
4567   case LISTITEM_DATE:
4568     if (item->HasEPGInfoTag())
4569       return item->GetEPGInfoTag()->StartAsLocalTime().GetAsLocalizedDateTime(false, false);
4570     if (item->HasPVRChannelInfoTag())
4571     {
4572       CEpgInfoTag epgTag;
4573       return item->GetPVRChannelInfoTag()->GetEPGNow(epgTag) ? epgTag.StartAsLocalTime().GetAsLocalizedDateTime(false, false) : CDateTime::GetCurrentDateTime().GetAsLocalizedDateTime(false, false);
4574     }
4575     if (item->HasPVRRecordingInfoTag())
4576       return item->GetPVRRecordingInfoTag()->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(false, false);
4577     if (item->HasPVRTimerInfoTag())
4578       return item->GetPVRTimerInfoTag()->Summary();
4579     if (item->m_dateTime.IsValid())
4580       return item->m_dateTime.GetAsLocalizedDate();
4581     break;
4582   case LISTITEM_SIZE:
4583     if (!item->m_bIsFolder || item->m_dwSize)
4584       return StringUtils::SizeToString(item->m_dwSize);
4585     break;
4586   case LISTITEM_RATING:
4587     {
4588       CStdString rating;
4589       if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_fRating > 0.f) // movie rating
4590         rating = StringUtils::Format("%.1f", item->GetVideoInfoTag()->m_fRating);
4591       else if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetRating() > '0')
4592       { // song rating.  Images will probably be better than numbers for this in the long run
4593         rating = item->GetMusicInfoTag()->GetRating();
4594       }
4595       return rating;
4596     }
4597   case LISTITEM_RATING_AND_VOTES:
4598     {
4599       if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_fRating > 0.f) // movie rating
4600       {
4601         CStdString strRatingAndVotes;
4602         if (item->GetVideoInfoTag()->m_strVotes.empty())
4603           strRatingAndVotes = StringUtils::Format("%.1f",
4604                                                   item->GetVideoInfoTag()->m_fRating);
4605         else
4606           strRatingAndVotes = StringUtils::Format("%.1f (%s %s)",
4607                                                   item->GetVideoInfoTag()->m_fRating,
4608                                                   item->GetVideoInfoTag()->m_strVotes.c_str(),
4609                                                   g_localizeStrings.Get(20350).c_str());
4610         return strRatingAndVotes;
4611       }
4612     }
4613     break;
4614   case LISTITEM_VOTES:
4615     if (item->HasVideoInfoTag())
4616       return item->GetVideoInfoTag()->m_strVotes;
4617     break;
4618   case LISTITEM_PROGRAM_COUNT:
4619     {
4620       return StringUtils::Format("%i", item->m_iprogramCount);;
4621     }
4622   case LISTITEM_DURATION:
4623     {
4624       CStdString duration;
4625       if (item->HasPVRChannelInfoTag())
4626       {
4627         const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4628         CEpgInfoTag tag;
4629         if (channel && channel->GetEPGNow(tag))
4630           return StringUtils::SecondsToTimeString(tag.GetDuration());
4631         return StringUtils::EmptyString;
4632       }
4633       else if (item->HasPVRRecordingInfoTag())
4634       {
4635         if (item->GetPVRRecordingInfoTag()->GetDuration() > 0)
4636           duration = StringUtils::SecondsToTimeString(item->GetPVRRecordingInfoTag()->GetDuration());
4637       }
4638       else if (item->HasEPGInfoTag())
4639       {
4640         if (item->GetEPGInfoTag()->GetDuration() > 0)
4641           duration = StringUtils::SecondsToTimeString(item->GetEPGInfoTag()->GetDuration());
4642       }
4643       else if (item->HasVideoInfoTag())
4644       {
4645         if (item->GetVideoInfoTag()->GetDuration() > 0)
4646           duration = StringUtils::Format("%d", item->GetVideoInfoTag()->GetDuration() / 60);
4647       }
4648       else if (item->HasMusicInfoTag())
4649       {
4650         if (item->GetMusicInfoTag()->GetDuration() > 0)
4651           duration = StringUtils::SecondsToTimeString(item->GetMusicInfoTag()->GetDuration());
4652       }
4653       return duration;
4654     }
4655   case LISTITEM_PLOT:
4656     if (item->HasPVRChannelInfoTag())
4657     {
4658       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4659       CEpgInfoTag tag;
4660       if (channel && channel->GetEPGNow(tag))
4661         return tag.Plot();
4662       return StringUtils::EmptyString;
4663     }
4664     if (item->HasEPGInfoTag())
4665       return item->GetEPGInfoTag()->Plot();
4666     if (item->HasPVRRecordingInfoTag())
4667       return item->GetPVRRecordingInfoTag()->m_strPlot;
4668     if (item->HasVideoInfoTag())
4669     {
4670       if (!(!item->GetVideoInfoTag()->m_strShowTitle.empty() && item->GetVideoInfoTag()->m_iSeason == -1)) // dont apply to tvshows
4671         if (item->GetVideoInfoTag()->m_playCount == 0 && !CSettings::Get().GetBool("videolibrary.showunwatchedplots"))
4672           return g_localizeStrings.Get(20370);
4673
4674       return item->GetVideoInfoTag()->m_strPlot;
4675     }
4676     break;
4677   case LISTITEM_PLOT_OUTLINE:
4678     if (item->HasPVRChannelInfoTag())
4679     {
4680       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4681       CEpgInfoTag tag;
4682       if (channel && channel->GetEPGNow(tag))
4683         return tag.PlotOutline();
4684       return StringUtils::EmptyString;
4685     }
4686     if (item->HasEPGInfoTag())
4687       return item->GetEPGInfoTag()->PlotOutline();
4688     if (item->HasPVRRecordingInfoTag())
4689       return item->GetPVRRecordingInfoTag()->m_strPlotOutline;
4690     if (item->HasVideoInfoTag())
4691       return item->GetVideoInfoTag()->m_strPlotOutline;
4692     break;
4693   case LISTITEM_EPISODE:
4694     if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iEpisode > 0)
4695     {
4696       CStdString strResult;
4697       if (item->GetVideoInfoTag()->m_iSeason == 0) // prefix episode with 'S'
4698         strResult = StringUtils::Format("S%d",item->GetVideoInfoTag()->m_iEpisode);
4699       else
4700         strResult = StringUtils::Format("%d",item->GetVideoInfoTag()->m_iEpisode);
4701       return strResult;
4702     }
4703     break;
4704   case LISTITEM_SEASON:
4705     if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iSeason > 0)
4706     {
4707       return StringUtils::Format("%d",item->GetVideoInfoTag()->m_iSeason);;
4708     }
4709     break;
4710   case LISTITEM_TVSHOW:
4711     if (item->HasVideoInfoTag())
4712       return item->GetVideoInfoTag()->m_strShowTitle;
4713     break;
4714   case LISTITEM_COMMENT:
4715     if (item->HasPVRTimerInfoTag())
4716       return item->GetPVRTimerInfoTag()->GetStatus();
4717     if (item->HasMusicInfoTag())
4718       return item->GetMusicInfoTag()->GetComment();
4719     break;
4720   case LISTITEM_ACTUAL_ICON:
4721     return item->GetIconImage();
4722   case LISTITEM_ICON:
4723     {
4724       CStdString strThumb = item->GetArt("thumb");
4725       if (strThumb.empty())
4726         strThumb = item->GetIconImage();
4727       if (fallback)
4728         *fallback = item->GetIconImage();
4729       return strThumb;
4730     }
4731   case LISTITEM_OVERLAY:
4732     return item->GetOverlayImage();
4733   case LISTITEM_THUMB:
4734     return item->GetArt("thumb");
4735   case LISTITEM_FOLDERPATH:
4736     return CURL(item->GetPath()).GetWithoutUserDetails();
4737   case LISTITEM_FOLDERNAME:
4738   case LISTITEM_PATH:
4739     {
4740       CStdString path;
4741       if (item->IsMusicDb() && item->HasMusicInfoTag())
4742         path = URIUtils::GetDirectory(item->GetMusicInfoTag()->GetURL());
4743       else if (item->IsVideoDb() && item->HasVideoInfoTag())
4744       {
4745         if( item->m_bIsFolder )
4746           path = item->GetVideoInfoTag()->m_strPath;
4747         else
4748           URIUtils::GetParentPath(item->GetVideoInfoTag()->m_strFileNameAndPath, path);
4749       }
4750       else
4751         URIUtils::GetParentPath(item->GetPath(), path);
4752       path = CURL(path).GetWithoutUserDetails();
4753       if (info==LISTITEM_FOLDERNAME)
4754       {
4755         URIUtils::RemoveSlashAtEnd(path);
4756         path=URIUtils::GetFileName(path);
4757       }
4758       CURL::Decode(path);
4759       return path;
4760     }
4761   case LISTITEM_FILENAME_AND_PATH:
4762     {
4763       CStdString path;
4764       if (item->IsMusicDb() && item->HasMusicInfoTag())
4765         path = item->GetMusicInfoTag()->GetURL();
4766       else if (item->IsVideoDb() && item->HasVideoInfoTag())
4767         path = item->GetVideoInfoTag()->m_strFileNameAndPath;
4768       else
4769         path = item->GetPath();
4770       path = CURL(path).GetWithoutUserDetails();
4771       CURL::Decode(path);
4772       return path;
4773     }
4774   case LISTITEM_PICTURE_PATH:
4775     if (item->IsPicture() && (!item->IsZIP() || item->IsRAR() || item->IsCBZ() || item->IsCBR()))
4776       return item->GetPath();
4777     break;
4778   case LISTITEM_STUDIO:
4779     if (item->HasVideoInfoTag())
4780       return StringUtils::Join(item->GetVideoInfoTag()->m_studio, g_advancedSettings.m_videoItemSeparator);
4781     break;
4782   case LISTITEM_COUNTRY:
4783     if (item->HasVideoInfoTag())
4784       return StringUtils::Join(item->GetVideoInfoTag()->m_country, g_advancedSettings.m_videoItemSeparator);
4785     break;
4786   case LISTITEM_MPAA:
4787     if (item->HasVideoInfoTag())
4788       return item->GetVideoInfoTag()->m_strMPAARating;
4789     break;
4790   case LISTITEM_CAST:
4791     if (item->HasVideoInfoTag())
4792       return item->GetVideoInfoTag()->GetCast();
4793     break;
4794   case LISTITEM_CAST_AND_ROLE:
4795     if (item->HasVideoInfoTag())
4796       return item->GetVideoInfoTag()->GetCast(true);
4797     break;
4798   case LISTITEM_WRITER:
4799     if (item->HasVideoInfoTag())
4800       return StringUtils::Join(item->GetVideoInfoTag()->m_writingCredits, g_advancedSettings.m_videoItemSeparator);
4801     break;
4802   case LISTITEM_TAGLINE:
4803     if (item->HasVideoInfoTag())
4804       return item->GetVideoInfoTag()->m_strTagLine;
4805     break;
4806   case LISTITEM_TRAILER:
4807     if (item->HasVideoInfoTag())
4808       return item->GetVideoInfoTag()->m_strTrailer;
4809     break;
4810   case LISTITEM_TOP250:
4811     if (item->HasVideoInfoTag())
4812     {
4813       CStdString strResult;
4814       if (item->GetVideoInfoTag()->m_iTop250 > 0)
4815         strResult = StringUtils::Format("%i",item->GetVideoInfoTag()->m_iTop250);
4816       return strResult;
4817     }
4818     break;
4819   case LISTITEM_SORT_LETTER:
4820     {
4821       CStdString letter;
4822       std::wstring character(1, item->GetSortLabel()[0]);
4823       StringUtils::ToUpper(character);
4824       g_charsetConverter.wToUTF8(character, letter);
4825       return letter;
4826     }
4827     break;
4828   case LISTITEM_VIDEO_CODEC:
4829     if (item->HasVideoInfoTag())
4830       return item->GetVideoInfoTag()->m_streamDetails.GetVideoCodec();
4831     break;
4832   case LISTITEM_VIDEO_RESOLUTION:
4833     if (item->HasVideoInfoTag())
4834       return CStreamDetails::VideoDimsToResolutionDescription(item->GetVideoInfoTag()->m_streamDetails.GetVideoWidth(), item->GetVideoInfoTag()->m_streamDetails.GetVideoHeight());
4835     break;
4836   case LISTITEM_VIDEO_ASPECT:
4837     if (item->HasVideoInfoTag())
4838       return CStreamDetails::VideoAspectToAspectDescription(item->GetVideoInfoTag()->m_streamDetails.GetVideoAspect());
4839     break;
4840   case LISTITEM_AUDIO_CODEC:
4841     if (item->HasVideoInfoTag())
4842     {
4843       return item->GetVideoInfoTag()->m_streamDetails.GetAudioCodec();
4844     }
4845     break;
4846   case LISTITEM_AUDIO_CHANNELS:
4847     if (item->HasVideoInfoTag())
4848     {
4849       CStdString strResult;
4850       int iChannels = item->GetVideoInfoTag()->m_streamDetails.GetAudioChannels();
4851       if (iChannels > -1)
4852         strResult = StringUtils::Format("%i", iChannels);
4853       return strResult;
4854     }
4855     break;
4856   case LISTITEM_AUDIO_LANGUAGE:
4857     if (item->HasVideoInfoTag())
4858       return item->GetVideoInfoTag()->m_streamDetails.GetAudioLanguage();
4859     break;
4860   case LISTITEM_SUBTITLE_LANGUAGE:
4861     if (item->HasVideoInfoTag())
4862       return item->GetVideoInfoTag()->m_streamDetails.GetSubtitleLanguage();
4863     break;
4864   case LISTITEM_STARTTIME:
4865     if (item->HasPVRChannelInfoTag())
4866     {
4867       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4868       CEpgInfoTag tag;
4869       if (channel && channel->GetEPGNow(tag))
4870         return tag.StartAsLocalTime().GetAsLocalizedTime("", false);
4871       return CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
4872     }
4873     if (item->HasEPGInfoTag())
4874       return item->GetEPGInfoTag()->StartAsLocalTime().GetAsLocalizedTime("", false);
4875     if (item->HasPVRTimerInfoTag())
4876       return item->GetPVRTimerInfoTag()->StartAsLocalTime().GetAsLocalizedTime("", false);
4877     if (item->HasPVRRecordingInfoTag())
4878       return item->GetPVRRecordingInfoTag()->RecordingTimeAsLocalTime().GetAsLocalizedTime("", false);
4879     if (item->m_dateTime.IsValid())
4880       return item->m_dateTime.GetAsLocalizedTime("", false);
4881     break;
4882   case LISTITEM_ENDTIME:
4883     if (item->HasPVRChannelInfoTag())
4884     {
4885       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4886       CEpgInfoTag tag;
4887       if (channel && channel->GetEPGNow(tag))
4888         return tag.EndAsLocalTime().GetAsLocalizedTime("", false);
4889       return CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
4890     }
4891     if (item->HasEPGInfoTag())
4892       return item->GetEPGInfoTag()->EndAsLocalTime().GetAsLocalizedTime("", false);
4893     if (item->HasPVRTimerInfoTag())
4894       return item->GetPVRTimerInfoTag()->EndAsLocalTime().GetAsLocalizedTime("", false);
4895     break;
4896   case LISTITEM_STARTDATE:
4897     if (item->HasPVRChannelInfoTag())
4898     {
4899       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4900       CEpgInfoTag tag;
4901       if (channel && channel->GetEPGNow(tag))
4902         return tag.StartAsLocalTime().GetAsLocalizedDate(true);
4903       return CDateTime::GetCurrentDateTime().GetAsLocalizedDate(true);
4904     }
4905     if (item->HasEPGInfoTag())
4906       return item->GetEPGInfoTag()->StartAsLocalTime().GetAsLocalizedDate(true);
4907     if (item->HasPVRTimerInfoTag())
4908       return item->GetPVRTimerInfoTag()->StartAsLocalTime().GetAsLocalizedDate(true);
4909     if (item->HasPVRRecordingInfoTag())
4910       return item->GetPVRRecordingInfoTag()->RecordingTimeAsLocalTime().GetAsLocalizedDate(true);
4911     if (item->m_dateTime.IsValid())
4912       return item->m_dateTime.GetAsLocalizedDate(true);
4913     break;
4914   case LISTITEM_ENDDATE:
4915     if (item->HasPVRChannelInfoTag())
4916     {
4917       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4918       CEpgInfoTag tag;
4919       if (channel && channel->GetEPGNow(tag))
4920         return tag.EndAsLocalTime().GetAsLocalizedDate(true);
4921       return CDateTime::GetCurrentDateTime().GetAsLocalizedDate(true);
4922     }
4923     if (item->HasEPGInfoTag())
4924       return item->GetEPGInfoTag()->EndAsLocalTime().GetAsLocalizedDate(true);
4925     if (item->HasPVRTimerInfoTag())
4926       return item->GetPVRTimerInfoTag()->EndAsLocalTime().GetAsLocalizedDate(true);
4927     break;
4928   case LISTITEM_CHANNEL_NUMBER:
4929     {
4930       CStdString number;
4931       if (item->HasPVRChannelInfoTag())
4932         number = StringUtils::Format("%i", item->GetPVRChannelInfoTag()->ChannelNumber());
4933       if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->HasPVRChannel())
4934         number = StringUtils::Format("%i", item->GetEPGInfoTag()->PVRChannelNumber());
4935       if (item->HasPVRTimerInfoTag())
4936         number = StringUtils::Format("%i", item->GetPVRTimerInfoTag()->ChannelNumber());
4937
4938       return number;
4939     }
4940     break;
4941   case LISTITEM_CHANNEL_NAME:
4942     if (item->HasPVRChannelInfoTag())
4943       return item->GetPVRChannelInfoTag()->ChannelName();
4944     if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->HasPVRChannel())
4945       return item->GetEPGInfoTag()->PVRChannelName();
4946     if (item->HasPVRRecordingInfoTag())
4947       return item->GetPVRRecordingInfoTag()->m_strChannelName;
4948     if (item->HasPVRTimerInfoTag())
4949       return item->GetPVRTimerInfoTag()->ChannelName();
4950     break;
4951   case LISTITEM_NEXT_STARTTIME:
4952     {
4953       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4954       CEpgInfoTag tag;
4955       if (channel && channel->GetEPGNext(tag))
4956         return tag.StartAsLocalTime().GetAsLocalizedTime("", false);
4957     }
4958     return CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
4959   case LISTITEM_NEXT_ENDTIME:
4960     {
4961       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4962       CEpgInfoTag tag;
4963       if (channel && channel->GetEPGNext(tag))
4964         return tag.EndAsLocalTime().GetAsLocalizedTime("", false);
4965     }
4966     return CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
4967   case LISTITEM_NEXT_STARTDATE:
4968     {
4969       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4970       CEpgInfoTag tag;
4971       if (channel && channel->GetEPGNext(tag))
4972         return tag.StartAsLocalTime().GetAsLocalizedDate(true);
4973     }
4974     return CDateTime::GetCurrentDateTime().GetAsLocalizedDate(true);
4975   case LISTITEM_NEXT_ENDDATE:
4976     {
4977       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4978       CEpgInfoTag tag;
4979       if (channel && channel->GetEPGNext(tag))
4980         return tag.EndAsLocalTime().GetAsLocalizedDate(true);
4981     }
4982     return CDateTime::GetCurrentDateTime().GetAsLocalizedDate(true);
4983   case LISTITEM_NEXT_PLOT:
4984     {
4985       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4986       CEpgInfoTag tag;
4987       if (channel && channel->GetEPGNext(tag))
4988         return tag.Plot();
4989     }
4990     return StringUtils::EmptyString;
4991   case LISTITEM_NEXT_PLOT_OUTLINE:
4992     {
4993       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4994       CEpgInfoTag tag;
4995       if (channel && channel->GetEPGNext(tag))
4996         return tag.PlotOutline();
4997     }
4998     return StringUtils::EmptyString;
4999   case LISTITEM_NEXT_DURATION:
5000     {
5001       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
5002       CEpgInfoTag tag;
5003       if (channel && channel->GetEPGNext(tag))
5004         return StringUtils::SecondsToTimeString(tag.GetDuration());
5005     }
5006     return StringUtils::EmptyString;
5007   case LISTITEM_NEXT_GENRE:
5008     {
5009       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
5010       CEpgInfoTag tag;
5011       if (channel && channel->GetEPGNext(tag))
5012         return StringUtils::Join(tag.Genre(), g_advancedSettings.m_videoItemSeparator);
5013     }
5014     return StringUtils::EmptyString;
5015   case LISTITEM_NEXT_TITLE:
5016     {
5017       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
5018       CEpgInfoTag tag;
5019       if (channel && channel->GetEPGNext(tag))
5020         return tag.Title();
5021     }
5022     return StringUtils::EmptyString;
5023   case LISTITEM_PARENTALRATING:
5024     {
5025       CStdString rating;
5026       if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->ParentalRating() > 0)
5027         rating = StringUtils::Format("%i", item->GetEPGInfoTag()->ParentalRating());
5028       return rating;
5029     }
5030     break;
5031   case LISTITEM_PERCENT_PLAYED:
5032     {
5033       int val;
5034       if (GetItemInt(val, item, info))
5035       {
5036         return StringUtils::Format("%d", val);;
5037       }
5038       break;
5039     }
5040   case LISTITEM_DATE_ADDED:
5041     if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_dateAdded.IsValid())
5042       return item->GetVideoInfoTag()->m_dateAdded.GetAsLocalizedDate();
5043     break;
5044   case LISTITEM_DBTYPE:
5045     if (item->HasVideoInfoTag())
5046       return item->GetVideoInfoTag()->m_type;
5047     break;
5048   case LISTITEM_DBID:
5049     if (item->HasVideoInfoTag())
5050       {
5051         return StringUtils::Format("%i", item->GetVideoInfoTag()->m_iDbId);;
5052       }
5053     if (item->HasMusicInfoTag())
5054       {
5055         return StringUtils::Format("%i", item->GetMusicInfoTag()->GetDatabaseId());;
5056       }
5057     break;
5058   case LISTITEM_STEREOSCOPIC_MODE:
5059     {
5060       std::string stereoMode = item->GetProperty("stereomode").asString();
5061       if (stereoMode.empty() && item->HasVideoInfoTag())
5062         stereoMode = CStereoscopicsManager::Get().NormalizeStereoMode(item->GetVideoInfoTag()->m_streamDetails.GetStereoMode());
5063       return stereoMode;
5064     }
5065   }
5066   return "";
5067 }
5068
5069 CStdString CGUIInfoManager::GetItemImage(const CFileItem *item, int info, CStdString *fallback)
5070 {
5071   if (info >= CONDITIONAL_LABEL_START && info <= CONDITIONAL_LABEL_END)
5072     return GetSkinVariableString(info, true, item);
5073
5074   switch (info)
5075   {
5076   case LISTITEM_RATING:  // old song rating format
5077     {
5078       if (item->HasMusicInfoTag())
5079       {
5080         return StringUtils::Format("songrating%c.png", item->GetMusicInfoTag()->GetRating());
5081       }
5082     }
5083     break;
5084   case LISTITEM_STAR_RATING:
5085     {
5086       CStdString rating;
5087       if (item->HasVideoInfoTag())
5088       { // rating for videos is assumed 0..10, so convert to 0..5
5089         rating = StringUtils::Format("rating%d.png", (long)((item->GetVideoInfoTag()->m_fRating * 0.5f) + 0.5f));
5090       }
5091       else if (item->HasMusicInfoTag())
5092       { // song rating.
5093         rating = StringUtils::Format("rating%c.png", item->GetMusicInfoTag()->GetRating());
5094       }
5095       return rating;
5096     }
5097     break;
5098   }  /* switch (info) */
5099
5100   return GetItemLabel(item, info, fallback);
5101 }
5102
5103 bool CGUIInfoManager::GetItemBool(const CGUIListItem *item, int condition) const
5104 {
5105   if (!item) return false;
5106   if (condition >= LISTITEM_PROPERTY_START && condition - LISTITEM_PROPERTY_START < (int)m_listitemProperties.size())
5107   { // grab the property
5108     CStdString property = m_listitemProperties[condition - LISTITEM_PROPERTY_START];
5109     return item->GetProperty(property).asBoolean();
5110   }
5111   else if (condition == LISTITEM_ISPLAYING)
5112   {
5113     if (item->HasProperty("playlistposition"))
5114       return (int)item->GetProperty("playlisttype").asInteger() == g_playlistPlayer.GetCurrentPlaylist() && (int)item->GetProperty("playlistposition").asInteger() == g_playlistPlayer.GetCurrentSong();
5115     else if (item->IsFileItem() && !m_currentFile->GetPath().empty())
5116     {
5117       if (!g_application.m_strPlayListFile.empty())
5118       {
5119         //playlist file that is currently playing or the playlistitem that is currently playing.
5120         return g_application.m_strPlayListFile.Equals(((const CFileItem *)item)->GetPath()) || m_currentFile->IsSamePath((const CFileItem *)item);
5121       }
5122       return m_currentFile->IsSamePath((const CFileItem *)item);
5123     }
5124   }
5125   else if (condition == LISTITEM_ISSELECTED)
5126     return item->IsSelected();
5127   else if (condition == LISTITEM_IS_FOLDER)
5128     return item->m_bIsFolder;
5129   else if (condition == LISTITEM_IS_RESUMABLE)
5130   {
5131     if (item->IsFileItem())
5132     {
5133       if (((const CFileItem *)item)->HasVideoInfoTag())
5134         return ((const CFileItem *)item)->GetVideoInfoTag()->m_resumePoint.timeInSeconds > 0;
5135       else if (((const CFileItem *)item)->HasPVRRecordingInfoTag())
5136         return ((const CFileItem *)item)->GetPVRRecordingInfoTag()->m_resumePoint.timeInSeconds > 0;
5137     }
5138   }
5139   else if (item->IsFileItem())
5140   {
5141     const CFileItem *pItem = (const CFileItem *)item;
5142     if (condition == LISTITEM_ISRECORDING)
5143     {
5144       if (!g_PVRManager.IsStarted())
5145         return false;
5146
5147       if (pItem->HasPVRChannelInfoTag())
5148       {
5149         return pItem->GetPVRChannelInfoTag()->IsRecording();
5150       }
5151       else if (pItem->HasPVRTimerInfoTag())
5152       {
5153         const CPVRTimerInfoTag *timer = pItem->GetPVRTimerInfoTag();
5154         if (timer)
5155           return timer->IsRecording();
5156       }
5157       else if (pItem->HasEPGInfoTag())
5158       {
5159         CFileItemPtr timer = g_PVRTimers->GetTimerForEpgTag(pItem);
5160         if (timer && timer->HasPVRTimerInfoTag())
5161           return timer->GetPVRTimerInfoTag()->IsRecording();
5162       }
5163     }
5164     else if (condition == LISTITEM_HASTIMER)
5165     {
5166       if (pItem->HasEPGInfoTag())
5167       {
5168         CFileItemPtr timer = g_PVRTimers->GetTimerForEpgTag(pItem);
5169         if (timer && timer->HasPVRTimerInfoTag())
5170           return timer->GetPVRTimerInfoTag()->IsActive();
5171       }
5172     }
5173     else if (condition == LISTITEM_HAS_EPG)
5174     {
5175       if (pItem->HasPVRChannelInfoTag())
5176       {
5177         CEpgInfoTag epgTag;
5178         return pItem->GetPVRChannelInfoTag()->GetEPGNow(epgTag);
5179       }
5180       else
5181       {
5182         return pItem->HasEPGInfoTag();
5183       }
5184     }
5185     else if (condition == LISTITEM_ISENCRYPTED)
5186     {
5187       if (pItem->HasPVRChannelInfoTag())
5188       {
5189         return pItem->GetPVRChannelInfoTag()->IsEncrypted();
5190       }
5191       else if (pItem->HasEPGInfoTag() && pItem->GetEPGInfoTag()->HasPVRChannel())
5192       {
5193         return pItem->GetEPGInfoTag()->ChannelTag()->IsEncrypted();
5194       }
5195     }
5196     else if (condition == LISTITEM_IS_STEREOSCOPIC)
5197     {
5198       std::string stereoMode = pItem->GetProperty("stereomode").asString();
5199       if (stereoMode.empty() && pItem->HasVideoInfoTag())
5200           stereoMode = CStereoscopicsManager::Get().NormalizeStereoMode(pItem->GetVideoInfoTag()->m_streamDetails.GetStereoMode());
5201       if (!stereoMode.empty() && stereoMode != "mono")
5202         return true;
5203     }
5204   }
5205
5206   return false;
5207 }
5208
5209 void CGUIInfoManager::ResetCache()
5210 {
5211   // reset any animation triggers as well
5212   m_containerMoves.clear();
5213   m_updateTime++;
5214 }
5215
5216 // Called from tuxbox service thread to update current status
5217 void CGUIInfoManager::UpdateFromTuxBox()
5218 {
5219   if(g_tuxbox.vVideoSubChannel.mode)
5220     m_currentFile->GetVideoInfoTag()->m_strTitle = g_tuxbox.vVideoSubChannel.current_name;
5221
5222   // Set m_currentMovieDuration
5223   if(!g_tuxbox.sCurSrvData.current_event_duration.empty() &&
5224     !g_tuxbox.sCurSrvData.next_event_description.empty() &&
5225     !g_tuxbox.sCurSrvData.current_event_duration.Equals("-") &&
5226     !g_tuxbox.sCurSrvData.next_event_description.Equals("-"))
5227   {
5228     StringUtils::Replace(g_tuxbox.sCurSrvData.current_event_duration, "(","");
5229     StringUtils::Replace(g_tuxbox.sCurSrvData.current_event_duration, ")","");
5230
5231     m_currentMovieDuration = StringUtils::Format("%s: %s %s (%s - %s)",
5232                                                  g_localizeStrings.Get(180).c_str(),
5233                                                  g_tuxbox.sCurSrvData.current_event_duration.c_str(),
5234                                                  g_localizeStrings.Get(12391).c_str(),
5235                                                  g_tuxbox.sCurSrvData.current_event_time.c_str(),
5236                                                  g_tuxbox.sCurSrvData.next_event_time.c_str());
5237   }
5238
5239   //Set strVideoGenre
5240   if (!g_tuxbox.sCurSrvData.current_event_description.empty() &&
5241     !g_tuxbox.sCurSrvData.next_event_description.empty() &&
5242     !g_tuxbox.sCurSrvData.current_event_description.Equals("-") &&
5243     !g_tuxbox.sCurSrvData.next_event_description.Equals("-"))
5244   {
5245     CStdString genre = StringUtils::Format("%s %s  -  (%s: %s)",
5246                                            g_localizeStrings.Get(143).c_str(),
5247                                            g_tuxbox.sCurSrvData.current_event_description.c_str(),
5248                                            g_localizeStrings.Get(209).c_str(),
5249                                            g_tuxbox.sCurSrvData.next_event_description.c_str());
5250     m_currentFile->GetVideoInfoTag()->m_genre = StringUtils::Split(genre, g_advancedSettings.m_videoItemSeparator);
5251   }
5252
5253   //Set m_currentMovie.m_director
5254   if (!g_tuxbox.sCurSrvData.current_event_details.Equals("-") &&
5255     !g_tuxbox.sCurSrvData.current_event_details.empty())
5256   {
5257     m_currentFile->GetVideoInfoTag()->m_director = StringUtils::Split(g_tuxbox.sCurSrvData.current_event_details, g_advancedSettings.m_videoItemSeparator);
5258   }
5259 }
5260
5261 CStdString CGUIInfoManager::GetPictureLabel(int info)
5262 {
5263   if (info == SLIDE_FILE_NAME)
5264     return GetItemLabel(m_currentSlide, LISTITEM_FILENAME);
5265   else if (info == SLIDE_FILE_PATH)
5266   {
5267     CStdString path = URIUtils::GetDirectory(m_currentSlide->GetPath());
5268     return CURL(path).GetWithoutUserDetails();
5269   }
5270   else if (info == SLIDE_FILE_SIZE)
5271     return GetItemLabel(m_currentSlide, LISTITEM_SIZE);
5272   else if (info == SLIDE_FILE_DATE)
5273     return GetItemLabel(m_currentSlide, LISTITEM_DATE);
5274   else if (info == SLIDE_INDEX)
5275   {
5276     CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
5277     if (slideshow && slideshow->NumSlides())
5278     {
5279       return StringUtils::Format("%d/%d", slideshow->CurrentSlide(), slideshow->NumSlides());
5280     }
5281   }
5282   if (m_currentSlide->HasPictureInfoTag())
5283     return m_currentSlide->GetPictureInfoTag()->GetInfo(info);
5284   return "";
5285 }
5286
5287 void CGUIInfoManager::SetCurrentSlide(CFileItem &item)
5288 {
5289   if (m_currentSlide->GetPath() != item.GetPath())
5290   {
5291     if (!item.GetPictureInfoTag()->Loaded()) // If picture metadata has not been loaded yet, load it now
5292       item.GetPictureInfoTag()->Load(item.GetPath());
5293     *m_currentSlide = item;
5294   }
5295 }
5296
5297 void CGUIInfoManager::ResetCurrentSlide()
5298 {
5299   m_currentSlide->Reset();
5300 }
5301
5302 bool CGUIInfoManager::CheckWindowCondition(CGUIWindow *window, int condition) const
5303 {
5304   // check if it satisfies our condition
5305   if (!window) return false;
5306   if ((condition & WINDOW_CONDITION_HAS_LIST_ITEMS) && !window->HasListItems())
5307     return false;
5308   if ((condition & WINDOW_CONDITION_IS_MEDIA_WINDOW) && !window->IsMediaWindow())
5309     return false;
5310   return true;
5311 }
5312
5313 CGUIWindow *CGUIInfoManager::GetWindowWithCondition(int contextWindow, int condition) const
5314 {
5315   CGUIWindow *window = g_windowManager.GetWindow(contextWindow);
5316   if (CheckWindowCondition(window, condition))
5317     return window;
5318
5319   // try topmost dialog
5320   window = g_windowManager.GetWindow(g_windowManager.GetTopMostModalDialogID());
5321   if (CheckWindowCondition(window, condition))
5322     return window;
5323
5324   // try active window
5325   window = g_windowManager.GetWindow(g_windowManager.GetActiveWindow());
5326   if (CheckWindowCondition(window, condition))
5327     return window;
5328
5329   return NULL;
5330 }
5331
5332 void CGUIInfoManager::SetCurrentVideoTag(const CVideoInfoTag &tag)
5333 {
5334   *m_currentFile->GetVideoInfoTag() = tag;
5335   m_currentFile->m_lStartOffset = 0;
5336 }
5337
5338 void CGUIInfoManager::SetCurrentSongTag(const MUSIC_INFO::CMusicInfoTag &tag)
5339 {
5340   //CLog::Log(LOGDEBUG, "Asked to SetCurrentTag");
5341   *m_currentFile->GetMusicInfoTag() = tag;
5342   m_currentFile->m_lStartOffset = 0;
5343 }
5344
5345 const CFileItem& CGUIInfoManager::GetCurrentSlide() const
5346 {
5347   return *m_currentSlide;
5348 }
5349
5350 const MUSIC_INFO::CMusicInfoTag* CGUIInfoManager::GetCurrentSongTag() const
5351 {
5352   if (m_currentFile->HasMusicInfoTag())
5353     return m_currentFile->GetMusicInfoTag();
5354
5355   return NULL;
5356 }
5357
5358 const CVideoInfoTag* CGUIInfoManager::GetCurrentMovieTag() const
5359 {
5360   if (m_currentFile->HasVideoInfoTag())
5361     return m_currentFile->GetVideoInfoTag();
5362
5363   return NULL;
5364 }
5365
5366 void GUIInfo::SetInfoFlag(uint32_t flag)
5367 {
5368   assert(flag >= (1 << 24));
5369   m_data1 |= flag;
5370 }
5371
5372 uint32_t GUIInfo::GetInfoFlag() const
5373 {
5374   // we strip out the bottom 24 bits, where we keep data
5375   // and return the flag only
5376   return m_data1 & 0xff000000;
5377 }
5378
5379 uint32_t GUIInfo::GetData1() const
5380 {
5381   // we strip out the top 8 bits, where we keep flags
5382   // and return the unflagged data
5383   return m_data1 & ((1 << 24) -1);
5384 }
5385
5386 int GUIInfo::GetData2() const
5387 {
5388   return m_data2;
5389 }
5390
5391 void CGUIInfoManager::SetLibraryBool(int condition, bool value)
5392 {
5393   switch (condition)
5394   {
5395     case LIBRARY_HAS_MUSIC:
5396       m_libraryHasMusic = value ? 1 : 0;
5397       break;
5398     case LIBRARY_HAS_MOVIES:
5399       m_libraryHasMovies = value ? 1 : 0;
5400       break;
5401     case LIBRARY_HAS_MOVIE_SETS:
5402       m_libraryHasMovieSets = value ? 1 : 0;
5403       break;
5404     case LIBRARY_HAS_TVSHOWS:
5405       m_libraryHasTVShows = value ? 1 : 0;
5406       break;
5407     case LIBRARY_HAS_MUSICVIDEOS:
5408       m_libraryHasMusicVideos = value ? 1 : 0;
5409       break;
5410     default:
5411       break;
5412   }
5413 }
5414
5415 void CGUIInfoManager::ResetLibraryBools()
5416 {
5417   m_libraryHasMusic = -1;
5418   m_libraryHasMovies = -1;
5419   m_libraryHasTVShows = -1;
5420   m_libraryHasMusicVideos = -1;
5421   m_libraryHasMovieSets = -1;
5422 }
5423
5424 bool CGUIInfoManager::GetLibraryBool(int condition)
5425 {
5426   if (condition == LIBRARY_HAS_MUSIC)
5427   {
5428     if (m_libraryHasMusic < 0)
5429     { // query
5430       CMusicDatabase db;
5431       if (db.Open())
5432       {
5433         m_libraryHasMusic = (db.GetSongsCount() > 0) ? 1 : 0;
5434         db.Close();
5435       }
5436     }
5437     return m_libraryHasMusic > 0;
5438   }
5439   else if (condition == LIBRARY_HAS_MOVIES)
5440   {
5441     if (m_libraryHasMovies < 0)
5442     {
5443       CVideoDatabase db;
5444       if (db.Open())
5445       {
5446         m_libraryHasMovies = db.HasContent(VIDEODB_CONTENT_MOVIES) ? 1 : 0;
5447         db.Close();
5448       }
5449     }
5450     return m_libraryHasMovies > 0;
5451   }
5452   else if (condition == LIBRARY_HAS_MOVIE_SETS)
5453   {
5454     if (m_libraryHasMovieSets < 0)
5455     {
5456       CVideoDatabase db;
5457       if (db.Open())
5458       {
5459         m_libraryHasMovieSets = db.HasSets() ? 1 : 0;
5460         db.Close();
5461       }
5462     }
5463     return m_libraryHasMovieSets > 0;
5464   }
5465   else if (condition == LIBRARY_HAS_TVSHOWS)
5466   {
5467     if (m_libraryHasTVShows < 0)
5468     {
5469       CVideoDatabase db;
5470       if (db.Open())
5471       {
5472         m_libraryHasTVShows = db.HasContent(VIDEODB_CONTENT_TVSHOWS) ? 1 : 0;
5473         db.Close();
5474       }
5475     }
5476     return m_libraryHasTVShows > 0;
5477   }
5478   else if (condition == LIBRARY_HAS_MUSICVIDEOS)
5479   {
5480     if (m_libraryHasMusicVideos < 0)
5481     {
5482       CVideoDatabase db;
5483       if (db.Open())
5484       {
5485         m_libraryHasMusicVideos = db.HasContent(VIDEODB_CONTENT_MUSICVIDEOS) ? 1 : 0;
5486         db.Close();
5487       }
5488     }
5489     return m_libraryHasMusicVideos > 0;
5490   }
5491   else if (condition == LIBRARY_HAS_VIDEO)
5492   {
5493     return (GetLibraryBool(LIBRARY_HAS_MOVIES) ||
5494             GetLibraryBool(LIBRARY_HAS_TVSHOWS) ||
5495             GetLibraryBool(LIBRARY_HAS_MUSICVIDEOS));
5496   }
5497   return false;
5498 }
5499
5500 int CGUIInfoManager::RegisterSkinVariableString(const CSkinVariableString* info)
5501 {
5502   if (!info)
5503     return 0;
5504
5505   CSingleLock lock(m_critInfo);
5506   m_skinVariableStrings.push_back(*info);
5507   delete info;
5508   return CONDITIONAL_LABEL_START + m_skinVariableStrings.size() - 1;
5509 }
5510
5511 int CGUIInfoManager::TranslateSkinVariableString(const CStdString& name, int context)
5512 {
5513   for (vector<CSkinVariableString>::const_iterator it = m_skinVariableStrings.begin();
5514        it != m_skinVariableStrings.end(); ++it)
5515   {
5516     if (it->GetName().Equals(name) && it->GetContext() == context)
5517       return it - m_skinVariableStrings.begin() + CONDITIONAL_LABEL_START;
5518   }
5519   return 0;
5520 }
5521
5522 CStdString CGUIInfoManager::GetSkinVariableString(int info,
5523                                                   bool preferImage /*= false*/,
5524                                                   const CGUIListItem *item /*= NULL*/)
5525 {
5526   info -= CONDITIONAL_LABEL_START;
5527   if (info >= 0 && info < (int)m_skinVariableStrings.size())
5528     return m_skinVariableStrings[info].GetValue(preferImage, item);
5529
5530   return "";
5531 }
5532
5533 bool CGUIInfoManager::ConditionsChangedValues(const std::map<INFO::InfoPtr, bool>& map)
5534 {
5535   for (std::map<INFO::InfoPtr, bool>::const_iterator it = map.begin() ; it != map.end() ; it++)
5536   {
5537     if (GetBoolValue(it->first) != it->second)
5538       return true;
5539   }
5540   return false;
5541 }
5542
5543 bool CGUIInfoManager::GetEpgInfoTag(CEpgInfoTag& tag) const
5544 {
5545   if (m_currentFile->HasEPGInfoTag())
5546   {
5547     CEpgInfoTag* currentTag =  m_currentFile->GetEPGInfoTag();
5548     while (currentTag && !currentTag->IsActive())
5549       currentTag = currentTag->GetNextEvent().get();
5550     if (currentTag)
5551     {
5552       tag = *currentTag;
5553       return true;
5554     }
5555   }
5556   return false;
5557 }