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