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