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