Merge pull request #2367 from NHellFire/Lircmap
[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("h")) return TIME_FORMAT_H;
1169   else if (format.Equals("h:mm:ss")) return TIME_FORMAT_H_MM_SS;
1170   else if (format.Equals("xx")) return TIME_FORMAT_XX;
1171   return TIME_FORMAT_GUESS;
1172 }
1173
1174 CStdString CGUIInfoManager::GetLabel(int info, int contextWindow, CStdString *fallback)
1175 {
1176   if (info >= CONDITIONAL_LABEL_START && info <= CONDITIONAL_LABEL_END)
1177     return GetSkinVariableString(info, false);
1178
1179   CStdString strLabel;
1180   if (info >= MULTI_INFO_START && info <= MULTI_INFO_END)
1181     return GetMultiInfoLabel(m_multiInfo[info - MULTI_INFO_START], contextWindow);
1182
1183   if (info >= SLIDE_INFO_START && info <= SLIDE_INFO_END)
1184     return GetPictureLabel(info);
1185
1186   if (info >= LISTITEM_PROPERTY_START+MUSICPLAYER_PROPERTY_OFFSET &&
1187       info - (LISTITEM_PROPERTY_START+MUSICPLAYER_PROPERTY_OFFSET) < (int)m_listitemProperties.size())
1188   { // grab the property
1189     if (!m_currentFile)
1190       return "";
1191
1192     CStdString property = m_listitemProperties[info - LISTITEM_PROPERTY_START-MUSICPLAYER_PROPERTY_OFFSET];
1193     return m_currentFile->GetProperty(property).asString();
1194   }
1195
1196   if (info >= LISTITEM_START && info <= LISTITEM_END)
1197   {
1198     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_HAS_LIST_ITEMS); // true for has list items
1199     if (window)
1200     {
1201       CFileItemPtr item = window->GetCurrentListItem();
1202       strLabel = GetItemLabel(item.get(), info, fallback);
1203     }
1204
1205     return strLabel;
1206   }
1207
1208   switch (info)
1209   {
1210   case PVR_NEXT_RECORDING_CHANNEL:
1211   case PVR_NEXT_RECORDING_CHAN_ICO:
1212   case PVR_NEXT_RECORDING_DATETIME:
1213   case PVR_NEXT_RECORDING_TITLE:
1214   case PVR_NOW_RECORDING_CHANNEL:
1215   case PVR_NOW_RECORDING_CHAN_ICO:
1216   case PVR_NOW_RECORDING_DATETIME:
1217   case PVR_NOW_RECORDING_TITLE:
1218   case PVR_BACKEND_NAME:
1219   case PVR_BACKEND_VERSION:
1220   case PVR_BACKEND_HOST:
1221   case PVR_BACKEND_DISKSPACE:
1222   case PVR_BACKEND_CHANNELS:
1223   case PVR_BACKEND_TIMERS:
1224   case PVR_BACKEND_RECORDINGS:
1225   case PVR_BACKEND_NUMBER:
1226   case PVR_TOTAL_DISKSPACE:
1227   case PVR_NEXT_TIMER:
1228   case PVR_PLAYING_DURATION:
1229   case PVR_PLAYING_TIME:
1230   case PVR_PLAYING_PROGRESS:
1231   case PVR_ACTUAL_STREAM_CLIENT:
1232   case PVR_ACTUAL_STREAM_DEVICE:
1233   case PVR_ACTUAL_STREAM_STATUS:
1234   case PVR_ACTUAL_STREAM_SIG:
1235   case PVR_ACTUAL_STREAM_SNR:
1236   case PVR_ACTUAL_STREAM_SIG_PROGR:
1237   case PVR_ACTUAL_STREAM_SNR_PROGR:
1238   case PVR_ACTUAL_STREAM_BER:
1239   case PVR_ACTUAL_STREAM_UNC:
1240   case PVR_ACTUAL_STREAM_VIDEO_BR:
1241   case PVR_ACTUAL_STREAM_AUDIO_BR:
1242   case PVR_ACTUAL_STREAM_DOLBY_BR:
1243   case PVR_ACTUAL_STREAM_CRYPTION:
1244     g_PVRManager.TranslateCharInfo(info, strLabel);
1245     break;
1246   case WEATHER_CONDITIONS:
1247     strLabel = g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_COND);
1248     strLabel = strLabel.Trim();
1249     break;
1250   case WEATHER_TEMPERATURE:
1251     strLabel.Format("%s%s", g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_TEMP), g_langInfo.GetTempUnitString().c_str());
1252     break;
1253   case WEATHER_LOCATION:
1254     strLabel = g_weatherManager.GetInfo(WEATHER_LABEL_LOCATION);
1255     break;
1256   case WEATHER_FANART_CODE:
1257     strLabel = URIUtils::GetFileName(g_weatherManager.GetInfo(WEATHER_IMAGE_CURRENT_ICON));
1258     URIUtils::RemoveExtension(strLabel);
1259     break;
1260   case WEATHER_PLUGIN:
1261     strLabel = g_guiSettings.GetString("weather.addon");
1262     break;
1263   case SYSTEM_DATE:
1264     strLabel = GetDate();
1265     break;
1266   case SYSTEM_FPS:
1267     strLabel.Format("%02.2f", m_fps);
1268     break;
1269   case PLAYER_VOLUME:
1270     strLabel.Format("%2.1f dB", CAEUtil::PercentToGain(g_settings.m_fVolumeLevel));
1271     break;
1272   case PLAYER_SUBTITLE_DELAY:
1273     strLabel.Format("%2.3f s", g_settings.m_currentVideoSettings.m_SubtitleDelay);
1274     break;
1275   case PLAYER_AUDIO_DELAY:
1276     strLabel.Format("%2.3f s", g_settings.m_currentVideoSettings.m_AudioDelay);
1277     break;
1278   case PLAYER_CHAPTER:
1279     if(g_application.IsPlaying() && g_application.m_pPlayer)
1280       strLabel.Format("%02d", g_application.m_pPlayer->GetChapter());
1281     break;
1282   case PLAYER_CHAPTERCOUNT:
1283     if(g_application.IsPlaying() && g_application.m_pPlayer)
1284       strLabel.Format("%02d", g_application.m_pPlayer->GetChapterCount());
1285     break;
1286   case PLAYER_CHAPTERNAME:
1287     if(g_application.IsPlaying() && g_application.m_pPlayer)
1288       g_application.m_pPlayer->GetChapterName(strLabel);
1289     break;
1290   case PLAYER_CACHELEVEL:
1291     {
1292       int iLevel = 0;
1293       if(g_application.IsPlaying() && GetInt(iLevel, PLAYER_CACHELEVEL) && iLevel >= 0)
1294         strLabel.Format("%i", iLevel);
1295     }
1296     break;
1297   case PLAYER_TIME:
1298     if(g_application.IsPlaying() && g_application.m_pPlayer)
1299       strLabel = GetCurrentPlayTime(TIME_FORMAT_HH_MM);
1300     break;
1301   case PLAYER_DURATION:
1302     if(g_application.IsPlaying() && g_application.m_pPlayer)
1303       strLabel = GetDuration(TIME_FORMAT_HH_MM);
1304     break;
1305   case PLAYER_PATH:
1306   case PLAYER_FILEPATH:
1307     if (m_currentFile)
1308     {
1309       if (m_currentFile->HasMusicInfoTag())
1310         strLabel = m_currentFile->GetMusicInfoTag()->GetURL();
1311       else if (m_currentFile->HasVideoInfoTag())
1312         strLabel = m_currentFile->GetVideoInfoTag()->m_strFileNameAndPath;
1313       if (strLabel.IsEmpty())
1314         strLabel = m_currentFile->GetPath();
1315     }
1316     if (info == PLAYER_PATH)
1317     {
1318       // do this twice since we want the path outside the archive if this
1319       // is to be of use.
1320       if (URIUtils::IsInArchive(strLabel))
1321         strLabel = URIUtils::GetParentPath(strLabel);
1322       strLabel = URIUtils::GetParentPath(strLabel);
1323     }
1324     break;
1325   case PLAYER_TITLE:
1326     {
1327       if(m_currentFile)
1328       {
1329         if (m_currentFile->HasPVRChannelInfoTag())
1330         {
1331           CEpgInfoTag tag;
1332           return m_currentFile->GetPVRChannelInfoTag()->GetEPGNow(tag) ?
1333                    tag.Title() :
1334                    g_guiSettings.GetBool("epg.hidenoinfoavailable") ?
1335                      StringUtils::EmptyString :
1336                      g_localizeStrings.Get(19055); // no information available
1337         }
1338         if (m_currentFile->HasPVRRecordingInfoTag() && !m_currentFile->GetPVRRecordingInfoTag()->m_strTitle.IsEmpty())
1339           return m_currentFile->GetPVRRecordingInfoTag()->m_strTitle;
1340         if (m_currentFile->HasVideoInfoTag() && !m_currentFile->GetVideoInfoTag()->m_strTitle.IsEmpty())
1341           return m_currentFile->GetVideoInfoTag()->m_strTitle;
1342         if (m_currentFile->HasMusicInfoTag() && !m_currentFile->GetMusicInfoTag()->GetTitle().IsEmpty())
1343           return m_currentFile->GetMusicInfoTag()->GetTitle();
1344         // don't have the title, so use dvdplayer, label, or drop down to title from path
1345         if (g_application.m_pPlayer && !g_application.m_pPlayer->GetPlayingTitle().IsEmpty())
1346           return g_application.m_pPlayer->GetPlayingTitle();
1347         if (!m_currentFile->GetLabel().IsEmpty())
1348           return m_currentFile->GetLabel();
1349         return CUtil::GetTitleFromPath(m_currentFile->GetPath());
1350       }
1351       else
1352       {
1353         if (g_application.m_pPlayer && !g_application.m_pPlayer->GetPlayingTitle().IsEmpty())
1354           return g_application.m_pPlayer->GetPlayingTitle();
1355       }
1356     }
1357     break;
1358   case MUSICPLAYER_TITLE:
1359   case MUSICPLAYER_ALBUM:
1360   case MUSICPLAYER_ARTIST:
1361   case MUSICPLAYER_ALBUM_ARTIST:
1362   case MUSICPLAYER_GENRE:
1363   case MUSICPLAYER_YEAR:
1364   case MUSICPLAYER_TRACK_NUMBER:
1365   case MUSICPLAYER_BITRATE:
1366   case MUSICPLAYER_PLAYLISTLEN:
1367   case MUSICPLAYER_PLAYLISTPOS:
1368   case MUSICPLAYER_CHANNELS:
1369   case MUSICPLAYER_BITSPERSAMPLE:
1370   case MUSICPLAYER_SAMPLERATE:
1371   case MUSICPLAYER_CODEC:
1372   case MUSICPLAYER_DISC_NUMBER:
1373   case MUSICPLAYER_RATING:
1374   case MUSICPLAYER_COMMENT:
1375   case MUSICPLAYER_LYRICS:
1376   case MUSICPLAYER_CHANNEL_NAME:
1377   case MUSICPLAYER_CHANNEL_NUMBER:
1378   case MUSICPLAYER_CHANNEL_GROUP:
1379   case MUSICPLAYER_PLAYCOUNT:
1380   case MUSICPLAYER_LASTPLAYED:
1381     strLabel = GetMusicLabel(info);
1382   break;
1383   case VIDEOPLAYER_TITLE:
1384   case VIDEOPLAYER_ORIGINALTITLE:
1385   case VIDEOPLAYER_GENRE:
1386   case VIDEOPLAYER_DIRECTOR:
1387   case VIDEOPLAYER_YEAR:
1388   case VIDEOPLAYER_PLAYLISTLEN:
1389   case VIDEOPLAYER_PLAYLISTPOS:
1390   case VIDEOPLAYER_PLOT:
1391   case VIDEOPLAYER_PLOT_OUTLINE:
1392   case VIDEOPLAYER_EPISODE:
1393   case VIDEOPLAYER_SEASON:
1394   case VIDEOPLAYER_RATING:
1395   case VIDEOPLAYER_RATING_AND_VOTES:
1396   case VIDEOPLAYER_TVSHOW:
1397   case VIDEOPLAYER_PREMIERED:
1398   case VIDEOPLAYER_STUDIO:
1399   case VIDEOPLAYER_COUNTRY:
1400   case VIDEOPLAYER_MPAA:
1401   case VIDEOPLAYER_TOP250:
1402   case VIDEOPLAYER_CAST:
1403   case VIDEOPLAYER_CAST_AND_ROLE:
1404   case VIDEOPLAYER_ARTIST:
1405   case VIDEOPLAYER_ALBUM:
1406   case VIDEOPLAYER_WRITER:
1407   case VIDEOPLAYER_TAGLINE:
1408   case VIDEOPLAYER_TRAILER:
1409   case VIDEOPLAYER_STARTTIME:
1410   case VIDEOPLAYER_ENDTIME:
1411   case VIDEOPLAYER_NEXT_TITLE:
1412   case VIDEOPLAYER_NEXT_GENRE:
1413   case VIDEOPLAYER_NEXT_PLOT:
1414   case VIDEOPLAYER_NEXT_PLOT_OUTLINE:
1415   case VIDEOPLAYER_NEXT_STARTTIME:
1416   case VIDEOPLAYER_NEXT_ENDTIME:
1417   case VIDEOPLAYER_NEXT_DURATION:
1418   case VIDEOPLAYER_CHANNEL_NAME:
1419   case VIDEOPLAYER_CHANNEL_NUMBER:
1420   case VIDEOPLAYER_CHANNEL_GROUP:
1421   case VIDEOPLAYER_PARENTAL_RATING:
1422   case VIDEOPLAYER_PLAYCOUNT:
1423   case VIDEOPLAYER_LASTPLAYED:
1424     strLabel = GetVideoLabel(info);
1425   break;
1426   case VIDEOPLAYER_VIDEO_CODEC:
1427     if(g_application.IsPlaying() && g_application.m_pPlayer)
1428     {
1429       SPlayerVideoStreamInfo info;
1430       g_application.m_pPlayer->GetVideoStreamInfo(info);
1431       strLabel = info.videoCodecName;
1432     }
1433     break;
1434   case VIDEOPLAYER_VIDEO_RESOLUTION:
1435     if(g_application.IsPlaying() && g_application.m_pPlayer)
1436       return CStreamDetails::VideoDimsToResolutionDescription(g_application.m_pPlayer->GetPictureWidth(), g_application.m_pPlayer->GetPictureHeight());
1437     break;
1438   case VIDEOPLAYER_AUDIO_CODEC:
1439     if(g_application.IsPlaying() && g_application.m_pPlayer)
1440     {
1441       SPlayerAudioStreamInfo info;
1442       g_application.m_pPlayer->GetAudioStreamInfo(g_application.m_pPlayer->GetAudioStream(), info);
1443       strLabel = info.audioCodecName;
1444     }
1445     break;
1446   case VIDEOPLAYER_VIDEO_ASPECT:
1447     if (g_application.IsPlaying() && g_application.m_pPlayer)
1448     {
1449       SPlayerVideoStreamInfo info;
1450       g_application.m_pPlayer->GetVideoStreamInfo(info);
1451       strLabel = CStreamDetails::VideoAspectToAspectDescription(info.videoAspectRatio);
1452     }
1453     break;
1454   case VIDEOPLAYER_AUDIO_CHANNELS:
1455     if(g_application.IsPlaying() && g_application.m_pPlayer)
1456     {
1457       SPlayerAudioStreamInfo info;
1458       g_application.m_pPlayer->GetAudioStreamInfo(g_application.m_pPlayer->GetAudioStream(), info);
1459       strLabel.Format("%i", info.channels);
1460     }
1461     break;
1462   case PLAYLIST_LENGTH:
1463   case PLAYLIST_POSITION:
1464   case PLAYLIST_RANDOM:
1465   case PLAYLIST_REPEAT:
1466     strLabel = GetPlaylistLabel(info);
1467   break;
1468   case MUSICPM_SONGSPLAYED:
1469   case MUSICPM_MATCHINGSONGS:
1470   case MUSICPM_MATCHINGSONGSPICKED:
1471   case MUSICPM_MATCHINGSONGSLEFT:
1472   case MUSICPM_RELAXEDSONGSPICKED:
1473   case MUSICPM_RANDOMSONGSPICKED:
1474     strLabel = GetMusicPartyModeLabel(info);
1475   break;
1476
1477   case SYSTEM_FREE_SPACE:
1478   case SYSTEM_USED_SPACE:
1479   case SYSTEM_TOTAL_SPACE:
1480   case SYSTEM_FREE_SPACE_PERCENT:
1481   case SYSTEM_USED_SPACE_PERCENT:
1482     return g_sysinfo.GetHddSpaceInfo(info);
1483   break;
1484
1485   case SYSTEM_CPU_TEMPERATURE:
1486   case SYSTEM_GPU_TEMPERATURE:
1487   case SYSTEM_FAN_SPEED:
1488   case SYSTEM_CPU_USAGE:
1489     return GetSystemHeatInfo(info);
1490     break;
1491
1492   case SYSTEM_VIDEO_ENCODER_INFO:
1493   case NETWORK_MAC_ADDRESS:
1494   case SYSTEM_KERNEL_VERSION:
1495   case SYSTEM_CPUFREQUENCY:
1496   case SYSTEM_INTERNET_STATE:
1497   case SYSTEM_UPTIME:
1498   case SYSTEM_TOTALUPTIME:
1499   case SYSTEM_BATTERY_LEVEL:
1500     return g_sysinfo.GetInfo(info);
1501     break;
1502
1503   case SYSTEM_SCREEN_RESOLUTION:
1504     if(g_Windowing.IsFullScreen())
1505       strLabel.Format("%ix%i@%.2fHz - %s (%02.2f fps)",
1506         g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution].iScreenWidth,
1507         g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution].iScreenHeight,
1508         g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution].fRefreshRate,
1509         g_localizeStrings.Get(244), GetFPS());
1510     else
1511       strLabel.Format("%ix%i - %s (%02.2f fps)",
1512         g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution].iScreenWidth,
1513         g_settings.m_ResInfo[g_guiSettings.m_LookAndFeelResolution].iScreenHeight,
1514         g_localizeStrings.Get(242), GetFPS());
1515     return strLabel;
1516     break;
1517
1518   case CONTAINER_FOLDERPATH:
1519   case CONTAINER_FOLDERNAME:
1520     {
1521       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
1522       if (window)
1523       {
1524         if (info==CONTAINER_FOLDERNAME)
1525           strLabel = ((CGUIMediaWindow*)window)->CurrentDirectory().GetLabel();
1526         else
1527           strLabel = CURL(((CGUIMediaWindow*)window)->CurrentDirectory().GetPath()).GetWithoutUserDetails();
1528       }
1529       break;
1530     }
1531   case CONTAINER_PLUGINNAME:
1532     {
1533       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
1534       if (window)
1535       {
1536         CURL url(((CGUIMediaWindow*)window)->CurrentDirectory().GetPath());
1537         if (url.GetProtocol().Equals("plugin"))
1538         {
1539           strLabel = url.GetFileName();
1540           URIUtils::RemoveSlashAtEnd(strLabel);
1541         }
1542       }
1543       break;
1544     }
1545   case CONTAINER_VIEWMODE:
1546     {
1547       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
1548       if (window)
1549       {
1550         const CGUIControl *control = window->GetControl(window->GetViewContainerID());
1551         if (control && control->IsContainer())
1552           strLabel = ((IGUIContainer *)control)->GetLabel();
1553       }
1554       break;
1555     }
1556   case CONTAINER_SORT_METHOD:
1557     {
1558       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
1559       if (window)
1560       {
1561         const CGUIViewState *viewState = ((CGUIMediaWindow*)window)->GetViewState();
1562         if (viewState)
1563           strLabel = g_localizeStrings.Get(viewState->GetSortMethodLabel());
1564     }
1565     }
1566     break;
1567   case CONTAINER_NUM_PAGES:
1568   case CONTAINER_NUM_ITEMS:
1569   case CONTAINER_CURRENT_PAGE:
1570     return GetMultiInfoLabel(GUIInfo(info), contextWindow);
1571     break;
1572   case CONTAINER_SHOWPLOT:
1573     {
1574       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
1575       if (window)
1576         return ((CGUIMediaWindow *)window)->CurrentDirectory().GetProperty("showplot").asString();
1577     }
1578     break;
1579   case CONTAINER_TOTALTIME:
1580     {
1581       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
1582       if (window)
1583       {
1584         const CFileItemList& items=((CGUIMediaWindow *)window)->CurrentDirectory();
1585         int duration=0;
1586         for (int i=0;i<items.Size();++i)
1587         {
1588           CFileItemPtr item=items.Get(i);
1589           if (item->HasMusicInfoTag())
1590             duration += item->GetMusicInfoTag()->GetDuration();
1591           else if (item->HasVideoInfoTag())
1592             duration += item->GetVideoInfoTag()->m_streamDetails.GetVideoDuration();
1593         }
1594         if (duration > 0)
1595           return StringUtils::SecondsToTimeString(duration);
1596       }
1597     }
1598     break;
1599   case SYSTEM_BUILD_VERSION:
1600     strLabel = GetVersion();
1601     break;
1602   case SYSTEM_BUILD_DATE:
1603     strLabel = GetBuild();
1604     break;
1605   case SYSTEM_FREE_MEMORY:
1606   case SYSTEM_FREE_MEMORY_PERCENT:
1607   case SYSTEM_USED_MEMORY:
1608   case SYSTEM_USED_MEMORY_PERCENT:
1609   case SYSTEM_TOTAL_MEMORY:
1610     {
1611       MEMORYSTATUSEX stat;
1612       stat.dwLength = sizeof(MEMORYSTATUSEX);
1613       GlobalMemoryStatusEx(&stat);
1614       int iMemPercentFree = 100 - ((int)( 100.0f* (stat.ullTotalPhys - stat.ullAvailPhys)/stat.ullTotalPhys + 0.5f ));
1615       int iMemPercentUsed = 100 - iMemPercentFree;
1616
1617       if (info == SYSTEM_FREE_MEMORY)
1618         strLabel.Format("%luMB", (ULONG)(stat.ullAvailPhys/MB));
1619       else if (info == SYSTEM_FREE_MEMORY_PERCENT)
1620         strLabel.Format("%i%%", iMemPercentFree);
1621       else if (info == SYSTEM_USED_MEMORY)
1622         strLabel.Format("%luMB", (ULONG)((stat.ullTotalPhys - stat.ullAvailPhys)/MB));
1623       else if (info == SYSTEM_USED_MEMORY_PERCENT)
1624         strLabel.Format("%i%%", iMemPercentUsed);
1625       else if (info == SYSTEM_TOTAL_MEMORY)
1626         strLabel.Format("%luMB", (ULONG)(stat.ullTotalPhys/MB));
1627     }
1628     break;
1629   case SYSTEM_SCREEN_MODE:
1630     strLabel = g_settings.m_ResInfo[g_graphicsContext.GetVideoResolution()].strMode;
1631     break;
1632   case SYSTEM_SCREEN_WIDTH:
1633     strLabel.Format("%i", g_settings.m_ResInfo[g_graphicsContext.GetVideoResolution()].iScreenWidth);
1634     break;
1635   case SYSTEM_SCREEN_HEIGHT:
1636     strLabel.Format("%i", g_settings.m_ResInfo[g_graphicsContext.GetVideoResolution()].iScreenHeight);
1637     break;
1638   case SYSTEM_CURRENT_WINDOW:
1639     return g_localizeStrings.Get(g_windowManager.GetFocusedWindow());
1640     break;
1641   case SYSTEM_CURRENT_CONTROL:
1642     {
1643       CGUIWindow *window = g_windowManager.GetWindow(g_windowManager.GetFocusedWindow());
1644       if (window)
1645       {
1646         CGUIControl *control = window->GetFocusedControl();
1647         if (control)
1648           strLabel = control->GetDescription();
1649       }
1650     }
1651     break;
1652 #ifdef HAS_DVD_DRIVE
1653   case SYSTEM_DVD_LABEL:
1654     strLabel = g_mediaManager.GetDiskLabel();
1655     break;
1656 #endif
1657   case SYSTEM_ALARM_POS:
1658     if (g_alarmClock.GetRemaining("shutdowntimer") == 0.f)
1659       strLabel = "";
1660     else
1661     {
1662       double fTime = g_alarmClock.GetRemaining("shutdowntimer");
1663       if (fTime > 60.f)
1664         strLabel.Format(g_localizeStrings.Get(13213).c_str(),g_alarmClock.GetRemaining("shutdowntimer")/60.f);
1665       else
1666         strLabel.Format(g_localizeStrings.Get(13214).c_str(),g_alarmClock.GetRemaining("shutdowntimer"));
1667     }
1668     break;
1669   case SYSTEM_PROFILENAME:
1670     strLabel = g_settings.GetCurrentProfile().getName();
1671     break;
1672   case SYSTEM_PROFILECOUNT:
1673     strLabel.Format("%i", g_settings.GetNumProfiles());
1674     break;
1675   case SYSTEM_LANGUAGE:
1676     strLabel = g_guiSettings.GetString("locale.language");
1677     break;
1678   case SYSTEM_TEMPERATURE_UNITS:
1679     strLabel = g_langInfo.GetTempUnitString();
1680     break;
1681   case SYSTEM_PROGRESS_BAR:
1682     {
1683       int percent;
1684       if (GetInt(percent, SYSTEM_PROGRESS_BAR) && percent > 0)
1685         strLabel.Format("%i", percent);
1686     }
1687     break;
1688   case SYSTEM_FRIENDLY_NAME:
1689     {
1690       CStdString friendlyName = g_guiSettings.GetString("services.devicename");
1691       if (friendlyName.Equals("XBMC"))
1692         strLabel.Format("%s (%s)", friendlyName.c_str(), g_application.getNetwork().GetHostName().c_str());
1693       else
1694         strLabel = friendlyName;
1695     }
1696     break;
1697
1698   case SKIN_THEME:
1699     strLabel = g_guiSettings.GetString("lookandfeel.skintheme");
1700     break;
1701   case SKIN_COLOUR_THEME:
1702     strLabel = g_guiSettings.GetString("lookandfeel.skincolors");
1703     break;
1704   case SKIN_ASPECT_RATIO:
1705     if (g_SkinInfo)
1706       strLabel = g_SkinInfo->GetCurrentAspect();
1707     break;
1708   case NETWORK_IP_ADDRESS:
1709     {
1710       CNetworkInterface* iface = g_application.getNetwork().GetFirstConnectedInterface();
1711       if (iface)
1712         return iface->GetCurrentIPAddress();
1713     }
1714     break;
1715   case NETWORK_SUBNET_MASK:
1716     {
1717       CNetworkInterface* iface = g_application.getNetwork().GetFirstConnectedInterface();
1718       if (iface)
1719         return iface->GetCurrentNetmask();
1720     }
1721     break;
1722   case NETWORK_GATEWAY_ADDRESS:
1723     {
1724       CNetworkInterface* iface = g_application.getNetwork().GetFirstConnectedInterface();
1725       if (iface)
1726         return iface->GetCurrentDefaultGateway();
1727     }
1728     break;
1729   case NETWORK_DNS1_ADDRESS:
1730     {
1731       vector<CStdString> nss = g_application.getNetwork().GetNameServers();
1732       if (nss.size() >= 1)
1733         return nss[0];
1734     }
1735     break;
1736   case NETWORK_DNS2_ADDRESS:
1737     {
1738       vector<CStdString> nss = g_application.getNetwork().GetNameServers();
1739       if (nss.size() >= 2)
1740         return nss[1];
1741     }
1742     break;
1743   case NETWORK_DHCP_ADDRESS:
1744     {
1745       CStdString dhcpserver;
1746       return dhcpserver;
1747     }
1748     break;
1749   case NETWORK_LINK_STATE:
1750     {
1751       CStdString linkStatus = g_localizeStrings.Get(151);
1752       linkStatus += " ";
1753       CNetworkInterface* iface = g_application.getNetwork().GetFirstConnectedInterface();
1754       if (iface && iface->IsConnected())
1755         linkStatus += g_localizeStrings.Get(15207);
1756       else
1757         linkStatus += g_localizeStrings.Get(15208);
1758       return linkStatus;
1759     }
1760     break;
1761
1762   case VISUALISATION_PRESET:
1763     {
1764       CGUIMessage msg(GUI_MSG_GET_VISUALISATION, 0, 0);
1765       g_windowManager.SendMessage(msg);
1766       if (msg.GetPointer())
1767       {
1768         CVisualisation* viz = NULL;
1769         viz = (CVisualisation*)msg.GetPointer();
1770         if (viz)
1771         {
1772           strLabel = viz->GetPresetName();
1773           URIUtils::RemoveExtension(strLabel);
1774         }
1775       }
1776     }
1777     break;
1778   case VISUALISATION_NAME:
1779     {
1780       AddonPtr addon;
1781       strLabel = g_guiSettings.GetString("musicplayer.visualisation");
1782       if (CAddonMgr::Get().GetAddon(strLabel,addon) && addon)
1783         strLabel = addon->Name();
1784     }
1785     break;
1786   case FANART_COLOR1:
1787     {
1788       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
1789       if (window)
1790         return ((CGUIMediaWindow *)window)->CurrentDirectory().GetProperty("fanart_color1").asString();
1791     }
1792     break;
1793   case FANART_COLOR2:
1794     {
1795       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
1796       if (window)
1797         return ((CGUIMediaWindow *)window)->CurrentDirectory().GetProperty("fanart_color2").asString();
1798     }
1799     break;
1800   case FANART_COLOR3:
1801     {
1802       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
1803       if (window)
1804         return ((CGUIMediaWindow *)window)->CurrentDirectory().GetProperty("fanart_color3").asString();
1805     }
1806     break;
1807   case FANART_IMAGE:
1808     {
1809       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
1810       if (window)
1811         return ((CGUIMediaWindow *)window)->CurrentDirectory().GetArt("fanart");
1812     }
1813     break;
1814   case SYSTEM_RENDER_VENDOR:
1815     strLabel = g_Windowing.GetRenderVendor();
1816     break;
1817   case SYSTEM_RENDER_RENDERER:
1818     strLabel = g_Windowing.GetRenderRenderer();
1819     break;
1820   case SYSTEM_RENDER_VERSION:
1821     strLabel = g_Windowing.GetRenderVersionString();
1822     break;
1823   }
1824
1825   return strLabel;
1826 }
1827
1828 // tries to get a integer value for use in progressbars/sliders and such
1829 bool CGUIInfoManager::GetInt(int &value, int info, int contextWindow, const CGUIListItem *item /* = NULL */) const
1830 {
1831   if (info >= MULTI_INFO_START && info <= MULTI_INFO_END)
1832     return GetMultiInfoInt(value, m_multiInfo[info - MULTI_INFO_START], contextWindow);
1833
1834   if (info >= LISTITEM_START && info <= LISTITEM_END)
1835     return GetItemInt(value, item, info);
1836
1837   value = 0;
1838   switch( info )
1839   {
1840     case PLAYER_VOLUME:
1841       value = g_application.GetVolume();
1842       return true;
1843     case PLAYER_SUBTITLE_DELAY:
1844       value = g_application.GetSubtitleDelay();
1845       return true;
1846     case PLAYER_AUDIO_DELAY:
1847       value = g_application.GetAudioDelay();
1848       return true;
1849     case PLAYER_PROGRESS:
1850     case PLAYER_PROGRESS_CACHE:
1851     case PLAYER_SEEKBAR:
1852     case PLAYER_CACHELEVEL:
1853     case PLAYER_CHAPTER:
1854     case PLAYER_CHAPTERCOUNT:
1855       {
1856         if( g_application.IsPlaying() && g_application.m_pPlayer)
1857         {
1858           switch( info )
1859           {
1860           case PLAYER_PROGRESS:
1861             value = (int)(g_application.GetPercentage());
1862             break;
1863           case PLAYER_PROGRESS_CACHE:
1864             value = (int)(g_application.GetCachePercentage());
1865             break;
1866           case PLAYER_SEEKBAR:
1867             value = (int)g_application.GetSeekHandler()->GetPercent();
1868             break;
1869           case PLAYER_CACHELEVEL:
1870             value = (int)(g_application.m_pPlayer->GetCacheLevel());
1871             break;
1872           case PLAYER_CHAPTER:
1873             value = g_application.m_pPlayer->GetChapter();
1874             break;
1875           case PLAYER_CHAPTERCOUNT:
1876             value = g_application.m_pPlayer->GetChapterCount();
1877             break;
1878           }
1879         }
1880       }
1881       return true;
1882     case SYSTEM_FREE_MEMORY:
1883     case SYSTEM_USED_MEMORY:
1884       {
1885         MEMORYSTATUSEX stat;
1886         stat.dwLength = sizeof(MEMORYSTATUSEX);
1887         GlobalMemoryStatusEx(&stat);
1888         int memPercentUsed = (int)( 100.0f* (stat.ullTotalPhys - stat.ullAvailPhys)/stat.ullTotalPhys + 0.5f );
1889         if (info == SYSTEM_FREE_MEMORY)
1890           value = 100 - memPercentUsed;
1891         else
1892           value = memPercentUsed;
1893         return true;
1894       }
1895     case SYSTEM_PROGRESS_BAR:
1896       {
1897         CGUIDialogProgress *bar = (CGUIDialogProgress *)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
1898         if (bar && bar->IsDialogRunning())
1899           value = bar->GetPercentage();
1900         return true;
1901       }
1902     case SYSTEM_FREE_SPACE:
1903     case SYSTEM_USED_SPACE:
1904       {
1905         g_sysinfo.GetHddSpaceInfo(value, info, true);
1906         return true;
1907       }
1908     case SYSTEM_CPU_USAGE:
1909       value = g_cpuInfo.getUsedPercentage();
1910       return true;
1911     case PVR_PLAYING_PROGRESS:
1912     case PVR_ACTUAL_STREAM_SIG_PROGR:
1913     case PVR_ACTUAL_STREAM_SNR_PROGR:
1914       value = g_PVRManager.TranslateIntInfo(info);
1915       return true;
1916     case SYSTEM_BATTERY_LEVEL:
1917       value = g_powerManager.BatteryLevel();
1918       return true;
1919   }
1920   return false;
1921 }
1922
1923 unsigned int CGUIInfoManager::Register(const CStdString &expression, int context)
1924 {
1925   CStdString condition(CGUIInfoLabel::ReplaceLocalize(expression));
1926   condition.TrimLeft(" \t\r\n");
1927   condition.TrimRight(" \t\r\n");
1928
1929   if (condition.IsEmpty())
1930     return 0;
1931
1932   CSingleLock lock(m_critInfo);
1933   // do we have the boolean expression already registered?
1934   InfoBool test(condition, context);
1935   for (unsigned int i = 0; i < m_bools.size(); ++i)
1936   {
1937     if (*m_bools[i] == test)
1938       return i+1;
1939   }
1940
1941   if (condition.find_first_of("|+[]!") != condition.npos)
1942     m_bools.push_back(new InfoExpression(condition, context));
1943   else
1944     m_bools.push_back(new InfoSingle(condition, context));
1945
1946   return m_bools.size();
1947 }
1948
1949 bool CGUIInfoManager::EvaluateBool(const CStdString &expression, int contextWindow)
1950 {
1951   bool result = false;
1952   unsigned int info = Register(expression, contextWindow);
1953   if (info)
1954     result = GetBoolValue(info);
1955   return result;
1956 }
1957
1958 /*
1959  TODO: what to do with item-based infobools...
1960  these crop up:
1961  1. if condition is between LISTITEM_START and LISTITEM_END
1962  2. if condition is STRING_IS_EMPTY, STRING_COMPARE, STRING_STR, INTEGER_GREATER_THAN and the
1963     corresponding label is between LISTITEM_START and LISTITEM_END
1964
1965  In both cases they shouldn't be in our cache as they depend on items outside of our control atm.
1966
1967  We only pass a listitem object in for controls inside a listitemlayout, so I think it's probably OK
1968  to not cache these, as they're "pushed" out anyway.
1969
1970  The problem is how do we avoid these?  The only thing we have to go on is the expression here, so I
1971  guess what we have to do is call through via Update.  One thing we don't handle, however, is that the
1972  majority of conditions (even inside lists) don't depend on the listitem at all.
1973
1974  Advantage is that we know this at creation time I think, so could perhaps signal it in IsDirty()?
1975  */
1976 bool CGUIInfoManager::GetBoolValue(unsigned int expression, const CGUIListItem *item)
1977 {
1978   if (expression && --expression < m_bools.size())
1979     return m_bools[expression]->Get(m_updateTime, item);
1980   return false;
1981 }
1982
1983 // checks the condition and returns it as necessary.  Currently used
1984 // for toggle button controls and visibility of images.
1985 bool CGUIInfoManager::GetBool(int condition1, int contextWindow, const CGUIListItem *item)
1986 {
1987   bool bReturn = false;
1988   int condition = abs(condition1);
1989
1990   if (item && condition >= LISTITEM_START && condition < LISTITEM_END)
1991     bReturn = GetItemBool(item, condition);
1992   // Ethernet Link state checking
1993   // Will check if system has a Ethernet Link connection! [Cable in!]
1994   // This can used for the skinner to switch off Network or Inter required functions
1995   else if ( condition == SYSTEM_ALWAYS_TRUE)
1996     bReturn = true;
1997   else if (condition == SYSTEM_ALWAYS_FALSE)
1998     bReturn = false;
1999   else if (condition == SYSTEM_ETHERNET_LINK_ACTIVE)
2000     bReturn = true;
2001   else if (condition == WINDOW_IS_MEDIA)
2002   { // note: This doesn't return true for dialogs (content, favourites, login, videoinfo)
2003     CGUIWindow *pWindow = g_windowManager.GetWindow(g_windowManager.GetActiveWindow());
2004     bReturn = (pWindow && pWindow->IsMediaWindow());
2005   }
2006   else if (condition == PLAYER_MUTED)
2007     bReturn = g_settings.m_bMute;
2008   else if (condition >= LIBRARY_HAS_MUSIC && condition <= LIBRARY_HAS_MUSICVIDEOS)
2009     bReturn = GetLibraryBool(condition);
2010   else if (condition == LIBRARY_IS_SCANNING)
2011   {
2012     if (g_application.IsMusicScanning() || g_application.IsVideoScanning())
2013       bReturn = true;
2014     else
2015       bReturn = false;
2016   }
2017   else if (condition == LIBRARY_IS_SCANNING_VIDEO)
2018   {
2019     bReturn = g_application.IsVideoScanning();
2020   }
2021   else if (condition == LIBRARY_IS_SCANNING_MUSIC)
2022   {
2023     bReturn = g_application.IsMusicScanning();
2024   }
2025   else if (condition == SYSTEM_PLATFORM_LINUX)
2026 #if defined(_LINUX) && !defined(TARGET_DARWIN) && !defined(TARGET_ANDROID)
2027     bReturn = true;
2028 #else
2029     bReturn = false;
2030 #endif
2031   else if (condition == SYSTEM_PLATFORM_WINDOWS)
2032 #ifdef WIN32
2033     bReturn = true;
2034 #else
2035     bReturn = false;
2036 #endif
2037   else if (condition == SYSTEM_PLATFORM_DARWIN)
2038 #ifdef TARGET_DARWIN
2039     bReturn = true;
2040 #else
2041     bReturn = false;
2042 #endif
2043   else if (condition == SYSTEM_PLATFORM_DARWIN_OSX)
2044 #ifdef TARGET_DARWIN_OSX
2045     bReturn = true;
2046 #else
2047     bReturn = false;
2048 #endif
2049   else if (condition == SYSTEM_PLATFORM_DARWIN_IOS)
2050 #ifdef TARGET_DARWIN_IOS
2051     bReturn = true;
2052 #else
2053     bReturn = false;
2054 #endif
2055   else if (condition == SYSTEM_PLATFORM_DARWIN_ATV2)
2056 #ifdef TARGET_DARWIN_IOS_ATV2
2057     bReturn = true;
2058 #else
2059     bReturn = false;
2060 #endif
2061   else if (condition == SYSTEM_PLATFORM_ANDROID)
2062 #if defined(TARGET_ANDROID)
2063     bReturn = true;
2064 #else
2065     bReturn = false;
2066 #endif
2067   else if (condition == SYSTEM_MEDIA_DVD)
2068     bReturn = g_mediaManager.IsDiscInDrive();
2069 #ifdef HAS_DVD_DRIVE
2070   else if (condition == SYSTEM_DVDREADY)
2071     bReturn = g_mediaManager.GetDriveStatus() != DRIVE_NOT_READY;
2072   else if (condition == SYSTEM_TRAYOPEN)
2073     bReturn = g_mediaManager.GetDriveStatus() == DRIVE_OPEN;
2074 #endif
2075   else if (condition == SYSTEM_CAN_POWERDOWN)
2076     bReturn = g_powerManager.CanPowerdown();
2077   else if (condition == SYSTEM_CAN_SUSPEND)
2078     bReturn = g_powerManager.CanSuspend();
2079   else if (condition == SYSTEM_CAN_HIBERNATE)
2080     bReturn = g_powerManager.CanHibernate();
2081   else if (condition == SYSTEM_CAN_REBOOT)
2082     bReturn = g_powerManager.CanReboot();
2083   else if (condition == SYSTEM_SCREENSAVER_ACTIVE)
2084     bReturn = g_application.IsInScreenSaver();
2085
2086   else if (condition == PLAYER_SHOWINFO)
2087     bReturn = m_playerShowInfo;
2088   else if (condition == PLAYER_SHOWCODEC)
2089     bReturn = m_playerShowCodec;
2090   else if (condition >= MULTI_INFO_START && condition <= MULTI_INFO_END)
2091   {
2092     return GetMultiInfoBool(m_multiInfo[condition - MULTI_INFO_START], contextWindow, item);
2093   }
2094   else if (condition == SYSTEM_HASLOCKS)
2095     bReturn = g_settings.GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE;
2096   else if (condition == SYSTEM_HAS_PVR)
2097     bReturn = true;
2098   else if (condition == SYSTEM_ISMASTER)
2099     bReturn = g_settings.GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE && g_passwordManager.bMasterUser;
2100   else if (condition == SYSTEM_ISFULLSCREEN)
2101     bReturn = g_Windowing.IsFullScreen();
2102   else if (condition == SYSTEM_ISSTANDALONE)
2103     bReturn = g_application.IsStandAlone();
2104   else if (condition == SYSTEM_ISINHIBIT)
2105     bReturn = g_application.IsIdleShutdownInhibited();
2106   else if (condition == SYSTEM_HAS_SHUTDOWN)
2107     bReturn = (g_guiSettings.GetInt("powermanagement.shutdowntime") > 0);
2108   else if (condition == SYSTEM_LOGGEDON)
2109     bReturn = !(g_windowManager.GetActiveWindow() == WINDOW_LOGIN_SCREEN);
2110   else if (condition == SYSTEM_SHOW_EXIT_BUTTON)
2111     bReturn = g_advancedSettings.m_showExitButton;
2112   else if (condition == SYSTEM_HAS_LOGINSCREEN)
2113     bReturn = g_settings.UsingLoginScreen();
2114   else if (condition == WEATHER_IS_FETCHED)
2115     bReturn = g_weatherManager.IsFetched();
2116   else if (condition >= PVR_CONDITIONS_START && condition <= PVR_CONDITIONS_END)
2117     bReturn = g_PVRManager.TranslateBoolInfo(condition);
2118
2119   else if (condition == SYSTEM_INTERNET_STATE)
2120   {
2121     g_sysinfo.GetInfo(condition);
2122     bReturn = g_sysinfo.HasInternet();
2123   }
2124   else if (condition == SKIN_HAS_VIDEO_OVERLAY)
2125   {
2126     bReturn = g_windowManager.IsOverlayAllowed() && g_application.IsPlayingVideo();
2127   }
2128   else if (condition == SKIN_HAS_MUSIC_OVERLAY)
2129   {
2130     bReturn = g_windowManager.IsOverlayAllowed() && g_application.IsPlayingAudio();
2131   }
2132   else if (condition == CONTAINER_HASFILES || condition == CONTAINER_HASFOLDERS)
2133   {
2134     CGUIWindow *pWindow = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2135     if (pWindow)
2136     {
2137       const CFileItemList& items=((CGUIMediaWindow*)pWindow)->CurrentDirectory();
2138       for (int i=0;i<items.Size();++i)
2139       {
2140         CFileItemPtr item=items.Get(i);
2141         if (!item->m_bIsFolder && condition == CONTAINER_HASFILES)
2142         {
2143           bReturn=true;
2144           break;
2145         }
2146         else if (item->m_bIsFolder && !item->IsParentFolder() && condition == CONTAINER_HASFOLDERS)
2147         {
2148           bReturn=true;
2149           break;
2150         }
2151       }
2152     }
2153   }
2154   else if (condition == CONTAINER_STACKED)
2155   {
2156     CGUIWindow *pWindow = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2157     if (pWindow)
2158       bReturn = ((CGUIMediaWindow*)pWindow)->CurrentDirectory().GetProperty("isstacked").asBoolean();
2159   }
2160   else if (condition == CONTAINER_HAS_THUMB)
2161   {
2162     CGUIWindow *pWindow = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2163     if (pWindow)
2164       bReturn = ((CGUIMediaWindow*)pWindow)->CurrentDirectory().HasArt("thumb");
2165   }
2166   else if (condition == CONTAINER_HAS_NEXT || condition == CONTAINER_HAS_PREVIOUS || condition == CONTAINER_SCROLLING)
2167   {
2168     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2169     if (window)
2170     {
2171       const CGUIControl* control = window->GetControl(window->GetViewContainerID());
2172       if (control)
2173         bReturn = control->GetCondition(condition, 0);
2174     }
2175   }
2176   else if (condition == CONTAINER_CAN_FILTER)
2177   {
2178     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2179     if (window)
2180       bReturn = !((CGUIMediaWindow*)window)->CanFilterAdvanced();
2181   }
2182   else if (condition == CONTAINER_CAN_FILTERADVANCED)
2183   {
2184     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2185     if (window)
2186       bReturn = ((CGUIMediaWindow*)window)->CanFilterAdvanced();
2187   }
2188   else if (condition == CONTAINER_FILTERED)
2189   {
2190     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2191     if (window)
2192       bReturn = ((CGUIMediaWindow*)window)->IsFiltered();
2193   }
2194   else if (condition == VIDEOPLAYER_HAS_INFO)
2195     bReturn = ((m_currentFile->HasVideoInfoTag() && !m_currentFile->GetVideoInfoTag()->IsEmpty()) ||
2196                (m_currentFile->HasPVRChannelInfoTag()  && !m_currentFile->GetPVRChannelInfoTag()->IsEmpty()));
2197   else if (condition >= CONTAINER_SCROLL_PREVIOUS && condition <= CONTAINER_SCROLL_NEXT)
2198   {
2199     // no parameters, so we assume it's just requested for a media window.  It therefore
2200     // can only happen if the list has focus.
2201     CGUIWindow *pWindow = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2202     if (pWindow)
2203     {
2204       map<int,int>::const_iterator it = m_containerMoves.find(pWindow->GetViewContainerID());
2205       if (it != m_containerMoves.end())
2206       {
2207         if (condition > CONTAINER_STATIC) // moving up
2208           bReturn = it->second >= std::max(condition - CONTAINER_STATIC, 1);
2209         else
2210           bReturn = it->second <= std::min(condition - CONTAINER_STATIC, -1);
2211       }
2212     }
2213   }
2214   else if (condition == SLIDESHOW_ISPAUSED)
2215   {
2216     CGUIWindowSlideShow *slideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
2217     bReturn = (slideShow && slideShow->IsPaused());
2218   }
2219   else if (condition == SLIDESHOW_ISRANDOM)
2220   {
2221     CGUIWindowSlideShow *slideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
2222     bReturn = (slideShow && slideShow->IsShuffled());
2223   }
2224   else if (condition == SLIDESHOW_ISACTIVE)
2225   {
2226     CGUIWindowSlideShow *slideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
2227     bReturn = (slideShow && slideShow->InSlideShow());
2228   }
2229   else if (g_application.IsPlaying())
2230   {
2231     switch (condition)
2232     {
2233     case PLAYER_HAS_MEDIA:
2234       bReturn = true;
2235       break;
2236     case PLAYER_HAS_AUDIO:
2237       bReturn = g_application.IsPlayingAudio();
2238       break;
2239     case PLAYER_HAS_VIDEO:
2240       bReturn = g_application.IsPlayingVideo();
2241       break;
2242     case PLAYER_PLAYING:
2243       bReturn = !g_application.IsPaused() && (g_application.GetPlaySpeed() == 1);
2244       break;
2245     case PLAYER_PAUSED:
2246       bReturn = g_application.IsPaused();
2247       break;
2248     case PLAYER_REWINDING:
2249       bReturn = !g_application.IsPaused() && g_application.GetPlaySpeed() < 1;
2250       break;
2251     case PLAYER_FORWARDING:
2252       bReturn = !g_application.IsPaused() && g_application.GetPlaySpeed() > 1;
2253       break;
2254     case PLAYER_REWINDING_2x:
2255       bReturn = !g_application.IsPaused() && g_application.GetPlaySpeed() == -2;
2256       break;
2257     case PLAYER_REWINDING_4x:
2258       bReturn = !g_application.IsPaused() && g_application.GetPlaySpeed() == -4;
2259       break;
2260     case PLAYER_REWINDING_8x:
2261       bReturn = !g_application.IsPaused() && g_application.GetPlaySpeed() == -8;
2262       break;
2263     case PLAYER_REWINDING_16x:
2264       bReturn = !g_application.IsPaused() && g_application.GetPlaySpeed() == -16;
2265       break;
2266     case PLAYER_REWINDING_32x:
2267       bReturn = !g_application.IsPaused() && g_application.GetPlaySpeed() == -32;
2268       break;
2269     case PLAYER_FORWARDING_2x:
2270       bReturn = !g_application.IsPaused() && g_application.GetPlaySpeed() == 2;
2271       break;
2272     case PLAYER_FORWARDING_4x:
2273       bReturn = !g_application.IsPaused() && g_application.GetPlaySpeed() == 4;
2274       break;
2275     case PLAYER_FORWARDING_8x:
2276       bReturn = !g_application.IsPaused() && g_application.GetPlaySpeed() == 8;
2277       break;
2278     case PLAYER_FORWARDING_16x:
2279       bReturn = !g_application.IsPaused() && g_application.GetPlaySpeed() == 16;
2280       break;
2281     case PLAYER_FORWARDING_32x:
2282       bReturn = !g_application.IsPaused() && g_application.GetPlaySpeed() == 32;
2283       break;
2284     case PLAYER_CAN_RECORD:
2285       bReturn = g_application.m_pPlayer->CanRecord();
2286       break;
2287     case PLAYER_CAN_PAUSE:
2288       bReturn = g_application.m_pPlayer->CanPause();
2289       break;
2290     case PLAYER_CAN_SEEK:
2291       bReturn = g_application.m_pPlayer->CanSeek();
2292       break;
2293     case PLAYER_RECORDING:
2294       bReturn = g_application.m_pPlayer->IsRecording();
2295     break;
2296     case PLAYER_DISPLAY_AFTER_SEEK:
2297       bReturn = GetDisplayAfterSeek();
2298     break;
2299     case PLAYER_CACHING:
2300       bReturn = g_application.m_pPlayer->IsCaching();
2301     break;
2302     case PLAYER_SEEKBAR:
2303       {
2304         CGUIDialog *seekBar = (CGUIDialog*)g_windowManager.GetWindow(WINDOW_DIALOG_SEEK_BAR);
2305         bReturn = seekBar ? seekBar->IsDialogRunning() : false;
2306       }
2307     break;
2308     case PLAYER_SEEKING:
2309       bReturn = m_playerSeeking;
2310     break;
2311     case PLAYER_SHOWTIME:
2312       bReturn = m_playerShowTime;
2313     break;
2314     case PLAYER_PASSTHROUGH:
2315       bReturn = g_application.m_pPlayer && g_application.m_pPlayer->IsPassthrough();
2316       break;
2317     case MUSICPM_ENABLED:
2318       bReturn = g_partyModeManager.IsEnabled();
2319     break;
2320     case MUSICPLAYER_HASPREVIOUS:
2321       {
2322         // requires current playlist be PLAYLIST_MUSIC
2323         bReturn = false;
2324         if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_MUSIC)
2325           bReturn = (g_playlistPlayer.GetCurrentSong() > 0); // not first song
2326       }
2327       break;
2328     case MUSICPLAYER_HASNEXT:
2329       {
2330         // requires current playlist be PLAYLIST_MUSIC
2331         bReturn = false;
2332         if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_MUSIC)
2333           bReturn = (g_playlistPlayer.GetCurrentSong() < (g_playlistPlayer.GetPlaylist(PLAYLIST_MUSIC).size() - 1)); // not last song
2334       }
2335       break;
2336     case MUSICPLAYER_PLAYLISTPLAYING:
2337       {
2338         bReturn = false;
2339         if (g_application.IsPlayingAudio() && g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_MUSIC)
2340           bReturn = true;
2341       }
2342       break;
2343     case VIDEOPLAYER_USING_OVERLAYS:
2344       bReturn = (g_guiSettings.GetInt("videoplayer.rendermethod") == RENDER_OVERLAYS);
2345     break;
2346     case VIDEOPLAYER_ISFULLSCREEN:
2347       bReturn = g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO;
2348     break;
2349     case VIDEOPLAYER_HASMENU:
2350       bReturn = g_application.m_pPlayer->HasMenu();
2351     break;
2352     case PLAYLIST_ISRANDOM:
2353       bReturn = g_playlistPlayer.IsShuffled(g_playlistPlayer.GetCurrentPlaylist());
2354     break;
2355     case PLAYLIST_ISREPEAT:
2356       bReturn = g_playlistPlayer.GetRepeat(g_playlistPlayer.GetCurrentPlaylist()) == PLAYLIST::REPEAT_ALL;
2357     break;
2358     case PLAYLIST_ISREPEATONE:
2359       bReturn = g_playlistPlayer.GetRepeat(g_playlistPlayer.GetCurrentPlaylist()) == PLAYLIST::REPEAT_ONE;
2360     break;
2361     case PLAYER_HASDURATION:
2362       bReturn = g_application.GetTotalTime() > 0;
2363       break;
2364     case VIDEOPLAYER_HASTELETEXT:
2365       if (g_application.m_pPlayer->GetTeletextCache())
2366         bReturn = true;
2367       break;
2368     case VIDEOPLAYER_HASSUBTITLES:
2369       bReturn = g_application.m_pPlayer->GetSubtitleCount() > 0;
2370       break;
2371     case VIDEOPLAYER_SUBTITLESENABLED:
2372       bReturn = g_application.m_pPlayer->GetSubtitleVisible();
2373       break;
2374     case VISUALISATION_LOCKED:
2375       {
2376         CGUIMessage msg(GUI_MSG_GET_VISUALISATION, 0, 0);
2377         g_windowManager.SendMessage(msg);
2378         if (msg.GetPointer())
2379         {
2380           CVisualisation *pVis = (CVisualisation *)msg.GetPointer();
2381           bReturn = pVis->IsLocked();
2382         }
2383       }
2384     break;
2385     case VISUALISATION_ENABLED:
2386       bReturn = !g_guiSettings.GetString("musicplayer.visualisation").IsEmpty();
2387     break;
2388     case VIDEOPLAYER_HAS_EPG:
2389       if (m_currentFile->HasPVRChannelInfoTag())
2390       {
2391         CEpgInfoTag epgTag;
2392         bReturn = m_currentFile->GetPVRChannelInfoTag()->GetEPGNow(epgTag);
2393       }
2394     break;
2395     default: // default, use integer value different from 0 as true
2396       {
2397         int val;
2398         bReturn = GetInt(val, condition) && val != 0;
2399       }
2400     }
2401   }
2402   if (condition1 < 0)
2403     bReturn = !bReturn;
2404   return bReturn;
2405 }
2406
2407 /// \brief Examines the multi information sent and returns true or false accordingly.
2408 bool CGUIInfoManager::GetMultiInfoBool(const GUIInfo &info, int contextWindow, const CGUIListItem *item)
2409 {
2410   bool bReturn = false;
2411   int condition = abs(info.m_info);
2412
2413   if (condition >= LISTITEM_START && condition <= LISTITEM_END)
2414   {
2415     if (!item)
2416     {
2417       CGUIWindow *window = NULL;
2418       int data1 = info.GetData1();
2419       if (!data1) // No container specified, so we lookup the current view container
2420       {
2421         window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_HAS_LIST_ITEMS);
2422         if (window && window->IsMediaWindow())
2423           data1 = ((CGUIMediaWindow*)(window))->GetViewContainerID();
2424       }
2425
2426       if (!window) // If we don't have a window already (from lookup above), get one
2427         window = GetWindowWithCondition(contextWindow, 0);
2428
2429       if (window)
2430       {
2431         const CGUIControl *control = window->GetControl(data1);
2432         if (control && control->IsContainer())
2433           item = ((IGUIContainer *)control)->GetListItem(info.GetData2(), info.GetInfoFlag()).get();
2434       }
2435     }
2436     if (item) // If we got a valid item, do the lookup
2437       bReturn = GetItemBool(item, condition); // Image prioritizes images over labels (in the case of music item ratings for instance)
2438   }
2439   else
2440   {
2441     switch (condition)
2442     {
2443       case SKIN_BOOL:
2444         {
2445           bReturn = g_settings.GetSkinBool(info.GetData1());
2446         }
2447         break;
2448       case SKIN_STRING:
2449         {
2450           if (info.GetData2())
2451             bReturn = g_settings.GetSkinString(info.GetData1()).Equals(m_stringParameters[info.GetData2()]);
2452           else
2453             bReturn = !g_settings.GetSkinString(info.GetData1()).IsEmpty();
2454         }
2455         break;
2456       case SKIN_HAS_THEME:
2457         {
2458           CStdString theme = g_guiSettings.GetString("lookandfeel.skintheme");
2459           theme.ToLower();
2460           URIUtils::RemoveExtension(theme);
2461           bReturn = theme.Equals(m_stringParameters[info.GetData1()]);
2462         }
2463         break;
2464       case STRING_IS_EMPTY:
2465         // note: Get*Image() falls back to Get*Label(), so this should cover all of them
2466         if (item && item->IsFileItem() && info.GetData1() >= LISTITEM_START && info.GetData1() < LISTITEM_END)
2467           bReturn = GetItemImage((const CFileItem *)item, info.GetData1()).IsEmpty();
2468         else
2469           bReturn = GetImage(info.GetData1(), contextWindow).IsEmpty();
2470         break;
2471       case STRING_COMPARE:
2472         {
2473           CStdString compare;
2474           if (info.GetData2() < 0) // info labels are stored with negative numbers
2475           {
2476             int info2 = -info.GetData2();
2477             if (item && item->IsFileItem() && info2 >= LISTITEM_START && info2 < LISTITEM_END)
2478               compare = GetItemImage((const CFileItem *)item, info2);
2479             else
2480               compare = GetImage(info2, contextWindow);
2481           }
2482           else if (info.GetData2() < (int)m_stringParameters.size())
2483           { // conditional string
2484             compare = m_stringParameters[info.GetData2()];
2485           }
2486           if (item && item->IsFileItem() && info.GetData1() >= LISTITEM_START && info.GetData1() < LISTITEM_END)
2487             bReturn = GetItemImage((const CFileItem *)item, info.GetData1()).Equals(compare);
2488           else
2489             bReturn = GetImage(info.GetData1(), contextWindow).Equals(compare);
2490         }
2491         break;
2492       case INTEGER_GREATER_THAN:
2493         {
2494           int integer;
2495           if (GetInt(integer, info.GetData1(), contextWindow, item))
2496             bReturn = integer > info.GetData2();
2497           else
2498           {
2499             CStdString value;
2500
2501             if (item && item->IsFileItem() && info.GetData1() >= LISTITEM_START && info.GetData1() < LISTITEM_END)
2502               value = GetItemImage((const CFileItem *)item, info.GetData1());
2503             else
2504               value = GetImage(info.GetData1(), contextWindow);
2505
2506             // Handle the case when a value contains time separator (:). This makes IntegerGreaterThan
2507             // useful for Player.Time* members without adding a separate set of members returning time in seconds
2508             if ( value.find_first_of( ':' ) != value.npos )
2509               bReturn = StringUtils::TimeStringToSeconds( value ) > info.GetData2();
2510             else
2511               bReturn = atoi( value.c_str() ) > info.GetData2();
2512           }
2513         }
2514         break;
2515       case STRING_STR:
2516       case STRING_STR_LEFT:
2517       case STRING_STR_RIGHT:
2518         {
2519           CStdString compare = m_stringParameters[info.GetData2()];
2520           // our compare string is already in lowercase, so lower case our label as well
2521           // as CStdString::Find() is case sensitive
2522           CStdString label;
2523           if (item && item->IsFileItem() && info.GetData1() >= LISTITEM_START && info.GetData1() < LISTITEM_END)
2524             label = GetItemImage((const CFileItem *)item, info.GetData1()).ToLower();
2525           else
2526             label = GetImage(info.GetData1(), contextWindow).ToLower();
2527           if (condition == STRING_STR_LEFT)
2528             bReturn = label.Find(compare) == 0;
2529           else if (condition == STRING_STR_RIGHT)
2530             bReturn = label.Find(compare) == (int)(label.size()-compare.size());
2531           else
2532             bReturn = label.Find(compare) > -1;
2533         }
2534         break;
2535       case SYSTEM_ALARM_LESS_OR_EQUAL:
2536         {
2537           int time = lrint(g_alarmClock.GetRemaining(m_stringParameters[info.GetData1()]));
2538           int timeCompare = atoi(m_stringParameters[info.GetData2()]);
2539           if (time > 0)
2540             bReturn = timeCompare >= time;
2541           else
2542             bReturn = false;
2543         }
2544         break;
2545       case SYSTEM_IDLE_TIME:
2546         bReturn = g_application.GlobalIdleTime() >= (int)info.GetData1();
2547         break;
2548       case CONTROL_GROUP_HAS_FOCUS:
2549         {
2550           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2551           if (window)
2552             bReturn = window->ControlGroupHasFocus(info.GetData1(), info.GetData2());
2553         }
2554         break;
2555       case CONTROL_IS_VISIBLE:
2556         {
2557           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2558           if (window)
2559           {
2560             // Note: This'll only work for unique id's
2561             const CGUIControl *control = window->GetControl(info.GetData1());
2562             if (control)
2563               bReturn = control->IsVisible();
2564           }
2565         }
2566         break;
2567       case CONTROL_IS_ENABLED:
2568         {
2569           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2570           if (window)
2571           {
2572             // Note: This'll only work for unique id's
2573             const CGUIControl *control = window->GetControl(info.GetData1());
2574             if (control)
2575               bReturn = !control->IsDisabled();
2576           }
2577         }
2578         break;
2579       case CONTROL_HAS_FOCUS:
2580         {
2581           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2582           if (window)
2583             bReturn = (window->GetFocusedControlID() == (int)info.GetData1());
2584         }
2585         break;
2586       case WINDOW_NEXT:
2587         if (info.GetData1())
2588           bReturn = ((int)info.GetData1() == m_nextWindowID);
2589         else
2590         {
2591           CGUIWindow *window = g_windowManager.GetWindow(m_nextWindowID);
2592           if (window && URIUtils::GetFileName(window->GetProperty("xmlfile").asString()).Equals(m_stringParameters[info.GetData2()]))
2593             bReturn = true;
2594         }
2595         break;
2596       case WINDOW_PREVIOUS:
2597         if (info.GetData1())
2598           bReturn = ((int)info.GetData1() == m_prevWindowID);
2599         else
2600         {
2601           CGUIWindow *window = g_windowManager.GetWindow(m_prevWindowID);
2602           if (window && URIUtils::GetFileName(window->GetProperty("xmlfile").asString()).Equals(m_stringParameters[info.GetData2()]))
2603             bReturn = true;
2604         }
2605         break;
2606       case WINDOW_IS_VISIBLE:
2607         if (info.GetData1())
2608           bReturn = g_windowManager.IsWindowVisible(info.GetData1());
2609         else
2610           bReturn = g_windowManager.IsWindowVisible(m_stringParameters[info.GetData2()]);
2611         break;
2612       case WINDOW_IS_TOPMOST:
2613         if (info.GetData1())
2614           bReturn = g_windowManager.IsWindowTopMost(info.GetData1());
2615         else
2616           bReturn = g_windowManager.IsWindowTopMost(m_stringParameters[info.GetData2()]);
2617         break;
2618       case WINDOW_IS_ACTIVE:
2619         if (info.GetData1())
2620           bReturn = g_windowManager.IsWindowActive(info.GetData1());
2621         else
2622           bReturn = g_windowManager.IsWindowActive(m_stringParameters[info.GetData2()]);
2623         break;
2624       case SYSTEM_HAS_ALARM:
2625         bReturn = g_alarmClock.HasAlarm(m_stringParameters[info.GetData1()]);
2626         break;
2627       case SYSTEM_GET_BOOL:
2628         bReturn = g_guiSettings.GetBool(m_stringParameters[info.GetData1()]);
2629         break;
2630       case SYSTEM_HAS_CORE_ID:
2631         bReturn = g_cpuInfo.HasCoreId(info.GetData1());
2632         break;
2633       case SYSTEM_SETTING:
2634         {
2635           if ( m_stringParameters[info.GetData1()].Equals("hidewatched") )
2636           {
2637             CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2638             if (window)
2639               bReturn = g_settings.GetWatchMode(((CGUIMediaWindow *)window)->CurrentDirectory().GetContent()) == VIDEO_SHOW_UNWATCHED;
2640           }
2641         }
2642         break;
2643       case SYSTEM_HAS_ADDON:
2644       {
2645         AddonPtr addon;
2646         bReturn = CAddonMgr::Get().GetAddon(m_stringParameters[info.GetData1()],addon) && addon;
2647         break;
2648       }
2649       case CONTAINER_SCROLL_PREVIOUS:
2650       case CONTAINER_MOVE_PREVIOUS:
2651       case CONTAINER_MOVE_NEXT:
2652       case CONTAINER_SCROLL_NEXT:
2653         {
2654           map<int,int>::const_iterator it = m_containerMoves.find(info.GetData1());
2655           if (it != m_containerMoves.end())
2656           {
2657             if (condition > CONTAINER_STATIC) // moving up
2658               bReturn = it->second >= std::max(condition - CONTAINER_STATIC, 1);
2659             else
2660               bReturn = it->second <= std::min(condition - CONTAINER_STATIC, -1);
2661           }
2662         }
2663         break;
2664       case CONTAINER_CONTENT:
2665         {
2666           CStdString content;
2667           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2668           if (window)
2669           {
2670             if (window->GetID() == WINDOW_DIALOG_MUSIC_INFO)
2671               content = ((CGUIDialogMusicInfo *)window)->CurrentDirectory().GetContent();
2672             else if (window->GetID() == WINDOW_DIALOG_VIDEO_INFO)
2673               content = ((CGUIDialogVideoInfo *)window)->CurrentDirectory().GetContent();
2674           }
2675           if (content.IsEmpty())
2676           {
2677             window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2678             if (window)
2679               content = ((CGUIMediaWindow *)window)->CurrentDirectory().GetContent();
2680           }
2681           bReturn = m_stringParameters[info.GetData2()].Equals(content);
2682         }
2683         break;
2684       case CONTAINER_ROW:
2685       case CONTAINER_COLUMN:
2686       case CONTAINER_POSITION:
2687       case CONTAINER_HAS_NEXT:
2688       case CONTAINER_HAS_PREVIOUS:
2689       case CONTAINER_SCROLLING:
2690       case CONTAINER_SUBITEM:
2691         {
2692           const CGUIControl *control = NULL;
2693           if (info.GetData1())
2694           { // container specified
2695             CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2696             if (window)
2697               control = window->GetControl(info.GetData1());
2698           }
2699           else
2700           { // no container specified - assume a mediawindow
2701             CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2702             if (window)
2703               control = window->GetControl(window->GetViewContainerID());
2704           }
2705           if (control)
2706             bReturn = control->GetCondition(condition, info.GetData2());
2707         }
2708         break;
2709       case CONTAINER_HAS_FOCUS:
2710         { // grab our container
2711           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2712           if (window)
2713           {
2714             const CGUIControl *control = window->GetControl(info.GetData1());
2715             if (control && control->IsContainer())
2716             {
2717               CFileItemPtr item = boost::static_pointer_cast<CFileItem>(((IGUIContainer *)control)->GetListItem(0));
2718               if (item && item->m_iprogramCount == info.GetData2())  // programcount used to store item id
2719                 bReturn = true;
2720             }
2721           }
2722           break;
2723         }
2724       case VIDEOPLAYER_CONTENT:
2725         {
2726           CStdString strContent="movies";
2727           if (!m_currentFile->HasVideoInfoTag() || m_currentFile->GetVideoInfoTag()->IsEmpty())
2728             strContent = "files";
2729           if (m_currentFile->HasVideoInfoTag() && m_currentFile->GetVideoInfoTag()->m_iSeason > -1) // episode
2730             strContent = "episodes";
2731           if (m_currentFile->HasVideoInfoTag() && !m_currentFile->GetVideoInfoTag()->m_artist.empty())
2732             strContent = "musicvideos";
2733           if (m_currentFile->HasVideoInfoTag() && m_currentFile->GetVideoInfoTag()->m_strStatus == "livetv")
2734             strContent = "livetv";
2735           if (m_currentFile->HasPVRChannelInfoTag())
2736             strContent = "livetv";
2737           bReturn = m_stringParameters[info.GetData1()].Equals(strContent);
2738         }
2739         break;
2740       case CONTAINER_SORT_METHOD:
2741       {
2742         CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2743         if (window)
2744         {
2745           const CGUIViewState *viewState = ((CGUIMediaWindow*)window)->GetViewState();
2746           if (viewState)
2747             bReturn = ((unsigned int)viewState->GetSortMethod() == info.GetData1());
2748         }
2749         break;
2750       }
2751       case CONTAINER_SORT_DIRECTION:
2752       {
2753         CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2754         if (window)
2755         {
2756           const CGUIViewState *viewState = ((CGUIMediaWindow*)window)->GetViewState();
2757           if (viewState)
2758             bReturn = ((unsigned int)viewState->GetDisplaySortOrder() == info.GetData1());
2759         }
2760         break;
2761       }
2762       case SYSTEM_DATE:
2763         {
2764           if (info.GetData2() == -1) // info doesn't contain valid startDate
2765             return false;
2766           CDateTime date = CDateTime::GetCurrentDateTime();
2767           int currentDate = date.GetMonth()*100+date.GetDay();
2768           int startDate = info.GetData1();
2769           int stopDate = info.GetData2();
2770
2771           if (stopDate < startDate)
2772             bReturn = currentDate >= startDate || currentDate < stopDate;
2773           else
2774             bReturn = currentDate >= startDate && currentDate < stopDate;
2775         }
2776         break;
2777       case SYSTEM_TIME:
2778         {
2779           CDateTime time=CDateTime::GetCurrentDateTime();
2780           int currentTime = time.GetMinuteOfDay();
2781           int startTime = info.GetData1();
2782           int stopTime = info.GetData2();
2783
2784           if (stopTime < startTime)
2785             bReturn = currentTime >= startTime || currentTime < stopTime;
2786           else
2787             bReturn = currentTime >= startTime && currentTime < stopTime;
2788         }
2789         break;
2790       case MUSICPLAYER_EXISTS:
2791         {
2792           int index = info.GetData2();
2793           if (info.GetData1() == 1)
2794           { // relative index
2795             if (g_playlistPlayer.GetCurrentPlaylist() != PLAYLIST_MUSIC)
2796               return false;
2797             index += g_playlistPlayer.GetCurrentSong();
2798           }
2799           if (index >= 0 && index < g_playlistPlayer.GetPlaylist(PLAYLIST_MUSIC).size())
2800             return true;
2801           return false;
2802         }
2803         break;
2804     }
2805   }
2806   return (info.m_info < 0) ? !bReturn : bReturn;
2807 }
2808
2809 bool CGUIInfoManager::GetMultiInfoInt(int &value, const GUIInfo &info, int contextWindow) const
2810 {
2811   if (info.m_info >= LISTITEM_START && info.m_info <= LISTITEM_END)
2812   {
2813     CFileItemPtr item;
2814     CGUIWindow *window = NULL;
2815
2816     int data1 = info.GetData1();
2817     if (!data1) // No container specified, so we lookup the current view container
2818     {
2819       window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_HAS_LIST_ITEMS);
2820       if (window && window->IsMediaWindow())
2821         data1 = ((CGUIMediaWindow*)(window))->GetViewContainerID();
2822     }
2823
2824     if (!window) // If we don't have a window already (from lookup above), get one
2825       window = GetWindowWithCondition(contextWindow, 0);
2826
2827     if (window)
2828     {
2829       const CGUIControl *control = window->GetControl(data1);
2830       if (control && control->IsContainer())
2831         item = boost::static_pointer_cast<CFileItem>(((IGUIContainer *)control)->GetListItem(info.GetData2(), info.GetInfoFlag()));
2832     }
2833
2834     if (item) // If we got a valid item, do the lookup
2835       return GetItemInt(value, item.get(), info.m_info);
2836   }
2837
2838   return 0;
2839 }
2840
2841 /// \brief Examines the multi information sent and returns the string as appropriate
2842 CStdString CGUIInfoManager::GetMultiInfoLabel(const GUIInfo &info, int contextWindow, CStdString *fallback)
2843 {
2844   if (info.m_info == SKIN_STRING)
2845   {
2846     return g_settings.GetSkinString(info.GetData1());
2847   }
2848   else if (info.m_info == SKIN_BOOL)
2849   {
2850     bool bInfo = g_settings.GetSkinBool(info.GetData1());
2851     if (bInfo)
2852       return g_localizeStrings.Get(20122);
2853   }
2854   if (info.m_info >= LISTITEM_START && info.m_info <= LISTITEM_END)
2855   {
2856     CFileItemPtr item;
2857     CGUIWindow *window = NULL;
2858
2859     int data1 = info.GetData1();
2860     if (!data1) // No container specified, so we lookup the current view container
2861     {
2862       window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_HAS_LIST_ITEMS);
2863       if (window && window->IsMediaWindow())
2864         data1 = ((CGUIMediaWindow*)(window))->GetViewContainerID();
2865     }
2866
2867     if (!window) // If we don't have a window already (from lookup above), get one
2868       window = GetWindowWithCondition(contextWindow, 0);
2869
2870     if (window)
2871     {
2872       const CGUIControl *control = window->GetControl(data1);
2873       if (control && control->IsContainer())
2874         item = boost::static_pointer_cast<CFileItem>(((IGUIContainer *)control)->GetListItem(info.GetData2(), info.GetInfoFlag()));
2875     }
2876
2877     if (item) // If we got a valid item, do the lookup
2878       return GetItemImage(item.get(), info.m_info, fallback); // Image prioritizes images over labels (in the case of music item ratings for instance)
2879   }
2880   else if (info.m_info == PLAYER_TIME)
2881   {
2882     return GetCurrentPlayTime((TIME_FORMAT)info.GetData1());
2883   }
2884   else if (info.m_info == PLAYER_TIME_REMAINING)
2885   {
2886     return GetCurrentPlayTimeRemaining((TIME_FORMAT)info.GetData1());
2887   }
2888   else if (info.m_info == PLAYER_FINISH_TIME)
2889   {
2890     CDateTime time;
2891     CEpgInfoTag currentTag;
2892     if (GetEpgInfoTag(currentTag))
2893       time = currentTag.EndAsLocalTime();
2894     else
2895     {
2896       time = CDateTime::GetCurrentDateTime();
2897       time += CDateTimeSpan(0, 0, 0, GetPlayTimeRemaining());
2898     }
2899     return LocalizeTime(time, (TIME_FORMAT)info.GetData1());
2900   }
2901   else if (info.m_info == PLAYER_START_TIME)
2902   {
2903     CDateTime time;
2904     CEpgInfoTag currentTag;
2905     if (GetEpgInfoTag(currentTag))
2906       time = currentTag.StartAsLocalTime();
2907     else
2908     {
2909       time = CDateTime::GetCurrentDateTime();
2910       time -= CDateTimeSpan(0, 0, 0, (int)GetPlayTime());
2911     }
2912     return LocalizeTime(time, (TIME_FORMAT)info.GetData1());
2913   }
2914   else if (info.m_info == PLAYER_TIME_SPEED)
2915   {
2916     CStdString strTime;
2917     if (g_application.GetPlaySpeed() != 1)
2918       strTime.Format("%s (%ix)", GetCurrentPlayTime((TIME_FORMAT)info.GetData1()).c_str(), g_application.GetPlaySpeed());
2919     else
2920       strTime = GetCurrentPlayTime();
2921     return strTime;
2922   }
2923   else if (info.m_info == PLAYER_DURATION)
2924   {
2925     return GetDuration((TIME_FORMAT)info.GetData1());
2926   }
2927   else if (info.m_info == PLAYER_SEEKTIME)
2928   {
2929     return GetCurrentSeekTime((TIME_FORMAT)info.GetData1());
2930   }
2931   else if (info.m_info == PLAYER_SEEKOFFSET)
2932   {
2933     CStdString seekOffset = StringUtils::SecondsToTimeString(abs(m_seekOffset), (TIME_FORMAT)info.GetData1());
2934     if (m_seekOffset < 0)
2935       return "-" + seekOffset;
2936     if (m_seekOffset > 0)
2937       return "+" + seekOffset;
2938   }
2939   else if (info.m_info == PLAYER_ITEM_ART)
2940   {
2941     return m_currentFile->GetArt(m_stringParameters[info.GetData1()]);
2942   }
2943   else if (info.m_info == SYSTEM_TIME)
2944   {
2945     return GetTime((TIME_FORMAT)info.GetData1());
2946   }
2947   else if (info.m_info == SYSTEM_DATE)
2948   {
2949     CDateTime time=CDateTime::GetCurrentDateTime();
2950     return time.GetAsLocalizedDate(m_stringParameters[info.GetData1()],false);
2951   }
2952   else if (info.m_info == CONTAINER_NUM_PAGES || info.m_info == CONTAINER_CURRENT_PAGE ||
2953            info.m_info == CONTAINER_NUM_ITEMS || info.m_info == CONTAINER_POSITION)
2954   {
2955     const CGUIControl *control = NULL;
2956     if (info.GetData1())
2957     { // container specified
2958       CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2959       if (window)
2960         control = window->GetControl(info.GetData1());
2961     }
2962     else
2963     { // no container specified - assume a mediawindow
2964       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2965       if (window)
2966         control = window->GetControl(window->GetViewContainerID());
2967     }
2968     if (control)
2969     {
2970       if (control->IsContainer())
2971         return ((IGUIContainer *)control)->GetLabel(info.m_info);
2972       else if (control->GetControlType() == CGUIControl::GUICONTROL_TEXTBOX)
2973         return ((CGUITextBox *)control)->GetLabel(info.m_info);
2974     }
2975   }
2976   else if (info.m_info == SYSTEM_GET_CORE_USAGE)
2977   {
2978     CStdString strCpu;
2979     strCpu.Format("%4.2f", g_cpuInfo.GetCoreInfo(atoi(m_stringParameters[info.GetData1()].c_str())).m_fPct);
2980     return strCpu;
2981   }
2982   else if (info.m_info >= MUSICPLAYER_TITLE && info.m_info <= MUSICPLAYER_ALBUM_ARTIST)
2983     return GetMusicPlaylistInfo(info);
2984   else if (info.m_info == CONTAINER_PROPERTY)
2985   {
2986     CGUIWindow *window = NULL;
2987     if (info.GetData1())
2988     { // container specified
2989       window = GetWindowWithCondition(contextWindow, 0);
2990     }
2991     else
2992     { // no container specified - assume a mediawindow
2993       window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2994     }
2995     if (window)
2996       return ((CGUIMediaWindow *)window)->CurrentDirectory().GetProperty(m_stringParameters[info.GetData2()]).asString();
2997   }
2998   else if (info.m_info == CONTROL_GET_LABEL)
2999   {
3000     CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
3001     if (window)
3002     {
3003       const CGUIControl *control = window->GetControl(info.GetData1());
3004       if (control)
3005         return control->GetDescription();
3006     }
3007   }
3008   else if (info.m_info == WINDOW_PROPERTY)
3009   {
3010     CGUIWindow *window = NULL;
3011     if (info.GetData1())
3012     { // window specified
3013       window = g_windowManager.GetWindow(info.GetData1());//GetWindowWithCondition(contextWindow, 0);
3014     }
3015     else
3016     { // no window specified - assume active
3017       window = GetWindowWithCondition(contextWindow, 0);
3018     }
3019
3020     if (window)
3021       return window->GetProperty(m_stringParameters[info.GetData2()]).asString();
3022   }
3023   else if (info.m_info == SYSTEM_ADDON_TITLE ||
3024            info.m_info == SYSTEM_ADDON_ICON)
3025   {
3026     // This logic does not check/care whether an addon has been disabled/marked as broken,
3027     // it simply retrieves it's name or icon that means if an addon is placed on the home screen it
3028     // will stay there even if it's disabled/marked as broken. This might need to be changed/fixed
3029     // in the future.
3030     AddonPtr addon;
3031     if (info.GetData2() == 0)
3032       CAddonMgr::Get().GetAddon(const_cast<CGUIInfoManager*>(this)->GetLabel(info.GetData1(), contextWindow),addon,ADDON_UNKNOWN,false);
3033     else
3034       CAddonMgr::Get().GetAddon(m_stringParameters[info.GetData1()],addon,ADDON_UNKNOWN,false);
3035     if (addon && info.m_info == SYSTEM_ADDON_TITLE)
3036       return addon->Name();
3037     if (addon && info.m_info == SYSTEM_ADDON_ICON)
3038       return addon->Icon();
3039   }
3040
3041   return StringUtils::EmptyString;
3042 }
3043
3044 /// \brief Obtains the filename of the image to show from whichever subsystem is needed
3045 CStdString CGUIInfoManager::GetImage(int info, int contextWindow, CStdString *fallback)
3046 {
3047   if (info >= CONDITIONAL_LABEL_START && info <= CONDITIONAL_LABEL_END)
3048     return GetSkinVariableString(info, true);
3049
3050   if (info >= MULTI_INFO_START && info <= MULTI_INFO_END)
3051   {
3052     return GetMultiInfoLabel(m_multiInfo[info - MULTI_INFO_START], contextWindow, fallback);
3053   }
3054   else if (info == WEATHER_CONDITIONS)
3055     return g_weatherManager.GetInfo(WEATHER_IMAGE_CURRENT_ICON);
3056   else if (info == SYSTEM_PROFILETHUMB)
3057   {
3058     CStdString thumb = g_settings.GetCurrentProfile().getThumb();
3059     if (thumb.IsEmpty())
3060       thumb = "unknown-user.png";
3061     return thumb;
3062   }
3063   else if (info == MUSICPLAYER_COVER)
3064   {
3065     if (!g_application.IsPlayingAudio()) return "";
3066     if (fallback)
3067       *fallback = "DefaultAlbumCover.png";
3068     return m_currentFile->HasArt("thumb") ? m_currentFile->GetArt("thumb") : "DefaultAlbumCover.png";
3069   }
3070   else if (info == MUSICPLAYER_RATING)
3071   {
3072     if (!g_application.IsPlayingAudio()) return "";
3073     return GetItemImage(m_currentFile, LISTITEM_RATING);
3074   }
3075   else if (info == PLAYER_STAR_RATING)
3076   {
3077     if (!g_application.IsPlaying()) return "";
3078     return GetItemImage(m_currentFile, LISTITEM_STAR_RATING);
3079   }
3080   else if (info == VIDEOPLAYER_COVER)
3081   {
3082     if (!g_application.IsPlayingVideo()) return "";
3083     if (fallback)
3084       *fallback = "DefaultVideoCover.png";
3085     if(m_currentMovieThumb.IsEmpty())
3086       return m_currentFile->HasArt("thumb") ? m_currentFile->GetArt("thumb") : "DefaultVideoCover.png";
3087     else return m_currentMovieThumb;
3088   }
3089   else if (info == CONTAINER_FOLDERTHUMB)
3090   {
3091     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
3092     if (window)
3093       return GetItemImage(&const_cast<CFileItemList&>(((CGUIMediaWindow*)window)->CurrentDirectory()), LISTITEM_THUMB, fallback);
3094   }
3095   else if (info == CONTAINER_TVSHOWTHUMB)
3096   {
3097     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
3098     if (window)
3099       return ((CGUIMediaWindow *)window)->CurrentDirectory().GetArt("tvshow.thumb");
3100   }
3101   else if (info == CONTAINER_SEASONTHUMB)
3102   {
3103     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
3104     if (window)
3105       return ((CGUIMediaWindow *)window)->CurrentDirectory().GetArt("season.thumb");
3106   }
3107   else if (info == LISTITEM_THUMB || info == LISTITEM_ICON || info == LISTITEM_ACTUAL_ICON ||
3108           info == LISTITEM_OVERLAY || info == LISTITEM_RATING || info == LISTITEM_STAR_RATING)
3109   {
3110     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_HAS_LIST_ITEMS);
3111     if (window)
3112     {
3113       CFileItemPtr item = window->GetCurrentListItem();
3114       if (item)
3115         return GetItemImage(item.get(), info, fallback);
3116     }
3117   }
3118   return GetLabel(info, contextWindow, fallback);
3119 }
3120
3121 CStdString CGUIInfoManager::GetDate(bool bNumbersOnly)
3122 {
3123   CDateTime time=CDateTime::GetCurrentDateTime();
3124   return time.GetAsLocalizedDate(!bNumbersOnly);
3125 }
3126
3127 CStdString CGUIInfoManager::GetTime(TIME_FORMAT format) const
3128 {
3129   CDateTime time=CDateTime::GetCurrentDateTime();
3130   return LocalizeTime(time, format);
3131 }
3132
3133 CStdString CGUIInfoManager::LocalizeTime(const CDateTime &time, TIME_FORMAT format) const
3134 {
3135   const CStdString timeFormat = g_langInfo.GetTimeFormat();
3136   bool use12hourclock = timeFormat.Find('h') != -1;
3137   switch (format)
3138   {
3139   case TIME_FORMAT_GUESS:
3140     return time.GetAsLocalizedTime("", false);
3141   case TIME_FORMAT_SS:
3142     return time.GetAsLocalizedTime("ss", true);
3143   case TIME_FORMAT_MM:
3144     return time.GetAsLocalizedTime("mm", true);
3145   case TIME_FORMAT_MM_SS:
3146     return time.GetAsLocalizedTime("mm:ss", true);
3147   case TIME_FORMAT_HH:  // this forces it to a 12 hour clock
3148     return time.GetAsLocalizedTime(use12hourclock ? "h" : "HH", false);
3149   case TIME_FORMAT_HH_MM:
3150     return time.GetAsLocalizedTime(use12hourclock ? "h:mm" : "HH:mm", false);
3151   case TIME_FORMAT_HH_MM_XX:
3152       return time.GetAsLocalizedTime(use12hourclock ? "h:mm xx" : "HH:mm", false);
3153   case TIME_FORMAT_HH_MM_SS:
3154     return time.GetAsLocalizedTime("", true);
3155   case TIME_FORMAT_H:
3156     return time.GetAsLocalizedTime("h", false);
3157   case TIME_FORMAT_H_MM_SS:
3158     return time.GetAsLocalizedTime("h:mm:ss", true);
3159   case TIME_FORMAT_XX:
3160     return use12hourclock ? time.GetAsLocalizedTime("xx", false) : "";
3161   default:
3162     break;
3163   }
3164   return time.GetAsLocalizedTime("", false);
3165 }
3166
3167 CStdString CGUIInfoManager::GetDuration(TIME_FORMAT format) const
3168 {
3169   if (g_application.IsPlayingAudio() && m_currentFile->HasMusicInfoTag())
3170   {
3171     const CMusicInfoTag& tag = *m_currentFile->GetMusicInfoTag();
3172     if (tag.GetDuration() > 0)
3173       return StringUtils::SecondsToTimeString(tag.GetDuration(), format);
3174   }
3175   if (g_application.IsPlayingVideo() && !m_currentMovieDuration.IsEmpty())
3176     return m_currentMovieDuration;  // for tuxbox
3177   unsigned int iTotal = (unsigned int)g_application.GetTotalTime();
3178   if (iTotal > 0)
3179     return StringUtils::SecondsToTimeString(iTotal, format);
3180   return "";
3181 }
3182
3183 CStdString CGUIInfoManager::GetMusicPartyModeLabel(int item)
3184 {
3185   // get song counts
3186   if (item >= MUSICPM_SONGSPLAYED && item <= MUSICPM_RANDOMSONGSPICKED)
3187   {
3188     int iSongs = -1;
3189     switch (item)
3190     {
3191     case MUSICPM_SONGSPLAYED:
3192       {
3193         iSongs = g_partyModeManager.GetSongsPlayed();
3194         break;
3195       }
3196     case MUSICPM_MATCHINGSONGS:
3197       {
3198         iSongs = g_partyModeManager.GetMatchingSongs();
3199         break;
3200       }
3201     case MUSICPM_MATCHINGSONGSPICKED:
3202       {
3203         iSongs = g_partyModeManager.GetMatchingSongsPicked();
3204         break;
3205       }
3206     case MUSICPM_MATCHINGSONGSLEFT:
3207       {
3208         iSongs = g_partyModeManager.GetMatchingSongsLeft();
3209         break;
3210       }
3211     case MUSICPM_RELAXEDSONGSPICKED:
3212       {
3213         iSongs = g_partyModeManager.GetRelaxedSongs();
3214         break;
3215       }
3216     case MUSICPM_RANDOMSONGSPICKED:
3217       {
3218         iSongs = g_partyModeManager.GetRandomSongs();
3219         break;
3220       }
3221     }
3222     if (iSongs < 0)
3223       return "";
3224     CStdString strLabel;
3225     strLabel.Format("%i", iSongs);
3226     return strLabel;
3227   }
3228   return "";
3229 }
3230
3231 const CStdString CGUIInfoManager::GetMusicPlaylistInfo(const GUIInfo& info)
3232 {
3233   PLAYLIST::CPlayList& playlist = g_playlistPlayer.GetPlaylist(PLAYLIST_MUSIC);
3234   if (playlist.size() < 1)
3235     return "";
3236   int index = info.GetData2();
3237   if (info.GetData1() == 1)
3238   { // relative index (requires current playlist is PLAYLIST_MUSIC)
3239     if (g_playlistPlayer.GetCurrentPlaylist() != PLAYLIST_MUSIC)
3240       return "";
3241     index = g_playlistPlayer.GetNextSong(index);
3242   }
3243   if (index < 0 || index >= playlist.size())
3244     return "";
3245   CFileItemPtr playlistItem = playlist[index];
3246   if (!playlistItem->GetMusicInfoTag()->Loaded())
3247   {
3248     playlistItem->LoadMusicTag();
3249     playlistItem->GetMusicInfoTag()->SetLoaded();
3250   }
3251   // try to set a thumbnail
3252   if (!playlistItem->HasArt("thumb"))
3253   {
3254     CMusicThumbLoader loader;
3255     loader.LoadItem(playlistItem.get());
3256     // still no thumb? then just the set the default cover
3257     if (!playlistItem->HasArt("thumb"))
3258       playlistItem->SetArt("thumb", "DefaultAlbumCover.png");
3259   }
3260   if (info.m_info == MUSICPLAYER_PLAYLISTPOS)
3261   {
3262     CStdString strPosition = "";
3263     strPosition.Format("%i", index + 1);
3264     return strPosition;
3265   }
3266   else if (info.m_info == MUSICPLAYER_COVER)
3267     return playlistItem->GetArt("thumb");
3268   return GetMusicTagLabel(info.m_info, playlistItem.get());
3269 }
3270
3271 CStdString CGUIInfoManager::GetPlaylistLabel(int item) const
3272 {
3273   if (!g_application.IsPlaying()) return "";
3274   int iPlaylist = g_playlistPlayer.GetCurrentPlaylist();
3275   switch (item)
3276   {
3277   case PLAYLIST_LENGTH:
3278     {
3279       CStdString strLength = "";
3280       strLength.Format("%i", g_playlistPlayer.GetPlaylist(iPlaylist).size());
3281       return strLength;
3282     }
3283   case PLAYLIST_POSITION:
3284     {
3285       CStdString strPosition = "";
3286       strPosition.Format("%i", g_playlistPlayer.GetCurrentSong() + 1);
3287       return strPosition;
3288     }
3289   case PLAYLIST_RANDOM:
3290     {
3291       if (g_playlistPlayer.IsShuffled(iPlaylist))
3292         return g_localizeStrings.Get(590); // 590: Random
3293       else
3294         return g_localizeStrings.Get(591); // 591: Off
3295     }
3296   case PLAYLIST_REPEAT:
3297     {
3298       PLAYLIST::REPEAT_STATE state = g_playlistPlayer.GetRepeat(iPlaylist);
3299       if (state == PLAYLIST::REPEAT_ONE)
3300         return g_localizeStrings.Get(592); // 592: One
3301       else if (state == PLAYLIST::REPEAT_ALL)
3302         return g_localizeStrings.Get(593); // 593: All
3303       else
3304         return g_localizeStrings.Get(594); // 594: Off
3305     }
3306   }
3307   return "";
3308 }
3309
3310 CStdString CGUIInfoManager::GetMusicLabel(int item)
3311 {
3312   if (!g_application.IsPlaying() || !m_currentFile->HasMusicInfoTag()) return "";
3313
3314   SPlayerAudioStreamInfo info;
3315   g_application.m_pPlayer->GetAudioStreamInfo(g_application.m_pPlayer->GetAudioStream(), info);
3316
3317   switch (item)
3318   {
3319   case MUSICPLAYER_PLAYLISTLEN:
3320     {
3321       if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_MUSIC)
3322         return GetPlaylistLabel(PLAYLIST_LENGTH);
3323     }
3324     break;
3325   case MUSICPLAYER_PLAYLISTPOS:
3326     {
3327       if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_MUSIC)
3328         return GetPlaylistLabel(PLAYLIST_POSITION);
3329     }
3330     break;
3331   case MUSICPLAYER_BITRATE:
3332     {
3333       float fTimeSpan = (float)(CTimeUtils::GetFrameTime() - m_lastMusicBitrateTime);
3334       if (fTimeSpan >= 500.0f)
3335       {
3336         m_MusicBitrate = info.bitrate;
3337         m_lastMusicBitrateTime = CTimeUtils::GetFrameTime();
3338       }
3339       CStdString strBitrate = "";
3340       if (m_MusicBitrate > 0)
3341         strBitrate.Format("%i", MathUtils::round_int((double)m_MusicBitrate / 1000.0));
3342       return strBitrate;
3343     }
3344     break;
3345   case MUSICPLAYER_CHANNELS:
3346     {
3347       CStdString strChannels = "";
3348       if (info.channels > 0)
3349       {
3350         strChannels.Format("%i", info.channels);
3351       }
3352       return strChannels;
3353     }
3354     break;
3355   case MUSICPLAYER_BITSPERSAMPLE:
3356     {
3357       CStdString strBitsPerSample = "";
3358       if (g_application.m_pPlayer->GetBitsPerSample() > 0)
3359       {
3360         strBitsPerSample.Format("%i", g_application.m_pPlayer->GetBitsPerSample());
3361       }
3362       return strBitsPerSample;
3363     }
3364     break;
3365   case MUSICPLAYER_SAMPLERATE:
3366     {
3367       CStdString strSampleRate = "";
3368       if (g_application.m_pPlayer->GetSampleRate() > 0)
3369       {
3370         strSampleRate.Format("%.5g", ((double)g_application.m_pPlayer->GetSampleRate() / 1000.0));
3371       }
3372       return strSampleRate;
3373     }
3374     break;
3375   case MUSICPLAYER_CODEC:
3376     {
3377       CStdString strCodec;
3378       strCodec.Format("%s", info.audioCodecName);
3379       return strCodec;
3380     }
3381     break;
3382   case MUSICPLAYER_LYRICS:
3383     return GetItemLabel(m_currentFile, AddListItemProp("lyrics"));
3384   }
3385   return GetMusicTagLabel(item, m_currentFile);
3386 }
3387
3388 CStdString CGUIInfoManager::GetMusicTagLabel(int info, const CFileItem *item)
3389 {
3390   if (!item->HasMusicInfoTag()) return "";
3391   const CMusicInfoTag &tag = *item->GetMusicInfoTag();
3392   switch (info)
3393   {
3394   case MUSICPLAYER_TITLE:
3395     if (tag.GetTitle().size()) { return tag.GetTitle(); }
3396     break;
3397   case MUSICPLAYER_ALBUM:
3398     if (tag.GetAlbum().size()) { return tag.GetAlbum(); }
3399     break;
3400   case MUSICPLAYER_ARTIST:
3401     if (tag.GetArtist().size()) { return StringUtils::Join(tag.GetArtist(), g_advancedSettings.m_musicItemSeparator); }
3402     break;
3403   case MUSICPLAYER_ALBUM_ARTIST:
3404     if (tag.GetAlbumArtist().size()) { return StringUtils::Join(tag.GetAlbumArtist(), g_advancedSettings.m_musicItemSeparator); }
3405     break;
3406   case MUSICPLAYER_YEAR:
3407     if (tag.GetYear()) { return tag.GetYearString(); }
3408     break;
3409   case MUSICPLAYER_GENRE:
3410     if (tag.GetGenre().size()) { return StringUtils::Join(tag.GetGenre(), g_advancedSettings.m_musicItemSeparator); }
3411     break;
3412   case MUSICPLAYER_LYRICS:
3413     if (tag.GetLyrics().size()) { return tag.GetLyrics(); }
3414   break;
3415   case MUSICPLAYER_TRACK_NUMBER:
3416     {
3417       CStdString strTrack;
3418       if (tag.Loaded() && tag.GetTrackNumber() > 0)
3419       {
3420         strTrack.Format("%02i", tag.GetTrackNumber());
3421         return strTrack;
3422       }
3423     }
3424     break;
3425   case MUSICPLAYER_DISC_NUMBER:
3426     return GetItemLabel(item, LISTITEM_DISC_NUMBER);
3427   case MUSICPLAYER_RATING:
3428     return GetItemLabel(item, LISTITEM_RATING);
3429   case MUSICPLAYER_COMMENT:
3430     return GetItemLabel(item, LISTITEM_COMMENT);
3431   case MUSICPLAYER_DURATION:
3432     return GetItemLabel(item, LISTITEM_DURATION);
3433   case MUSICPLAYER_CHANNEL_NAME:
3434     {
3435       CPVRChannel* channeltag = m_currentFile->GetPVRChannelInfoTag();
3436       if (channeltag)
3437         return channeltag->ChannelName();
3438     }
3439     break;
3440   case MUSICPLAYER_CHANNEL_NUMBER:
3441     {
3442       CPVRChannel* channeltag = m_currentFile->GetPVRChannelInfoTag();
3443       if (channeltag)
3444       {
3445         CStdString strNumber;
3446         strNumber.Format("%i", channeltag->ChannelNumber());
3447         return strNumber;
3448       }
3449     }
3450     break;
3451   case MUSICPLAYER_CHANNEL_GROUP:
3452     {
3453       CPVRChannel* channeltag = m_currentFile->GetPVRChannelInfoTag();
3454       if (channeltag && channeltag->IsRadio())
3455         return g_PVRManager.GetPlayingGroup(true)->GroupName();
3456     }
3457     break;
3458   case MUSICPLAYER_PLAYCOUNT:
3459     return GetItemLabel(item, LISTITEM_PLAYCOUNT);
3460   case MUSICPLAYER_LASTPLAYED:
3461     return GetItemLabel(item, LISTITEM_LASTPLAYED);
3462   }
3463   return "";
3464 }
3465
3466 CStdString CGUIInfoManager::GetVideoLabel(int item)
3467 {
3468   if (!g_application.IsPlaying())
3469     return "";
3470
3471   if (item == VIDEOPLAYER_TITLE)
3472   {
3473     if(g_application.IsPlayingVideo())
3474        return GetLabel(PLAYER_TITLE);
3475   }
3476   else if (item == VIDEOPLAYER_PLAYLISTLEN)
3477   {
3478     if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_VIDEO)
3479       return GetPlaylistLabel(PLAYLIST_LENGTH);
3480   }
3481   else if (item == VIDEOPLAYER_PLAYLISTPOS)
3482   {
3483     if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_VIDEO)
3484       return GetPlaylistLabel(PLAYLIST_POSITION);
3485   }
3486   else if (m_currentFile->HasPVRChannelInfoTag())
3487   {
3488     CPVRChannel* tag = m_currentFile->GetPVRChannelInfoTag();
3489     CEpgInfoTag epgTag;
3490
3491     switch (item)
3492     {
3493     /* Now playing infos */
3494     case VIDEOPLAYER_ORIGINALTITLE:
3495       return tag->GetEPGNow(epgTag) ?
3496           epgTag.Title() :
3497           g_guiSettings.GetBool("epg.hidenoinfoavailable") ?
3498               StringUtils::EmptyString :
3499               g_localizeStrings.Get(19055); // no information available
3500     case VIDEOPLAYER_GENRE:
3501       return tag->GetEPGNow(epgTag) ? StringUtils::Join(epgTag.Genre(), g_advancedSettings.m_videoItemSeparator) : StringUtils::EmptyString;
3502     case VIDEOPLAYER_PLOT:
3503       return tag->GetEPGNow(epgTag) ? epgTag.Plot() : StringUtils::EmptyString;
3504     case VIDEOPLAYER_PLOT_OUTLINE:
3505       return tag->GetEPGNow(epgTag) ? epgTag.PlotOutline() : StringUtils::EmptyString;
3506     case VIDEOPLAYER_STARTTIME:
3507       return tag->GetEPGNow(epgTag) ? epgTag.StartAsLocalTime().GetAsLocalizedTime("", false) : CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
3508     case VIDEOPLAYER_ENDTIME:
3509       return tag->GetEPGNow(epgTag) ? epgTag.EndAsLocalTime().GetAsLocalizedTime("", false) : CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
3510
3511     /* Next playing infos */
3512     case VIDEOPLAYER_NEXT_TITLE:
3513       return tag->GetEPGNext(epgTag) ?
3514           epgTag.Title() :
3515           g_guiSettings.GetBool("epg.hidenoinfoavailable") ?
3516               StringUtils::EmptyString :
3517               g_localizeStrings.Get(19055); // no information available
3518     case VIDEOPLAYER_NEXT_GENRE:
3519       return tag->GetEPGNext(epgTag) ? StringUtils::Join(epgTag.Genre(), g_advancedSettings.m_videoItemSeparator) : StringUtils::EmptyString;
3520     case VIDEOPLAYER_NEXT_PLOT:
3521       return tag->GetEPGNext(epgTag) ? epgTag.Plot() : StringUtils::EmptyString;
3522     case VIDEOPLAYER_NEXT_PLOT_OUTLINE:
3523       return tag->GetEPGNext(epgTag) ? epgTag.PlotOutline() : StringUtils::EmptyString;
3524     case VIDEOPLAYER_NEXT_STARTTIME:
3525       return tag->GetEPGNext(epgTag) ? epgTag.StartAsLocalTime().GetAsLocalizedTime("", false) : CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
3526     case VIDEOPLAYER_NEXT_ENDTIME:
3527       return tag->GetEPGNext(epgTag) ? epgTag.EndAsLocalTime().GetAsLocalizedTime("", false) : CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
3528     case VIDEOPLAYER_NEXT_DURATION:
3529       {
3530         CStdString duration;
3531         if (tag->GetEPGNext(epgTag) && epgTag.GetDuration() > 0)
3532           duration = StringUtils::SecondsToTimeString(epgTag.GetDuration());
3533         return duration;
3534       }
3535
3536     case VIDEOPLAYER_PARENTAL_RATING:
3537       {
3538         CStdString rating;
3539         if (tag->GetEPGNow(epgTag) && epgTag.ParentalRating() > 0)
3540           rating.Format("%i", epgTag.ParentalRating());
3541         return rating;
3542       }
3543       break;
3544
3545     /* General channel infos */
3546     case VIDEOPLAYER_CHANNEL_NAME:
3547       return tag->ChannelName();
3548     case VIDEOPLAYER_CHANNEL_NUMBER:
3549       {
3550         CStdString strNumber;
3551         strNumber.Format("%i", tag->ChannelNumber());
3552         return strNumber;
3553       }
3554     case VIDEOPLAYER_CHANNEL_GROUP:
3555       {
3556         if (tag && !tag->IsRadio())
3557           return g_PVRManager.GetPlayingGroup(false)->GroupName();
3558       }
3559     }
3560   }
3561   else if (m_currentFile->HasVideoInfoTag())
3562   {
3563     switch (item)
3564     {
3565     case VIDEOPLAYER_ORIGINALTITLE:
3566       return m_currentFile->GetVideoInfoTag()->m_strOriginalTitle;
3567       break;
3568     case VIDEOPLAYER_GENRE:
3569       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_genre, g_advancedSettings.m_videoItemSeparator);
3570       break;
3571     case VIDEOPLAYER_DIRECTOR:
3572       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_director, g_advancedSettings.m_videoItemSeparator);
3573       break;
3574     case VIDEOPLAYER_RATING:
3575       {
3576         CStdString strRating;
3577         if (m_currentFile->GetVideoInfoTag()->m_fRating > 0.f)
3578           strRating.Format("%.1f", m_currentFile->GetVideoInfoTag()->m_fRating);
3579         return strRating;
3580       }
3581       break;
3582     case VIDEOPLAYER_RATING_AND_VOTES:
3583       {
3584         CStdString strRatingAndVotes;
3585         if (m_currentFile->GetVideoInfoTag()->m_fRating > 0.f)
3586         {
3587           if (m_currentFile->GetVideoInfoTag()->m_strVotes.IsEmpty())
3588             strRatingAndVotes.Format("%.1f", m_currentFile->GetVideoInfoTag()->m_fRating);
3589           else
3590             strRatingAndVotes.Format("%.1f (%s %s)", m_currentFile->GetVideoInfoTag()->m_fRating, m_currentFile->GetVideoInfoTag()->m_strVotes, g_localizeStrings.Get(20350));
3591         }
3592         return strRatingAndVotes;
3593       }
3594       break;
3595     case VIDEOPLAYER_YEAR:
3596       {
3597         CStdString strYear;
3598         if (m_currentFile->GetVideoInfoTag()->m_iYear > 0)
3599           strYear.Format("%i", m_currentFile->GetVideoInfoTag()->m_iYear);
3600         return strYear;
3601       }
3602       break;
3603     case VIDEOPLAYER_PREMIERED:
3604       {
3605         CDateTime dateTime;
3606         if (m_currentFile->GetVideoInfoTag()->m_firstAired.IsValid())
3607           dateTime = m_currentFile->GetVideoInfoTag()->m_firstAired;
3608         else if (m_currentFile->GetVideoInfoTag()->m_premiered.IsValid())
3609           dateTime = m_currentFile->GetVideoInfoTag()->m_premiered;
3610
3611         if (dateTime.IsValid())
3612           return dateTime.GetAsLocalizedDate();
3613         break;
3614       }
3615       break;
3616     case VIDEOPLAYER_PLOT:
3617       return m_currentFile->GetVideoInfoTag()->m_strPlot;
3618     case VIDEOPLAYER_TRAILER:
3619       return m_currentFile->GetVideoInfoTag()->m_strTrailer;
3620     case VIDEOPLAYER_PLOT_OUTLINE:
3621       return m_currentFile->GetVideoInfoTag()->m_strPlotOutline;
3622     case VIDEOPLAYER_EPISODE:
3623       {
3624         CStdString strEpisode;
3625         if (m_currentFile->GetVideoInfoTag()->m_iSpecialSortEpisode > 0)
3626           strEpisode.Format("S%i", m_currentFile->GetVideoInfoTag()->m_iSpecialSortEpisode);
3627         else if(m_currentFile->GetVideoInfoTag()->m_iEpisode > 0)
3628           strEpisode.Format("%i", m_currentFile->GetVideoInfoTag()->m_iEpisode);
3629         return strEpisode;
3630       }
3631       break;
3632     case VIDEOPLAYER_SEASON:
3633       {
3634         CStdString strSeason;
3635         if (m_currentFile->GetVideoInfoTag()->m_iSpecialSortSeason > 0)
3636           strSeason.Format("%i", m_currentFile->GetVideoInfoTag()->m_iSpecialSortSeason);
3637         else if(m_currentFile->GetVideoInfoTag()->m_iSeason > 0)
3638           strSeason.Format("%i", m_currentFile->GetVideoInfoTag()->m_iSeason);
3639         return strSeason;
3640       }
3641       break;
3642     case VIDEOPLAYER_TVSHOW:
3643       return m_currentFile->GetVideoInfoTag()->m_strShowTitle;
3644
3645     case VIDEOPLAYER_STUDIO:
3646       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_studio, g_advancedSettings.m_videoItemSeparator);
3647     case VIDEOPLAYER_COUNTRY:
3648       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_country, g_advancedSettings.m_videoItemSeparator);
3649     case VIDEOPLAYER_MPAA:
3650       return m_currentFile->GetVideoInfoTag()->m_strMPAARating;
3651     case VIDEOPLAYER_TOP250:
3652       {
3653         CStdString strTop250;
3654         if (m_currentFile->GetVideoInfoTag()->m_iTop250 > 0)
3655           strTop250.Format("%i", m_currentFile->GetVideoInfoTag()->m_iTop250);
3656         return strTop250;
3657       }
3658       break;
3659     case VIDEOPLAYER_CAST:
3660       return m_currentFile->GetVideoInfoTag()->GetCast();
3661     case VIDEOPLAYER_CAST_AND_ROLE:
3662       return m_currentFile->GetVideoInfoTag()->GetCast(true);
3663     case VIDEOPLAYER_ARTIST:
3664       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator);
3665     case VIDEOPLAYER_ALBUM:
3666       return m_currentFile->GetVideoInfoTag()->m_strAlbum;
3667     case VIDEOPLAYER_WRITER:
3668       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_writingCredits, g_advancedSettings.m_videoItemSeparator);
3669     case VIDEOPLAYER_TAGLINE:
3670       return m_currentFile->GetVideoInfoTag()->m_strTagLine;
3671     case VIDEOPLAYER_LASTPLAYED:
3672       {
3673         if (m_currentFile->GetVideoInfoTag()->m_lastPlayed.IsValid())
3674           return m_currentFile->GetVideoInfoTag()->m_lastPlayed.GetAsLocalizedDateTime();
3675         break;
3676       }
3677     case VIDEOPLAYER_PLAYCOUNT:
3678       {
3679         CStdString strPlayCount;
3680         if (m_currentFile->GetVideoInfoTag()->m_playCount > 0)
3681           strPlayCount.Format("%i", m_currentFile->GetVideoInfoTag()->m_playCount);
3682         return strPlayCount;
3683       }
3684     }
3685   }
3686   return "";
3687 }
3688
3689 int64_t CGUIInfoManager::GetPlayTime() const
3690 {
3691   if (g_application.IsPlaying())
3692   {
3693     int64_t lPTS = (int64_t)(g_application.GetTime() * 1000);
3694     if (lPTS < 0) lPTS = 0;
3695     return lPTS;
3696   }
3697   return 0;
3698 }
3699
3700 CStdString CGUIInfoManager::GetCurrentPlayTime(TIME_FORMAT format) const
3701 {
3702   if (format == TIME_FORMAT_GUESS && GetTotalPlayTime() >= 3600)
3703     format = TIME_FORMAT_HH_MM_SS;
3704   if (g_application.IsPlaying())
3705     return StringUtils::SecondsToTimeString((int)(GetPlayTime()/1000), format);
3706   return "";
3707 }
3708
3709 CStdString CGUIInfoManager::GetCurrentSeekTime(TIME_FORMAT format) const
3710 {
3711   if (format == TIME_FORMAT_GUESS && GetTotalPlayTime() >= 3600)
3712     format = TIME_FORMAT_HH_MM_SS;
3713   float time = GetTotalPlayTime() * g_application.GetSeekHandler()->GetPercent() * 0.01f;
3714   return StringUtils::SecondsToTimeString((int)time, format);
3715 }
3716
3717 int CGUIInfoManager::GetTotalPlayTime() const
3718 {
3719   int iTotalTime = (int)g_application.GetTotalTime();
3720   return iTotalTime > 0 ? iTotalTime : 0;
3721 }
3722
3723 int CGUIInfoManager::GetPlayTimeRemaining() const
3724 {
3725   int iReverse = GetTotalPlayTime() - (int)g_application.GetTime();
3726   return iReverse > 0 ? iReverse : 0;
3727 }
3728
3729 CStdString CGUIInfoManager::GetCurrentPlayTimeRemaining(TIME_FORMAT format) const
3730 {
3731   if (format == TIME_FORMAT_GUESS && GetTotalPlayTime() >= 3600)
3732     format = TIME_FORMAT_HH_MM_SS;
3733   int timeRemaining = GetPlayTimeRemaining();
3734   if (timeRemaining && g_application.IsPlaying())
3735     return StringUtils::SecondsToTimeString(timeRemaining, format);
3736   return "";
3737 }
3738
3739 void CGUIInfoManager::ResetCurrentItem()
3740 {
3741   m_currentFile->Reset();
3742   m_currentMovieThumb = "";
3743   m_currentMovieDuration = "";
3744 }
3745
3746 void CGUIInfoManager::SetCurrentItem(CFileItem &item)
3747 {
3748   ResetCurrentItem();
3749
3750   if (item.IsAudio())
3751     SetCurrentSong(item);
3752   else
3753     SetCurrentMovie(item);
3754
3755   if (item.HasEPGInfoTag())
3756     *m_currentFile->GetEPGInfoTag() = *item.GetEPGInfoTag();
3757   else if (item.HasPVRChannelInfoTag())
3758   {
3759     CEpgInfoTag tag;
3760     if (item.GetPVRChannelInfoTag()->GetEPGNow(tag))
3761       *m_currentFile->GetEPGInfoTag() = tag;
3762   }
3763
3764   SetChanged();
3765   NotifyObservers(ObservableMessageCurrentItem);
3766 }
3767
3768 void CGUIInfoManager::SetCurrentAlbumThumb(const CStdString thumbFileName)
3769 {
3770   if (CFile::Exists(thumbFileName))
3771     m_currentFile->SetArt("thumb", thumbFileName);
3772   else
3773   {
3774     m_currentFile->SetArt("thumb", "");
3775     m_currentFile->FillInDefaultIcon();
3776   }
3777 }
3778
3779 void CGUIInfoManager::SetCurrentSong(CFileItem &item)
3780 {
3781   CLog::Log(LOGDEBUG,"CGUIInfoManager::SetCurrentSong(%s)",item.GetPath().c_str());
3782   *m_currentFile = item;
3783
3784   m_currentFile->LoadMusicTag();
3785   if (m_currentFile->GetMusicInfoTag()->GetTitle().IsEmpty())
3786   {
3787     // No title in tag, show filename only
3788     m_currentFile->GetMusicInfoTag()->SetTitle(CUtil::GetTitleFromPath(m_currentFile->GetPath()));
3789   }
3790   m_currentFile->GetMusicInfoTag()->SetLoaded(true);
3791
3792   // find a thumb for this file.
3793   if (m_currentFile->IsInternetStream())
3794   {
3795     if (!g_application.m_strPlayListFile.IsEmpty())
3796     {
3797       CLog::Log(LOGDEBUG,"Streaming media detected... using %s to find a thumb", g_application.m_strPlayListFile.c_str());
3798       CFileItem streamingItem(g_application.m_strPlayListFile,false);
3799       CMusicThumbLoader::FillThumb(streamingItem);
3800       if (streamingItem.HasArt("thumb"))
3801         m_currentFile->SetArt("thumb", streamingItem.GetArt("thumb"));
3802     }
3803   }
3804   else
3805   {
3806     CMusicThumbLoader loader;
3807     loader.LoadItem(m_currentFile);
3808   }
3809   m_currentFile->FillInDefaultIcon();
3810
3811   CMusicInfoLoader::LoadAdditionalTagInfo(m_currentFile);
3812 }
3813
3814 void CGUIInfoManager::SetCurrentMovie(CFileItem &item)
3815 {
3816   CLog::Log(LOGDEBUG,"CGUIInfoManager::SetCurrentMovie(%s)",item.GetPath().c_str());
3817   *m_currentFile = item;
3818
3819   /* also call GetMovieInfo() when a VideoInfoTag is already present or additional info won't be present in the tag */
3820   if (!m_currentFile->HasPVRChannelInfoTag())
3821   {
3822     CVideoDatabase dbs;
3823     if (dbs.Open())
3824     {
3825       dbs.LoadVideoInfo(item.GetPath(), *m_currentFile->GetVideoInfoTag());
3826       dbs.Close();
3827     }
3828   }
3829
3830   // Find a thumb for this file.
3831   if (!item.HasArt("thumb"))
3832   {
3833     CVideoThumbLoader loader;
3834     loader.LoadItem(m_currentFile);
3835   }
3836
3837   // find a thumb for this stream
3838   if (item.IsInternetStream())
3839   {
3840     // case where .strm is used to start an audio stream
3841     if (g_application.IsPlayingAudio())
3842     {
3843       SetCurrentSong(item);
3844       return;
3845     }
3846
3847     // else its a video
3848     if (!g_application.m_strPlayListFile.IsEmpty())
3849     {
3850       CLog::Log(LOGDEBUG,"Streaming media detected... using %s to find a thumb", g_application.m_strPlayListFile.c_str());
3851       CFileItem thumbItem(g_application.m_strPlayListFile,false);
3852       if (CVideoThumbLoader::FillThumb(thumbItem))
3853         item.SetArt("thumb", thumbItem.GetArt("thumb"));
3854     }
3855   }
3856
3857   item.FillInDefaultIcon();
3858   m_currentMovieThumb = item.GetArt("thumb");
3859 }
3860
3861 string CGUIInfoManager::GetSystemHeatInfo(int info)
3862 {
3863   if (CTimeUtils::GetFrameTime() - m_lastSysHeatInfoTime >= SYSHEATUPDATEINTERVAL)
3864   { // update our variables
3865     m_lastSysHeatInfoTime = CTimeUtils::GetFrameTime();
3866 #if defined(_LINUX)
3867     g_cpuInfo.getTemperature(m_cpuTemp);
3868     m_gpuTemp = GetGPUTemperature();
3869 #endif
3870   }
3871
3872   CStdString text;
3873   switch(info)
3874   {
3875     case SYSTEM_CPU_TEMPERATURE:
3876       return m_cpuTemp.IsValid() ? m_cpuTemp.ToString() : "?";
3877       break;
3878     case SYSTEM_GPU_TEMPERATURE:
3879       return m_gpuTemp.IsValid() ? m_gpuTemp.ToString() : "?";
3880       break;
3881     case SYSTEM_FAN_SPEED:
3882       text.Format("%i%%", m_fanSpeed * 2);
3883       break;
3884     case SYSTEM_CPU_USAGE:
3885 #if defined(TARGET_DARWIN) || defined(_WIN32)
3886       text.Format("%d%%", g_cpuInfo.getUsedPercentage());
3887 #else
3888       text.Format("%s", g_cpuInfo.GetCoresUsageString());
3889 #endif
3890       break;
3891   }
3892   return text;
3893 }
3894
3895 CTemperature CGUIInfoManager::GetGPUTemperature()
3896 {
3897   CStdString  cmd   = g_advancedSettings.m_gpuTempCmd;
3898   int         value = 0,
3899               ret   = 0;
3900   char        scale = 0;
3901   FILE        *p    = NULL;
3902
3903   if (cmd.IsEmpty() || !(p = popen(cmd.c_str(), "r")))
3904     return CTemperature();
3905
3906   ret = fscanf(p, "%d %c", &value, &scale);
3907   pclose(p);
3908
3909   if (ret != 2)
3910     return CTemperature();
3911
3912   if (scale == 'C' || scale == 'c')
3913     return CTemperature::CreateFromCelsius(value);
3914   if (scale == 'F' || scale == 'f')
3915     return CTemperature::CreateFromFahrenheit(value);
3916   return CTemperature();
3917 }
3918
3919 // Version string MUST NOT contain spaces.  It is used
3920 // in the HTTP request user agent.
3921 CStdString CGUIInfoManager::GetVersion()
3922 {
3923   CStdString tmp;
3924 #ifdef GIT_REV
3925   tmp.Format("%d.%d%s Git:%s", VERSION_MAJOR, VERSION_MINOR, VERSION_TAG, GIT_REV);
3926 #else
3927   tmp.Format("%d.%d%s", VERSION_MAJOR, VERSION_MINOR, VERSION_TAG);
3928 #endif
3929   return tmp;
3930 }
3931
3932 CStdString CGUIInfoManager::GetBuild()
3933 {
3934   CStdString tmp;
3935   tmp.Format("%s", __DATE__);
3936   return tmp;
3937 }
3938
3939 void CGUIInfoManager::SetDisplayAfterSeek(unsigned int timeOut, int seekOffset)
3940 {
3941   g_infoManager.m_performingSeek = false;
3942   if (timeOut>0)
3943   {
3944     m_AfterSeekTimeout = CTimeUtils::GetFrameTime() +  timeOut;
3945     if (seekOffset)
3946       m_seekOffset = seekOffset;
3947   }
3948   else
3949     m_AfterSeekTimeout = 0;
3950 }
3951
3952 bool CGUIInfoManager::GetDisplayAfterSeek()
3953 {
3954   if (CTimeUtils::GetFrameTime() < m_AfterSeekTimeout)
3955     return true;
3956   m_seekOffset = 0;
3957   return false;
3958 }
3959
3960 void CGUIInfoManager::Clear()
3961 {
3962   CSingleLock lock(m_critInfo);
3963   for (unsigned int i = 0; i < m_bools.size(); ++i)
3964     delete m_bools[i];
3965   m_bools.clear();
3966
3967   m_skinVariableStrings.clear();
3968 }
3969
3970 void CGUIInfoManager::UpdateFPS()
3971 {
3972   m_frameCounter++;
3973   unsigned int curTime = CTimeUtils::GetFrameTime();
3974
3975   float fTimeSpan = (float)(curTime - m_lastFPSTime);
3976   if (fTimeSpan >= 1000.0f)
3977   {
3978     fTimeSpan /= 1000.0f;
3979     m_fps = m_frameCounter / fTimeSpan;
3980     m_lastFPSTime = curTime;
3981     m_frameCounter = 0;
3982   }
3983 }
3984
3985 int CGUIInfoManager::AddListItemProp(const CStdString &str, int offset)
3986 {
3987   for (int i=0; i < (int)m_listitemProperties.size(); i++)
3988     if (m_listitemProperties[i] == str)
3989       return (LISTITEM_PROPERTY_START+offset + i);
3990
3991   if (m_listitemProperties.size() < LISTITEM_PROPERTY_END - LISTITEM_PROPERTY_START)
3992   {
3993     m_listitemProperties.push_back(str);
3994     return LISTITEM_PROPERTY_START + offset + m_listitemProperties.size() - 1;
3995   }
3996
3997   CLog::Log(LOGERROR,"%s - not enough listitem property space!", __FUNCTION__);
3998   return 0;
3999 }
4000
4001 int CGUIInfoManager::AddMultiInfo(const GUIInfo &info)
4002 {
4003   // check to see if we have this info already
4004   for (unsigned int i = 0; i < m_multiInfo.size(); i++)
4005     if (m_multiInfo[i] == info)
4006       return (int)i + MULTI_INFO_START;
4007   // return the new offset
4008   m_multiInfo.push_back(info);
4009   int id = (int)m_multiInfo.size() + MULTI_INFO_START - 1;
4010   if (id > MULTI_INFO_END)
4011     CLog::Log(LOGERROR, "%s - too many multiinfo bool/labels in this skin", __FUNCTION__);
4012   return id;
4013 }
4014
4015 int CGUIInfoManager::ConditionalStringParameter(const CStdString &parameter, bool caseSensitive /*= false*/)
4016 {
4017   // check to see if we have this parameter already
4018   for (unsigned int i = 0; i < m_stringParameters.size(); i++)
4019     if (parameter.Equals(m_stringParameters[i], caseSensitive))
4020       return (int)i;
4021   // return the new offset
4022   m_stringParameters.push_back(parameter);
4023   return (int)m_stringParameters.size() - 1;
4024 }
4025
4026 bool CGUIInfoManager::GetItemInt(int &value, const CGUIListItem *item, int info) const
4027 {
4028   if (!item)
4029   {
4030     value = 0;
4031     return false;
4032   }
4033
4034   if (info >= LISTITEM_PROPERTY_START && info - LISTITEM_PROPERTY_START < (int)m_listitemProperties.size())
4035   { // grab the property
4036     CStdString property = m_listitemProperties[info - LISTITEM_PROPERTY_START];
4037     CStdString val = item->GetProperty(property).asString();
4038     value = atoi(val);
4039     return true;
4040   }
4041
4042   switch (info)
4043   {
4044     case LISTITEM_PROGRESS:
4045     {
4046       value = 0;
4047       if (item->IsFileItem())
4048       {
4049         const CFileItem *pItem = (const CFileItem *)item;
4050         if (pItem && pItem->HasPVRChannelInfoTag())
4051         {
4052           CEpgInfoTag epgNow;
4053           if (pItem->GetPVRChannelInfoTag()->GetEPGNow(epgNow))
4054             value = (int) epgNow.ProgressPercentage();
4055         }
4056         else if (pItem && pItem->HasEPGInfoTag())
4057         {
4058           value = (int) pItem->GetEPGInfoTag()->ProgressPercentage();
4059         }
4060       }
4061
4062       return true;
4063     }
4064     break;
4065   case LISTITEM_PERCENT_PLAYED:
4066     if (item->IsFileItem() && ((const CFileItem *)item)->HasVideoInfoTag() && ((const CFileItem *)item)->GetVideoInfoTag()->m_resumePoint.IsPartWay())
4067       value = (int)(100 * ((const CFileItem *)item)->GetVideoInfoTag()->m_resumePoint.timeInSeconds / ((const CFileItem *)item)->GetVideoInfoTag()->m_resumePoint.totalTimeInSeconds);
4068     else if (item->IsFileItem() && ((const CFileItem *)item)->HasPVRRecordingInfoTag() && ((const CFileItem *)item)->GetPVRRecordingInfoTag()->m_resumePoint.IsPartWay())
4069       value = (int)(100 * ((const CFileItem *)item)->GetPVRRecordingInfoTag()->m_resumePoint.timeInSeconds / ((const CFileItem *)item)->GetPVRRecordingInfoTag()->m_resumePoint.totalTimeInSeconds);
4070     else
4071       value = 0;
4072     return true;
4073   }
4074
4075   value = 0;
4076   return false;
4077 }
4078
4079 CStdString CGUIInfoManager::GetItemLabel(const CFileItem *item, int info, CStdString *fallback)
4080 {
4081   if (!item) return "";
4082
4083   if (info >= CONDITIONAL_LABEL_START && info <= CONDITIONAL_LABEL_END)
4084     return GetSkinVariableString(info, false, item);
4085
4086   if (info >= LISTITEM_PROPERTY_START + LISTITEM_ART_OFFSET && info - (LISTITEM_PROPERTY_START + LISTITEM_ART_OFFSET) < (int)m_listitemProperties.size())
4087   { // grab the art
4088     std::string art = m_listitemProperties[info - (LISTITEM_PROPERTY_START + LISTITEM_ART_OFFSET)];
4089     return item->GetArt(art);
4090   }
4091
4092   if (info >= LISTITEM_PROPERTY_START && info - LISTITEM_PROPERTY_START < (int)m_listitemProperties.size())
4093   { // grab the property
4094     CStdString property = m_listitemProperties[info - LISTITEM_PROPERTY_START];
4095     return item->GetProperty(property).asString();
4096   }
4097
4098   if (info >= LISTITEM_PICTURE_START && info <= LISTITEM_PICTURE_END && item->HasPictureInfoTag())
4099     return item->GetPictureInfoTag()->GetInfo(picture_slide_map[info - LISTITEM_PICTURE_START]);
4100
4101   switch (info)
4102   {
4103   case LISTITEM_LABEL:
4104     return item->GetLabel();
4105   case LISTITEM_LABEL2:
4106     return item->GetLabel2();
4107   case LISTITEM_TITLE:
4108     if (item->HasPVRChannelInfoTag())
4109     {
4110       CEpgInfoTag epgTag;
4111       return item->GetPVRChannelInfoTag()->GetEPGNow(epgTag) ?
4112           epgTag.Title() :
4113           g_guiSettings.GetBool("epg.hidenoinfoavailable") ?
4114               StringUtils::EmptyString :
4115               g_localizeStrings.Get(19055); // no information available
4116     }
4117     if (item->HasPVRRecordingInfoTag())
4118       return item->GetPVRRecordingInfoTag()->m_strTitle;
4119     if (item->HasEPGInfoTag())
4120       return item->GetEPGInfoTag()->Title();
4121     if (item->HasPVRTimerInfoTag())
4122       return item->GetPVRTimerInfoTag()->Title();
4123     if (item->HasVideoInfoTag())
4124       return item->GetVideoInfoTag()->m_strTitle;
4125     if (item->HasMusicInfoTag())
4126       return item->GetMusicInfoTag()->GetTitle();
4127     break;
4128   case LISTITEM_ORIGINALTITLE:
4129     if (item->HasVideoInfoTag())
4130       return item->GetVideoInfoTag()->m_strOriginalTitle;
4131     break;
4132   case LISTITEM_PLAYCOUNT:
4133     {
4134       CStdString strPlayCount;
4135       if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_playCount > 0)
4136         strPlayCount.Format("%i", item->GetVideoInfoTag()->m_playCount);
4137       if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetPlayCount() > 0)
4138         strPlayCount.Format("%i", item->GetMusicInfoTag()->GetPlayCount());
4139       return strPlayCount;
4140     }
4141   case LISTITEM_LASTPLAYED:
4142     {
4143       CDateTime dateTime;
4144       if (item->HasVideoInfoTag())
4145         dateTime = item->GetVideoInfoTag()->m_lastPlayed;
4146       else if (item->HasMusicInfoTag())
4147         dateTime = item->GetMusicInfoTag()->GetLastPlayed();
4148
4149       if (dateTime.IsValid())
4150         return dateTime.GetAsLocalizedDate();
4151       break;
4152     }
4153   case LISTITEM_TRACKNUMBER:
4154     {
4155       CStdString track;
4156       if (item->HasMusicInfoTag())
4157         track.Format("%i", item->GetMusicInfoTag()->GetTrackNumber());
4158
4159       return track;
4160     }
4161   case LISTITEM_DISC_NUMBER:
4162     {
4163       CStdString disc;
4164       if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetDiscNumber() > 0)
4165         disc.Format("%i", item->GetMusicInfoTag()->GetDiscNumber());
4166       return disc;
4167     }
4168   case LISTITEM_ARTIST:
4169     if (item->HasVideoInfoTag())
4170       return StringUtils::Join(item->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator);
4171     if (item->HasMusicInfoTag())
4172       return StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator);
4173     break;
4174   case LISTITEM_ALBUM_ARTIST:
4175     if (item->HasMusicInfoTag())
4176       return StringUtils::Join(item->GetMusicInfoTag()->GetAlbumArtist(), g_advancedSettings.m_musicItemSeparator);
4177     break;
4178   case LISTITEM_DIRECTOR:
4179     if (item->HasVideoInfoTag())
4180       return StringUtils::Join(item->GetVideoInfoTag()->m_director, g_advancedSettings.m_videoItemSeparator);
4181     break;
4182   case LISTITEM_ALBUM:
4183     if (item->HasVideoInfoTag())
4184       return item->GetVideoInfoTag()->m_strAlbum;
4185     if (item->HasMusicInfoTag())
4186       return item->GetMusicInfoTag()->GetAlbum();
4187     break;
4188   case LISTITEM_YEAR:
4189     if (item->HasVideoInfoTag())
4190     {
4191       CStdString strResult;
4192       if (item->GetVideoInfoTag()->m_iYear > 0)
4193         strResult.Format("%i",item->GetVideoInfoTag()->m_iYear);
4194       return strResult;
4195     }
4196     if (item->HasMusicInfoTag())
4197       return item->GetMusicInfoTag()->GetYearString();
4198     break;
4199   case LISTITEM_PREMIERED:
4200     if (item->HasVideoInfoTag())
4201     {
4202       CDateTime dateTime;
4203       if (item->GetVideoInfoTag()->m_firstAired.IsValid())
4204         dateTime = item->GetVideoInfoTag()->m_firstAired;
4205       else if (item->GetVideoInfoTag()->m_premiered.IsValid())
4206         dateTime = item->GetVideoInfoTag()->m_premiered;
4207
4208       if (dateTime.IsValid())
4209         return dateTime.GetAsLocalizedDate();
4210       break;
4211     }
4212     break;
4213   case LISTITEM_GENRE:
4214     if (item->HasVideoInfoTag())
4215       return StringUtils::Join(item->GetVideoInfoTag()->m_genre, g_advancedSettings.m_videoItemSeparator);
4216     if (item->HasMusicInfoTag())
4217       return StringUtils::Join(item->GetMusicInfoTag()->GetGenre(), g_advancedSettings.m_musicItemSeparator);
4218     if (item->HasPVRChannelInfoTag())
4219     {
4220       CEpgInfoTag epgTag;
4221       return item->GetPVRChannelInfoTag()->GetEPGNow(epgTag) ? StringUtils::Join(epgTag.Genre(), g_advancedSettings.m_videoItemSeparator) : StringUtils::EmptyString;
4222     }
4223     if (item->HasPVRRecordingInfoTag())
4224       return StringUtils::Join(item->GetPVRRecordingInfoTag()->m_genre, g_advancedSettings.m_videoItemSeparator);
4225     if (item->HasEPGInfoTag())
4226       return StringUtils::Join(item->GetEPGInfoTag()->Genre(), g_advancedSettings.m_videoItemSeparator);
4227     break;
4228   case LISTITEM_FILENAME:
4229   case LISTITEM_FILE_EXTENSION:
4230     {
4231       CStdString strFile;
4232       if (item->IsMusicDb() && item->HasMusicInfoTag())
4233         strFile = URIUtils::GetFileName(item->GetMusicInfoTag()->GetURL());
4234       else if (item->IsVideoDb() && item->HasVideoInfoTag())
4235         strFile = URIUtils::GetFileName(item->GetVideoInfoTag()->m_strFileNameAndPath);
4236       else
4237         strFile = URIUtils::GetFileName(item->GetPath());
4238
4239       if (info==LISTITEM_FILE_EXTENSION)
4240       {
4241         CStdString strExtension = URIUtils::GetExtension(strFile);
4242         return strExtension.TrimLeft(".");
4243       }
4244       return strFile;
4245     }
4246     break;
4247   case LISTITEM_DATE:
4248     if (item->HasEPGInfoTag())
4249       return item->GetEPGInfoTag()->StartAsLocalTime().GetAsLocalizedDateTime(false, false);
4250     if (item->HasPVRChannelInfoTag())
4251     {
4252       CEpgInfoTag epgTag;
4253       return item->GetPVRChannelInfoTag()->GetEPGNow(epgTag) ? epgTag.StartAsLocalTime().GetAsLocalizedDateTime(false, false) : CDateTime::GetCurrentDateTime().GetAsLocalizedDateTime(false, false);
4254     }
4255     if (item->HasPVRRecordingInfoTag())
4256       return item->GetPVRRecordingInfoTag()->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(false, false);
4257     if (item->HasPVRTimerInfoTag())
4258       return item->GetPVRTimerInfoTag()->Summary();
4259     if (item->m_dateTime.IsValid())
4260       return item->m_dateTime.GetAsLocalizedDate();
4261     break;
4262   case LISTITEM_SIZE:
4263     if (!item->m_bIsFolder || item->m_dwSize)
4264       return StringUtils::SizeToString(item->m_dwSize);
4265     break;
4266   case LISTITEM_RATING:
4267     {
4268       CStdString rating;
4269       if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_fRating > 0.f) // movie rating
4270         rating.Format("%.1f", item->GetVideoInfoTag()->m_fRating);
4271       else if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetRating() > '0')
4272       { // song rating.  Images will probably be better than numbers for this in the long run
4273         rating = item->GetMusicInfoTag()->GetRating();
4274       }
4275       return rating;
4276     }
4277   case LISTITEM_RATING_AND_VOTES:
4278     {
4279       if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_fRating > 0.f) // movie rating
4280       {
4281         CStdString strRatingAndVotes;
4282         if (item->GetVideoInfoTag()->m_strVotes.IsEmpty())
4283           strRatingAndVotes.Format("%.1f", item->GetVideoInfoTag()->m_fRating);
4284         else
4285           strRatingAndVotes.Format("%.1f (%s %s)", item->GetVideoInfoTag()->m_fRating, item->GetVideoInfoTag()->m_strVotes, g_localizeStrings.Get(20350));
4286         return strRatingAndVotes;
4287       }
4288     }
4289     break;
4290   case LISTITEM_PROGRAM_COUNT:
4291     {
4292       CStdString count;
4293       count.Format("%i", item->m_iprogramCount);
4294       return count;
4295     }
4296   case LISTITEM_DURATION:
4297     {
4298       CStdString duration;
4299       if (item->HasPVRChannelInfoTag())
4300       {
4301         const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4302         CEpgInfoTag tag;
4303         if (channel && channel->GetEPGNow(tag))
4304           return StringUtils::SecondsToTimeString(tag.GetDuration());
4305         return StringUtils::EmptyString;
4306       }
4307       else if (item->HasPVRRecordingInfoTag())
4308       {
4309         if (item->GetPVRRecordingInfoTag()->GetDuration() > 0)
4310           duration = StringUtils::SecondsToTimeString(item->GetPVRRecordingInfoTag()->GetDuration());
4311       }
4312       else if (item->HasEPGInfoTag())
4313       {
4314         if (item->GetEPGInfoTag()->GetDuration() > 0)
4315           duration = StringUtils::SecondsToTimeString(item->GetEPGInfoTag()->GetDuration());
4316       }
4317       else if (item->HasVideoInfoTag())
4318       {
4319         if (item->GetVideoInfoTag()->GetDuration() > 0)
4320           duration.Format("%d", item->GetVideoInfoTag()->GetDuration() / 60);
4321       }
4322       else if (item->HasMusicInfoTag())
4323       {
4324         if (item->GetMusicInfoTag()->GetDuration() > 0)
4325           duration = StringUtils::SecondsToTimeString(item->GetMusicInfoTag()->GetDuration());
4326       }
4327       return duration;
4328     }
4329   case LISTITEM_PLOT:
4330     if (item->HasPVRChannelInfoTag())
4331     {
4332       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4333       CEpgInfoTag tag;
4334       if (channel && channel->GetEPGNow(tag))
4335         return tag.Plot();
4336       return StringUtils::EmptyString;
4337     }
4338     if (item->HasEPGInfoTag())
4339       return item->GetEPGInfoTag()->Plot();
4340     if (item->HasPVRRecordingInfoTag())
4341       return item->GetPVRRecordingInfoTag()->m_strPlot;
4342     if (item->HasVideoInfoTag())
4343     {
4344       if (!(!item->GetVideoInfoTag()->m_strShowTitle.IsEmpty() && item->GetVideoInfoTag()->m_iSeason == -1)) // dont apply to tvshows
4345         if (item->GetVideoInfoTag()->m_playCount == 0 && !g_guiSettings.GetBool("videolibrary.showunwatchedplots"))
4346           return g_localizeStrings.Get(20370);
4347
4348       return item->GetVideoInfoTag()->m_strPlot;
4349     }
4350     break;
4351   case LISTITEM_PLOT_OUTLINE:
4352     if (item->HasPVRChannelInfoTag())
4353     {
4354       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4355       CEpgInfoTag tag;
4356       if (channel && channel->GetEPGNow(tag))
4357         return tag.PlotOutline();
4358       return StringUtils::EmptyString;
4359     }
4360     if (item->HasEPGInfoTag())
4361       return item->GetEPGInfoTag()->PlotOutline();
4362     if (item->HasPVRRecordingInfoTag())
4363       return item->GetPVRRecordingInfoTag()->m_strPlotOutline;
4364     if (item->HasVideoInfoTag())
4365       return item->GetVideoInfoTag()->m_strPlotOutline;
4366     break;
4367   case LISTITEM_EPISODE:
4368     if (item->HasVideoInfoTag())
4369     {
4370       CStdString strResult;
4371       if (item->GetVideoInfoTag()->m_iSpecialSortEpisode > 0)
4372         strResult.Format("S%d",item->GetVideoInfoTag()->m_iEpisode);
4373       else if (item->GetVideoInfoTag()->m_iEpisode > 0) // if m_iEpisode = -1 there's no episode detail
4374         strResult.Format("%d",item->GetVideoInfoTag()->m_iEpisode);
4375       return strResult;
4376     }
4377     break;
4378   case LISTITEM_SEASON:
4379     if (item->HasVideoInfoTag())
4380     {
4381       CStdString strResult;
4382       if (item->GetVideoInfoTag()->m_iSpecialSortSeason > 0)
4383         strResult.Format("%d",item->GetVideoInfoTag()->m_iSpecialSortSeason);
4384       else if (item->GetVideoInfoTag()->m_iSeason > 0) // if m_iSeason = -1 there's no season detail
4385         strResult.Format("%d",item->GetVideoInfoTag()->m_iSeason);
4386       return strResult;
4387     }
4388     break;
4389   case LISTITEM_TVSHOW:
4390     if (item->HasVideoInfoTag())
4391       return item->GetVideoInfoTag()->m_strShowTitle;
4392     break;
4393   case LISTITEM_COMMENT:
4394     if (item->HasPVRTimerInfoTag())
4395       return item->GetPVRTimerInfoTag()->GetStatus();
4396     if (item->HasMusicInfoTag())
4397       return item->GetMusicInfoTag()->GetComment();
4398     break;
4399   case LISTITEM_ACTUAL_ICON:
4400     return item->GetIconImage();
4401   case LISTITEM_ICON:
4402     {
4403       CStdString strThumb = item->GetArt("thumb");
4404       if (strThumb.IsEmpty())
4405         strThumb = item->GetIconImage();
4406       if (fallback)
4407         *fallback = item->GetIconImage();
4408       return strThumb;
4409     }
4410   case LISTITEM_OVERLAY:
4411     return item->GetOverlayImage();
4412   case LISTITEM_THUMB:
4413     return item->GetArt("thumb");
4414   case LISTITEM_FOLDERPATH:
4415     return CURL(item->GetPath()).GetWithoutUserDetails();
4416   case LISTITEM_FOLDERNAME:
4417   case LISTITEM_PATH:
4418     {
4419       CStdString path;
4420       if (item->IsMusicDb() && item->HasMusicInfoTag())
4421         URIUtils::GetDirectory(item->GetMusicInfoTag()->GetURL(), path);
4422       else if (item->IsVideoDb() && item->HasVideoInfoTag())
4423       {
4424         if( item->m_bIsFolder )
4425           path = item->GetVideoInfoTag()->m_strPath;
4426         else
4427           URIUtils::GetParentPath(item->GetVideoInfoTag()->m_strFileNameAndPath, path);
4428       }
4429       else
4430         URIUtils::GetParentPath(item->GetPath(), path);
4431       path = CURL(path).GetWithoutUserDetails();
4432       if (info==LISTITEM_FOLDERNAME)
4433       {
4434         URIUtils::RemoveSlashAtEnd(path);
4435         path=URIUtils::GetFileName(path);
4436       }
4437       CURL::Decode(path);
4438       return path;
4439     }
4440   case LISTITEM_FILENAME_AND_PATH:
4441     {
4442       CStdString path;
4443       if (item->IsMusicDb() && item->HasMusicInfoTag())
4444         path = item->GetMusicInfoTag()->GetURL();
4445       else if (item->IsVideoDb() && item->HasVideoInfoTag())
4446         path = item->GetVideoInfoTag()->m_strFileNameAndPath;
4447       else
4448         path = item->GetPath();
4449       path = CURL(path).GetWithoutUserDetails();
4450       CURL::Decode(path);
4451       return path;
4452     }
4453   case LISTITEM_PICTURE_PATH:
4454     if (item->IsPicture() && (!item->IsZIP() || item->IsRAR() || item->IsCBZ() || item->IsCBR()))
4455       return item->GetPath();
4456     break;
4457   case LISTITEM_STUDIO:
4458     if (item->HasVideoInfoTag())
4459       return StringUtils::Join(item->GetVideoInfoTag()->m_studio, g_advancedSettings.m_videoItemSeparator);
4460     break;
4461   case LISTITEM_COUNTRY:
4462     if (item->HasVideoInfoTag())
4463       return StringUtils::Join(item->GetVideoInfoTag()->m_country, g_advancedSettings.m_videoItemSeparator);
4464     break;
4465   case LISTITEM_MPAA:
4466     if (item->HasVideoInfoTag())
4467       return item->GetVideoInfoTag()->m_strMPAARating;
4468     break;
4469   case LISTITEM_CAST:
4470     if (item->HasVideoInfoTag())
4471       return item->GetVideoInfoTag()->GetCast();
4472     break;
4473   case LISTITEM_CAST_AND_ROLE:
4474     if (item->HasVideoInfoTag())
4475       return item->GetVideoInfoTag()->GetCast(true);
4476     break;
4477   case LISTITEM_WRITER:
4478     if (item->HasVideoInfoTag())
4479       return StringUtils::Join(item->GetVideoInfoTag()->m_writingCredits, g_advancedSettings.m_videoItemSeparator);
4480     break;
4481   case LISTITEM_TAGLINE:
4482     if (item->HasVideoInfoTag())
4483       return item->GetVideoInfoTag()->m_strTagLine;
4484     break;
4485   case LISTITEM_TRAILER:
4486     if (item->HasVideoInfoTag())
4487       return item->GetVideoInfoTag()->m_strTrailer;
4488     break;
4489   case LISTITEM_TOP250:
4490     if (item->HasVideoInfoTag())
4491     {
4492       CStdString strResult;
4493       if (item->GetVideoInfoTag()->m_iTop250 > 0)
4494         strResult.Format("%i",item->GetVideoInfoTag()->m_iTop250);
4495       return strResult;
4496     }
4497     break;
4498   case LISTITEM_SORT_LETTER:
4499     {
4500       CStdString letter;
4501       g_charsetConverter.wToUTF8(item->GetSortLabel().Left(1).ToUpper(), letter);
4502       return letter;
4503     }
4504     break;
4505   case LISTITEM_VIDEO_CODEC:
4506     if (item->HasVideoInfoTag())
4507       return item->GetVideoInfoTag()->m_streamDetails.GetVideoCodec();
4508     break;
4509   case LISTITEM_VIDEO_RESOLUTION:
4510     if (item->HasVideoInfoTag())
4511       return CStreamDetails::VideoDimsToResolutionDescription(item->GetVideoInfoTag()->m_streamDetails.GetVideoWidth(), item->GetVideoInfoTag()->m_streamDetails.GetVideoHeight());
4512     break;
4513   case LISTITEM_VIDEO_ASPECT:
4514     if (item->HasVideoInfoTag())
4515       return CStreamDetails::VideoAspectToAspectDescription(item->GetVideoInfoTag()->m_streamDetails.GetVideoAspect());
4516     break;
4517   case LISTITEM_AUDIO_CODEC:
4518     if (item->HasVideoInfoTag())
4519     {
4520       return item->GetVideoInfoTag()->m_streamDetails.GetAudioCodec();
4521     }
4522     break;
4523   case LISTITEM_AUDIO_CHANNELS:
4524     if (item->HasVideoInfoTag())
4525     {
4526       CStdString strResult;
4527       int iChannels = item->GetVideoInfoTag()->m_streamDetails.GetAudioChannels();
4528       if (iChannels > -1)
4529         strResult.Format("%i", iChannels);
4530       return strResult;
4531     }
4532     break;
4533   case LISTITEM_AUDIO_LANGUAGE:
4534     if (item->HasVideoInfoTag())
4535       return item->GetVideoInfoTag()->m_streamDetails.GetAudioLanguage();
4536     break;
4537   case LISTITEM_SUBTITLE_LANGUAGE:
4538     if (item->HasVideoInfoTag())
4539       return item->GetVideoInfoTag()->m_streamDetails.GetSubtitleLanguage();
4540     break;
4541   case LISTITEM_STARTTIME:
4542     if (item->HasPVRChannelInfoTag())
4543     {
4544       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4545       CEpgInfoTag tag;
4546       if (channel && channel->GetEPGNow(tag))
4547         return tag.StartAsLocalTime().GetAsLocalizedTime("", false);
4548       return CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
4549     }
4550     if (item->HasEPGInfoTag())
4551       return item->GetEPGInfoTag()->StartAsLocalTime().GetAsLocalizedTime("", false);
4552     if (item->HasPVRTimerInfoTag())
4553       return item->GetPVRTimerInfoTag()->StartAsLocalTime().GetAsLocalizedTime("", false);
4554     if (item->HasPVRRecordingInfoTag())
4555       return item->GetPVRRecordingInfoTag()->RecordingTimeAsLocalTime().GetAsLocalizedTime("", false);
4556     if (item->m_dateTime.IsValid())
4557       return item->m_dateTime.GetAsLocalizedTime("", false);
4558     break;
4559   case LISTITEM_ENDTIME:
4560     if (item->HasPVRChannelInfoTag())
4561     {
4562       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4563       CEpgInfoTag tag;
4564       if (channel && channel->GetEPGNow(tag))
4565         return tag.EndAsLocalTime().GetAsLocalizedTime("", false);
4566       return CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
4567     }
4568     if (item->HasEPGInfoTag())
4569       return item->GetEPGInfoTag()->EndAsLocalTime().GetAsLocalizedTime("", false);
4570     if (item->HasPVRTimerInfoTag())
4571       return item->GetPVRTimerInfoTag()->EndAsLocalTime().GetAsLocalizedTime("", false);
4572     break;
4573   case LISTITEM_STARTDATE:
4574     if (item->HasPVRChannelInfoTag())
4575     {
4576       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4577       CEpgInfoTag tag;
4578       if (channel && channel->GetEPGNow(tag))
4579         return tag.StartAsLocalTime().GetAsLocalizedDate(true);
4580       return CDateTime::GetCurrentDateTime().GetAsLocalizedDate(true);
4581     }
4582     if (item->HasEPGInfoTag())
4583       return item->GetEPGInfoTag()->StartAsLocalTime().GetAsLocalizedDate(true);
4584     if (item->HasPVRTimerInfoTag())
4585       return item->GetPVRTimerInfoTag()->StartAsLocalTime().GetAsLocalizedDate(true);
4586     if (item->HasPVRRecordingInfoTag())
4587       return item->GetPVRRecordingInfoTag()->RecordingTimeAsLocalTime().GetAsLocalizedDate(true);
4588     if (item->m_dateTime.IsValid())
4589       return item->m_dateTime.GetAsLocalizedDate(true);
4590     break;
4591   case LISTITEM_ENDDATE:
4592     if (item->HasPVRChannelInfoTag())
4593     {
4594       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4595       CEpgInfoTag tag;
4596       if (channel && channel->GetEPGNow(tag))
4597         return tag.EndAsLocalTime().GetAsLocalizedDate(true);
4598       return CDateTime::GetCurrentDateTime().GetAsLocalizedDate(true);
4599     }
4600     if (item->HasEPGInfoTag())
4601       return item->GetEPGInfoTag()->EndAsLocalTime().GetAsLocalizedDate(true);
4602     if (item->HasPVRTimerInfoTag())
4603       return item->GetPVRTimerInfoTag()->EndAsLocalTime().GetAsLocalizedDate(true);
4604     break;
4605   case LISTITEM_CHANNEL_NUMBER:
4606     {
4607       CStdString number;
4608       if (item->HasPVRChannelInfoTag())
4609         number.Format("%i", item->GetPVRChannelInfoTag()->ChannelNumber());
4610       if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->HasPVRChannel())
4611         number.Format("%i", item->GetEPGInfoTag()->PVRChannelNumber());
4612       if (item->HasPVRTimerInfoTag())
4613         number.Format("%i", item->GetPVRTimerInfoTag()->ChannelNumber());
4614
4615       return number;
4616     }
4617     break;
4618   case LISTITEM_CHANNEL_NAME:
4619     if (item->HasPVRChannelInfoTag())
4620       return item->GetPVRChannelInfoTag()->ChannelName();
4621     if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->HasPVRChannel())
4622       return item->GetEPGInfoTag()->PVRChannelName();
4623     if (item->HasPVRRecordingInfoTag())
4624       return item->GetPVRRecordingInfoTag()->m_strChannelName;
4625     if (item->HasPVRTimerInfoTag())
4626       return item->GetPVRTimerInfoTag()->ChannelName();
4627     break;
4628   case LISTITEM_NEXT_STARTTIME:
4629     {
4630       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4631       CEpgInfoTag tag;
4632       if (channel && channel->GetEPGNext(tag))
4633         return tag.StartAsLocalTime().GetAsLocalizedTime("", false);
4634     }
4635     return CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
4636   case LISTITEM_NEXT_ENDTIME:
4637     {
4638       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4639       CEpgInfoTag tag;
4640       if (channel && channel->GetEPGNext(tag))
4641         return tag.EndAsLocalTime().GetAsLocalizedTime("", false);
4642     }
4643     return CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
4644   case LISTITEM_NEXT_STARTDATE:
4645     {
4646       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4647       CEpgInfoTag tag;
4648       if (channel && channel->GetEPGNext(tag))
4649         return tag.StartAsLocalTime().GetAsLocalizedDate(true);
4650     }
4651     return CDateTime::GetCurrentDateTime().GetAsLocalizedDate(true);
4652   case LISTITEM_NEXT_ENDDATE:
4653     {
4654       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4655       CEpgInfoTag tag;
4656       if (channel && channel->GetEPGNext(tag))
4657         return tag.EndAsLocalTime().GetAsLocalizedDate(true);
4658     }
4659     return CDateTime::GetCurrentDateTime().GetAsLocalizedDate(true);
4660   case LISTITEM_NEXT_PLOT:
4661     {
4662       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4663       CEpgInfoTag tag;
4664       if (channel && channel->GetEPGNext(tag))
4665         return tag.Plot();
4666     }
4667     return StringUtils::EmptyString;
4668   case LISTITEM_NEXT_PLOT_OUTLINE:
4669     {
4670       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4671       CEpgInfoTag tag;
4672       if (channel && channel->GetEPGNext(tag))
4673         return tag.PlotOutline();
4674     }
4675     return StringUtils::EmptyString;
4676   case LISTITEM_NEXT_DURATION:
4677     {
4678       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4679       CEpgInfoTag tag;
4680       if (channel && channel->GetEPGNext(tag))
4681         return StringUtils::SecondsToTimeString(tag.GetDuration());
4682     }
4683     return StringUtils::EmptyString;
4684   case LISTITEM_NEXT_GENRE:
4685     {
4686       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4687       CEpgInfoTag tag;
4688       if (channel && channel->GetEPGNext(tag))
4689         return StringUtils::Join(tag.Genre(), g_advancedSettings.m_videoItemSeparator);
4690     }
4691     return StringUtils::EmptyString;
4692   case LISTITEM_NEXT_TITLE:
4693     {
4694       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4695       CEpgInfoTag tag;
4696       if (channel && channel->GetEPGNext(tag))
4697         return tag.Title();
4698     }
4699     return StringUtils::EmptyString;
4700   case LISTITEM_PARENTALRATING:
4701     {
4702       CStdString rating;
4703       if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->ParentalRating() > 0)
4704         rating.Format("%i", item->GetEPGInfoTag()->ParentalRating());
4705       return rating;
4706     }
4707     break;
4708   case LISTITEM_PERCENT_PLAYED:
4709     {
4710       int val;
4711       if (GetItemInt(val, item, info))
4712       {
4713         CStdString str;
4714         str.Format("%d", val);
4715         return str;
4716       }
4717       break;
4718     }
4719   case LISTITEM_DATE_ADDED:
4720     if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_dateAdded.IsValid())
4721       return item->GetVideoInfoTag()->m_dateAdded.GetAsLocalizedDate();
4722     break;
4723   case LISTITEM_DBTYPE:
4724     if (item->HasVideoInfoTag())
4725       return item->GetVideoInfoTag()->m_type;
4726     break;
4727   case LISTITEM_DBID:
4728     if (item->HasVideoInfoTag())
4729       {
4730         CStdString dbid;
4731         dbid.Format("%i", item->GetVideoInfoTag()->m_iDbId);
4732         return dbid;
4733       }
4734     if (item->HasMusicInfoTag())
4735       {
4736         CStdString dbid;
4737         dbid.Format("%i", item->GetMusicInfoTag()->GetDatabaseId());
4738         return dbid;
4739       }
4740     break;
4741   }
4742   return "";
4743 }
4744
4745 CStdString CGUIInfoManager::GetItemImage(const CFileItem *item, int info, CStdString *fallback)
4746 {
4747   if (info >= CONDITIONAL_LABEL_START && info <= CONDITIONAL_LABEL_END)
4748     return GetSkinVariableString(info, true, item);
4749
4750   switch (info)
4751   {
4752   case LISTITEM_RATING:  // old song rating format
4753     {
4754       CStdString rating;
4755       if (item->HasMusicInfoTag())
4756       {
4757         rating.Format("songrating%c.png", item->GetMusicInfoTag()->GetRating());
4758         return rating;
4759       }
4760     }
4761     break;
4762   case LISTITEM_STAR_RATING:
4763     {
4764       CStdString rating;
4765       if (item->HasVideoInfoTag())
4766       { // rating for videos is assumed 0..10, so convert to 0..5
4767         rating.Format("rating%d.png", (long)((item->GetVideoInfoTag()->m_fRating * 0.5f) + 0.5f));
4768       }
4769       else if (item->HasMusicInfoTag())
4770       { // song rating.
4771         rating.Format("rating%c.png", item->GetMusicInfoTag()->GetRating());
4772       }
4773       return rating;
4774     }
4775     break;
4776   }  /* switch (info) */
4777
4778   return GetItemLabel(item, info, fallback);
4779 }
4780
4781 bool CGUIInfoManager::GetItemBool(const CGUIListItem *item, int condition) const
4782 {
4783   if (!item) return false;
4784   if (condition >= LISTITEM_PROPERTY_START && condition - LISTITEM_PROPERTY_START < (int)m_listitemProperties.size())
4785   { // grab the property
4786     CStdString property = m_listitemProperties[condition - LISTITEM_PROPERTY_START];
4787     return item->GetProperty(property).asBoolean();
4788   }
4789   else if (condition == LISTITEM_ISPLAYING)
4790   {
4791     if (item->HasProperty("playlistposition"))
4792       return (int)item->GetProperty("playlisttype").asInteger() == g_playlistPlayer.GetCurrentPlaylist() && (int)item->GetProperty("playlistposition").asInteger() == g_playlistPlayer.GetCurrentSong();
4793     else if (item->IsFileItem() && !m_currentFile->GetPath().IsEmpty())
4794     {
4795       if (!g_application.m_strPlayListFile.IsEmpty())
4796       {
4797         //playlist file that is currently playing or the playlistitem that is currently playing.
4798         return g_application.m_strPlayListFile.Equals(((const CFileItem *)item)->GetPath()) || m_currentFile->IsSamePath((const CFileItem *)item);
4799       }
4800       return m_currentFile->IsSamePath((const CFileItem *)item);
4801     }
4802   }
4803   else if (condition == LISTITEM_ISSELECTED)
4804     return item->IsSelected();
4805   else if (condition == LISTITEM_IS_FOLDER)
4806     return item->m_bIsFolder;
4807   else if (condition == LISTITEM_IS_RESUMABLE)
4808   {
4809     if (item->IsFileItem())
4810     {
4811       if (((const CFileItem *)item)->HasVideoInfoTag())
4812         return ((const CFileItem *)item)->GetVideoInfoTag()->m_resumePoint.timeInSeconds > 0;
4813       else if (((const CFileItem *)item)->HasPVRRecordingInfoTag())
4814         return ((const CFileItem *)item)->GetPVRRecordingInfoTag()->m_resumePoint.timeInSeconds > 0;
4815     }
4816   }
4817   else if (item->IsFileItem())
4818   {
4819     const CFileItem *pItem = (const CFileItem *)item;
4820     if (condition == LISTITEM_ISRECORDING)
4821     {
4822       if (!g_PVRManager.IsStarted())
4823         return false;
4824
4825       if (pItem->HasPVRChannelInfoTag())
4826       {
4827         return pItem->GetPVRChannelInfoTag()->IsRecording();
4828       }
4829       else if (pItem->HasPVRTimerInfoTag())
4830       {
4831         const CPVRTimerInfoTag *timer = pItem->GetPVRTimerInfoTag();
4832         if (timer)
4833           return timer->IsRecording();
4834       }
4835       else if (pItem->HasEPGInfoTag())
4836       {
4837         CFileItemPtr timer = g_PVRTimers->GetTimerForEpgTag(pItem);
4838         if (timer && timer->HasPVRTimerInfoTag())
4839           return timer->GetPVRTimerInfoTag()->IsRecording();
4840       }
4841     }
4842     else if (condition == LISTITEM_HASTIMER)
4843     {
4844       if (pItem->HasEPGInfoTag())
4845       {
4846         CFileItemPtr timer = g_PVRTimers->GetTimerForEpgTag(pItem);
4847         if (timer && timer->HasPVRTimerInfoTag())
4848           return timer->GetPVRTimerInfoTag()->IsActive();
4849       }
4850     }
4851     else if (condition == LISTITEM_HAS_EPG)
4852     {
4853       if (pItem->HasPVRChannelInfoTag())
4854       {
4855         CEpgInfoTag epgTag;
4856         return pItem->GetPVRChannelInfoTag()->GetEPGNow(epgTag);
4857       }
4858       else
4859       {
4860         return pItem->HasEPGInfoTag();
4861       }
4862     }
4863     else if (condition == LISTITEM_ISENCRYPTED)
4864     {
4865       if (pItem->HasPVRChannelInfoTag())
4866       {
4867         return pItem->GetPVRChannelInfoTag()->IsEncrypted();
4868       }
4869       else if (pItem->HasEPGInfoTag() && pItem->GetEPGInfoTag()->HasPVRChannel())
4870       {
4871         return pItem->GetEPGInfoTag()->ChannelTag()->IsEncrypted();
4872       }
4873     }
4874   }
4875
4876   return false;
4877 }
4878
4879 void CGUIInfoManager::ResetCache()
4880 {
4881   // reset any animation triggers as well
4882   m_containerMoves.clear();
4883   m_updateTime++;
4884 }
4885
4886 // Called from tuxbox service thread to update current status
4887 void CGUIInfoManager::UpdateFromTuxBox()
4888 {
4889   if(g_tuxbox.vVideoSubChannel.mode)
4890     m_currentFile->GetVideoInfoTag()->m_strTitle = g_tuxbox.vVideoSubChannel.current_name;
4891
4892   // Set m_currentMovieDuration
4893   if(!g_tuxbox.sCurSrvData.current_event_duration.IsEmpty() &&
4894     !g_tuxbox.sCurSrvData.next_event_description.IsEmpty() &&
4895     !g_tuxbox.sCurSrvData.current_event_duration.Equals("-") &&
4896     !g_tuxbox.sCurSrvData.next_event_description.Equals("-"))
4897   {
4898     g_tuxbox.sCurSrvData.current_event_duration.Replace("(","");
4899     g_tuxbox.sCurSrvData.current_event_duration.Replace(")","");
4900
4901     m_currentMovieDuration.Format("%s: %s %s (%s - %s)",
4902       g_localizeStrings.Get(180),
4903       g_tuxbox.sCurSrvData.current_event_duration,
4904       g_localizeStrings.Get(12391),
4905       g_tuxbox.sCurSrvData.current_event_time,
4906       g_tuxbox.sCurSrvData.next_event_time);
4907   }
4908
4909   //Set strVideoGenre
4910   if (!g_tuxbox.sCurSrvData.current_event_description.IsEmpty() &&
4911     !g_tuxbox.sCurSrvData.next_event_description.IsEmpty() &&
4912     !g_tuxbox.sCurSrvData.current_event_description.Equals("-") &&
4913     !g_tuxbox.sCurSrvData.next_event_description.Equals("-"))
4914   {
4915     CStdString genre;
4916     genre.Format("%s %s  -  (%s: %s)",
4917       g_localizeStrings.Get(143),
4918       g_tuxbox.sCurSrvData.current_event_description,
4919       g_localizeStrings.Get(209),
4920       g_tuxbox.sCurSrvData.next_event_description);
4921     m_currentFile->GetVideoInfoTag()->m_genre = StringUtils::Split(genre, g_advancedSettings.m_videoItemSeparator);
4922   }
4923
4924   //Set m_currentMovie.m_director
4925   if (!g_tuxbox.sCurSrvData.current_event_details.Equals("-") &&
4926     !g_tuxbox.sCurSrvData.current_event_details.IsEmpty())
4927   {
4928     m_currentFile->GetVideoInfoTag()->m_director = StringUtils::Split(g_tuxbox.sCurSrvData.current_event_details, g_advancedSettings.m_videoItemSeparator);
4929   }
4930 }
4931
4932 CStdString CGUIInfoManager::GetPictureLabel(int info)
4933 {
4934   if (info == SLIDE_FILE_NAME)
4935     return GetItemLabel(m_currentSlide, LISTITEM_FILENAME);
4936   else if (info == SLIDE_FILE_PATH)
4937   {
4938     CStdString path;
4939     URIUtils::GetDirectory(m_currentSlide->GetPath(), path);
4940     return CURL(path).GetWithoutUserDetails();
4941   }
4942   else if (info == SLIDE_FILE_SIZE)
4943     return GetItemLabel(m_currentSlide, LISTITEM_SIZE);
4944   else if (info == SLIDE_FILE_DATE)
4945     return GetItemLabel(m_currentSlide, LISTITEM_DATE);
4946   else if (info == SLIDE_INDEX)
4947   {
4948     CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
4949     if (slideshow && slideshow->NumSlides())
4950     {
4951       CStdString index;
4952       index.Format("%d/%d", slideshow->CurrentSlide(), slideshow->NumSlides());
4953       return index;
4954     }
4955   }
4956   if (m_currentSlide->HasPictureInfoTag())
4957     return m_currentSlide->GetPictureInfoTag()->GetInfo(info);
4958   return "";
4959 }
4960
4961 void CGUIInfoManager::SetCurrentSlide(CFileItem &item)
4962 {
4963   if (m_currentSlide->GetPath() != item.GetPath())
4964   {
4965     if (!item.GetPictureInfoTag()->Loaded()) // If picture metadata has not been loaded yet, load it now
4966       item.GetPictureInfoTag()->Load(item.GetPath());
4967     *m_currentSlide = item;
4968   }
4969 }
4970
4971 void CGUIInfoManager::ResetCurrentSlide()
4972 {
4973   m_currentSlide->Reset();
4974 }
4975
4976 bool CGUIInfoManager::CheckWindowCondition(CGUIWindow *window, int condition) const
4977 {
4978   // check if it satisfies our condition
4979   if (!window) return false;
4980   if ((condition & WINDOW_CONDITION_HAS_LIST_ITEMS) && !window->HasListItems())
4981     return false;
4982   if ((condition & WINDOW_CONDITION_IS_MEDIA_WINDOW) && !window->IsMediaWindow())
4983     return false;
4984   return true;
4985 }
4986
4987 CGUIWindow *CGUIInfoManager::GetWindowWithCondition(int contextWindow, int condition) const
4988 {
4989   CGUIWindow *window = g_windowManager.GetWindow(contextWindow);
4990   if (CheckWindowCondition(window, condition))
4991     return window;
4992
4993   // try topmost dialog
4994   window = g_windowManager.GetWindow(g_windowManager.GetTopMostModalDialogID());
4995   if (CheckWindowCondition(window, condition))
4996     return window;
4997
4998   // try active window
4999   window = g_windowManager.GetWindow(g_windowManager.GetActiveWindow());
5000   if (CheckWindowCondition(window, condition))
5001     return window;
5002
5003   return NULL;
5004 }
5005
5006 void CGUIInfoManager::SetCurrentVideoTag(const CVideoInfoTag &tag)
5007 {
5008   *m_currentFile->GetVideoInfoTag() = tag;
5009   m_currentFile->m_lStartOffset = 0;
5010 }
5011
5012 void CGUIInfoManager::SetCurrentSongTag(const MUSIC_INFO::CMusicInfoTag &tag)
5013 {
5014   //CLog::Log(LOGDEBUG, "Asked to SetCurrentTag");
5015   *m_currentFile->GetMusicInfoTag() = tag;
5016   m_currentFile->m_lStartOffset = 0;
5017 }
5018
5019 const CFileItem& CGUIInfoManager::GetCurrentSlide() const
5020 {
5021   return *m_currentSlide;
5022 }
5023
5024 const MUSIC_INFO::CMusicInfoTag* CGUIInfoManager::GetCurrentSongTag() const
5025 {
5026   if (m_currentFile->HasMusicInfoTag())
5027     return m_currentFile->GetMusicInfoTag();
5028
5029   return NULL;
5030 }
5031
5032 const CVideoInfoTag* CGUIInfoManager::GetCurrentMovieTag() const
5033 {
5034   if (m_currentFile->HasVideoInfoTag())
5035     return m_currentFile->GetVideoInfoTag();
5036
5037   return NULL;
5038 }
5039
5040 void GUIInfo::SetInfoFlag(uint32_t flag)
5041 {
5042   assert(flag >= (1 << 24));
5043   m_data1 |= flag;
5044 }
5045
5046 uint32_t GUIInfo::GetInfoFlag() const
5047 {
5048   // we strip out the bottom 24 bits, where we keep data
5049   // and return the flag only
5050   return m_data1 & 0xff000000;
5051 }
5052
5053 uint32_t GUIInfo::GetData1() const
5054 {
5055   // we strip out the top 8 bits, where we keep flags
5056   // and return the unflagged data
5057   return m_data1 & ((1 << 24) -1);
5058 }
5059
5060 int GUIInfo::GetData2() const
5061 {
5062   return m_data2;
5063 }
5064
5065 void CGUIInfoManager::SetLibraryBool(int condition, bool value)
5066 {
5067   switch (condition)
5068   {
5069     case LIBRARY_HAS_MUSIC:
5070       m_libraryHasMusic = value ? 1 : 0;
5071       break;
5072     case LIBRARY_HAS_MOVIES:
5073       m_libraryHasMovies = value ? 1 : 0;
5074       break;
5075     case LIBRARY_HAS_MOVIE_SETS:
5076       m_libraryHasMovieSets = value ? 1 : 0;
5077       break;
5078     case LIBRARY_HAS_TVSHOWS:
5079       m_libraryHasTVShows = value ? 1 : 0;
5080       break;
5081     case LIBRARY_HAS_MUSICVIDEOS:
5082       m_libraryHasMusicVideos = value ? 1 : 0;
5083       break;
5084     default:
5085       break;
5086   }
5087 }
5088
5089 void CGUIInfoManager::ResetLibraryBools()
5090 {
5091   m_libraryHasMusic = -1;
5092   m_libraryHasMovies = -1;
5093   m_libraryHasTVShows = -1;
5094   m_libraryHasMusicVideos = -1;
5095   m_libraryHasMovieSets = -1;
5096 }
5097
5098 bool CGUIInfoManager::GetLibraryBool(int condition)
5099 {
5100   if (condition == LIBRARY_HAS_MUSIC)
5101   {
5102     if (m_libraryHasMusic < 0)
5103     { // query
5104       CMusicDatabase db;
5105       if (db.Open())
5106       {
5107         m_libraryHasMusic = (db.GetSongsCount() > 0) ? 1 : 0;
5108         db.Close();
5109       }
5110     }
5111     return m_libraryHasMusic > 0;
5112   }
5113   else if (condition == LIBRARY_HAS_MOVIES)
5114   {
5115     if (m_libraryHasMovies < 0)
5116     {
5117       CVideoDatabase db;
5118       if (db.Open())
5119       {
5120         m_libraryHasMovies = db.HasContent(VIDEODB_CONTENT_MOVIES) ? 1 : 0;
5121         db.Close();
5122       }
5123     }
5124     return m_libraryHasMovies > 0;
5125   }
5126   else if (condition == LIBRARY_HAS_MOVIE_SETS)
5127   {
5128     if (m_libraryHasMovieSets < 0)
5129     {
5130       CVideoDatabase db;
5131       if (db.Open())
5132       {
5133         m_libraryHasMovieSets = db.HasSets() ? 1 : 0;
5134         db.Close();
5135       }
5136     }
5137     return m_libraryHasMovieSets > 0;
5138   }
5139   else if (condition == LIBRARY_HAS_TVSHOWS)
5140   {
5141     if (m_libraryHasTVShows < 0)
5142     {
5143       CVideoDatabase db;
5144       if (db.Open())
5145       {
5146         m_libraryHasTVShows = db.HasContent(VIDEODB_CONTENT_TVSHOWS) ? 1 : 0;
5147         db.Close();
5148       }
5149     }
5150     return m_libraryHasTVShows > 0;
5151   }
5152   else if (condition == LIBRARY_HAS_MUSICVIDEOS)
5153   {
5154     if (m_libraryHasMusicVideos < 0)
5155     {
5156       CVideoDatabase db;
5157       if (db.Open())
5158       {
5159         m_libraryHasMusicVideos = db.HasContent(VIDEODB_CONTENT_MUSICVIDEOS) ? 1 : 0;
5160         db.Close();
5161       }
5162     }
5163     return m_libraryHasMusicVideos > 0;
5164   }
5165   else if (condition == LIBRARY_HAS_VIDEO)
5166   {
5167     return (GetLibraryBool(LIBRARY_HAS_MOVIES) ||
5168             GetLibraryBool(LIBRARY_HAS_TVSHOWS) ||
5169             GetLibraryBool(LIBRARY_HAS_MUSICVIDEOS));
5170   }
5171   return false;
5172 }
5173
5174 int CGUIInfoManager::RegisterSkinVariableString(const CSkinVariableString* info)
5175 {
5176   if (!info)
5177     return 0;
5178
5179   CSingleLock lock(m_critInfo);
5180   m_skinVariableStrings.push_back(*info);
5181   delete info;
5182   return CONDITIONAL_LABEL_START + m_skinVariableStrings.size() - 1;
5183 }
5184
5185 int CGUIInfoManager::TranslateSkinVariableString(const CStdString& name, int context)
5186 {
5187   for (vector<CSkinVariableString>::const_iterator it = m_skinVariableStrings.begin();
5188        it != m_skinVariableStrings.end(); ++it)
5189   {
5190     if (it->GetName().Equals(name) && it->GetContext() == context)
5191       return it - m_skinVariableStrings.begin() + CONDITIONAL_LABEL_START;
5192   }
5193   return 0;
5194 }
5195
5196 CStdString CGUIInfoManager::GetSkinVariableString(int info,
5197                                                   bool preferImage /*= false*/,
5198                                                   const CGUIListItem *item /*= NULL*/)
5199 {
5200   info -= CONDITIONAL_LABEL_START;
5201   if (info >= 0 && info < (int)m_skinVariableStrings.size())
5202     return m_skinVariableStrings[info].GetValue(preferImage, item);
5203
5204   return "";
5205 }
5206
5207 bool CGUIInfoManager::ConditionsChangedValues(const std::map<int, bool>& map)
5208 {
5209   for (std::map<int, bool>::const_iterator it = map.begin() ; it != map.end() ; it++)
5210   {
5211     if (GetBoolValue(it->first) != it->second)
5212       return true;
5213   }
5214   return false;
5215 }
5216
5217 bool CGUIInfoManager::GetEpgInfoTag(CEpgInfoTag& tag) const
5218 {
5219   if (m_currentFile->HasEPGInfoTag())
5220   {
5221     CEpgInfoTag* currentTag =  m_currentFile->GetEPGInfoTag();
5222     while (currentTag && !currentTag->IsActive())
5223       currentTag = currentTag->GetNextEvent().get();
5224     if (currentTag)
5225     {
5226       tag = *currentTag;
5227       return true;
5228     }
5229   }
5230   return false;
5231 }