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