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