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