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