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