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