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