Merge pull request #5039 from CEikermann/patch-1
[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
2166   if (condition.empty())
2167     return INFO::InfoPtr();
2168
2169   CSingleLock lock(m_critInfo);
2170   // do we have the boolean expression already registered?
2171   vector<InfoPtr>::const_iterator i = find_if(m_bools.begin(), m_bools.end(), InfoBoolFinder(condition, context));
2172   if (i != m_bools.end())
2173     return *i;
2174
2175   if (condition.find_first_of("|+[]!") != condition.npos)
2176     m_bools.push_back(boost::make_shared<InfoExpression>(condition, context));
2177   else
2178     m_bools.push_back(boost::make_shared<InfoSingle>(condition, context));
2179
2180   return m_bools.back();
2181 }
2182
2183 bool CGUIInfoManager::EvaluateBool(const CStdString &expression, int contextWindow)
2184 {
2185   bool result = false;
2186   INFO::InfoPtr info = Register(expression, contextWindow);
2187   if (info)
2188     result = info->Get();
2189   return result;
2190 }
2191
2192 // checks the condition and returns it as necessary.  Currently used
2193 // for toggle button controls and visibility of images.
2194 bool CGUIInfoManager::GetBool(int condition1, int contextWindow, const CGUIListItem *item)
2195 {
2196   bool bReturn = false;
2197   int condition = abs(condition1);
2198
2199   if (condition >= LISTITEM_START && condition < LISTITEM_END)
2200   {
2201     if (item)
2202       bReturn = GetItemBool(item, condition);
2203     else
2204     {
2205       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_HAS_LIST_ITEMS); // true for has list items
2206       if (window)
2207       {
2208         CFileItemPtr item = window->GetCurrentListItem();
2209         bReturn = GetItemBool(item.get(), condition);
2210       }
2211     }
2212   }
2213   // Ethernet Link state checking
2214   // Will check if system has a Ethernet Link connection! [Cable in!]
2215   // This can used for the skinner to switch off Network or Inter required functions
2216   else if ( condition == SYSTEM_ALWAYS_TRUE)
2217     bReturn = true;
2218   else if (condition == SYSTEM_ALWAYS_FALSE)
2219     bReturn = false;
2220   else if (condition == SYSTEM_ETHERNET_LINK_ACTIVE)
2221     bReturn = true;
2222   else if (condition == WINDOW_IS_MEDIA)
2223   { // note: This doesn't return true for dialogs (content, favourites, login, videoinfo)
2224     CGUIWindow *pWindow = g_windowManager.GetWindow(g_windowManager.GetActiveWindow());
2225     bReturn = (pWindow && pWindow->IsMediaWindow());
2226   }
2227   else if (condition == PLAYER_MUTED)
2228     bReturn = g_application.IsMuted();
2229   else if (condition >= LIBRARY_HAS_MUSIC && condition <= LIBRARY_HAS_MUSICVIDEOS)
2230     bReturn = GetLibraryBool(condition);
2231   else if (condition == LIBRARY_IS_SCANNING)
2232   {
2233     if (g_application.IsMusicScanning() || g_application.IsVideoScanning())
2234       bReturn = true;
2235     else
2236       bReturn = false;
2237   }
2238   else if (condition == LIBRARY_IS_SCANNING_VIDEO)
2239   {
2240     bReturn = g_application.IsVideoScanning();
2241   }
2242   else if (condition == LIBRARY_IS_SCANNING_MUSIC)
2243   {
2244     bReturn = g_application.IsMusicScanning();
2245   }
2246   else if (condition == SYSTEM_PLATFORM_LINUX)
2247 #if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
2248     bReturn = true;
2249 #else
2250     bReturn = false;
2251 #endif
2252   else if (condition == SYSTEM_PLATFORM_WINDOWS)
2253 #ifdef TARGET_WINDOWS
2254     bReturn = true;
2255 #else
2256     bReturn = false;
2257 #endif
2258   else if (condition == SYSTEM_PLATFORM_DARWIN)
2259 #ifdef TARGET_DARWIN
2260     bReturn = true;
2261 #else
2262     bReturn = false;
2263 #endif
2264   else if (condition == SYSTEM_PLATFORM_DARWIN_OSX)
2265 #ifdef TARGET_DARWIN_OSX
2266     bReturn = true;
2267 #else
2268     bReturn = false;
2269 #endif
2270   else if (condition == SYSTEM_PLATFORM_DARWIN_IOS)
2271 #ifdef TARGET_DARWIN_IOS
2272     bReturn = true;
2273 #else
2274     bReturn = false;
2275 #endif
2276   else if (condition == SYSTEM_PLATFORM_DARWIN_ATV2)
2277 #ifdef TARGET_DARWIN_IOS_ATV2
2278     bReturn = true;
2279 #else
2280     bReturn = false;
2281 #endif
2282   else if (condition == SYSTEM_PLATFORM_ANDROID)
2283 #if defined(TARGET_ANDROID)
2284     bReturn = true;
2285 #else
2286     bReturn = false;
2287 #endif
2288   else if (condition == SYSTEM_PLATFORM_LINUX_RASPBERRY_PI)
2289 #if defined(TARGET_RASPBERRY_PI)
2290     bReturn = true;
2291 #else
2292     bReturn = false;
2293 #endif
2294   else if (condition == SYSTEM_MEDIA_DVD)
2295     bReturn = g_mediaManager.IsDiscInDrive();
2296 #ifdef HAS_DVD_DRIVE
2297   else if (condition == SYSTEM_DVDREADY)
2298     bReturn = g_mediaManager.GetDriveStatus() != DRIVE_NOT_READY;
2299   else if (condition == SYSTEM_TRAYOPEN)
2300     bReturn = g_mediaManager.GetDriveStatus() == DRIVE_OPEN;
2301 #endif
2302   else if (condition == SYSTEM_CAN_POWERDOWN)
2303     bReturn = g_powerManager.CanPowerdown();
2304   else if (condition == SYSTEM_CAN_SUSPEND)
2305     bReturn = g_powerManager.CanSuspend();
2306   else if (condition == SYSTEM_CAN_HIBERNATE)
2307     bReturn = g_powerManager.CanHibernate();
2308   else if (condition == SYSTEM_CAN_REBOOT)
2309     bReturn = g_powerManager.CanReboot();
2310   else if (condition == SYSTEM_SCREENSAVER_ACTIVE)
2311     bReturn = g_application.IsInScreenSaver();
2312
2313   else if (condition == PLAYER_SHOWINFO)
2314     bReturn = m_playerShowInfo;
2315   else if (condition == PLAYER_SHOWCODEC)
2316     bReturn = m_playerShowCodec;
2317   else if (condition >= MULTI_INFO_START && condition <= MULTI_INFO_END)
2318   {
2319     return GetMultiInfoBool(m_multiInfo[condition - MULTI_INFO_START], contextWindow, item);
2320   }
2321   else if (condition == SYSTEM_HASLOCKS)
2322     bReturn = CProfilesManager::Get().GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE;
2323   else if (condition == SYSTEM_HAS_PVR)
2324     bReturn = true;
2325   else if (condition == SYSTEM_ISMASTER)
2326     bReturn = CProfilesManager::Get().GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE && g_passwordManager.bMasterUser;
2327   else if (condition == SYSTEM_ISFULLSCREEN)
2328     bReturn = g_Windowing.IsFullScreen();
2329   else if (condition == SYSTEM_ISSTANDALONE)
2330     bReturn = g_application.IsStandAlone();
2331   else if (condition == SYSTEM_ISINHIBIT)
2332     bReturn = g_application.IsIdleShutdownInhibited();
2333   else if (condition == SYSTEM_HAS_SHUTDOWN)
2334     bReturn = (CSettings::Get().GetInt("powermanagement.shutdowntime") > 0);
2335   else if (condition == SYSTEM_LOGGEDON)
2336     bReturn = !(g_windowManager.GetActiveWindow() == WINDOW_LOGIN_SCREEN);
2337   else if (condition == SYSTEM_SHOW_EXIT_BUTTON)
2338     bReturn = g_advancedSettings.m_showExitButton;
2339   else if (condition == SYSTEM_HAS_LOGINSCREEN)
2340     bReturn = CProfilesManager::Get().UsingLoginScreen();
2341   else if (condition == WEATHER_IS_FETCHED)
2342     bReturn = g_weatherManager.IsFetched();
2343   else if (condition >= PVR_CONDITIONS_START && condition <= PVR_CONDITIONS_END)
2344     bReturn = g_PVRManager.TranslateBoolInfo(condition);
2345
2346   else if (condition == SYSTEM_INTERNET_STATE)
2347   {
2348     g_sysinfo.GetInfo(condition);
2349     bReturn = g_sysinfo.HasInternet();
2350   }
2351   else if (condition == SKIN_HAS_VIDEO_OVERLAY)
2352   {
2353     bReturn = g_windowManager.IsOverlayAllowed() && g_application.m_pPlayer->IsPlayingVideo();
2354   }
2355   else if (condition == SKIN_HAS_MUSIC_OVERLAY)
2356   {
2357     bReturn = g_windowManager.IsOverlayAllowed() && g_application.m_pPlayer->IsPlayingAudio();
2358   }
2359   else if (condition == CONTAINER_HASFILES || condition == CONTAINER_HASFOLDERS)
2360   {
2361     CGUIWindow *pWindow = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2362     if (pWindow)
2363     {
2364       const CFileItemList& items=((CGUIMediaWindow*)pWindow)->CurrentDirectory();
2365       for (int i=0;i<items.Size();++i)
2366       {
2367         CFileItemPtr item=items.Get(i);
2368         if (!item->m_bIsFolder && condition == CONTAINER_HASFILES)
2369         {
2370           bReturn=true;
2371           break;
2372         }
2373         else if (item->m_bIsFolder && !item->IsParentFolder() && condition == CONTAINER_HASFOLDERS)
2374         {
2375           bReturn=true;
2376           break;
2377         }
2378       }
2379     }
2380   }
2381   else if (condition == CONTAINER_STACKED)
2382   {
2383     CGUIWindow *pWindow = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2384     if (pWindow)
2385       bReturn = ((CGUIMediaWindow*)pWindow)->CurrentDirectory().GetProperty("isstacked").asBoolean();
2386   }
2387   else if (condition == CONTAINER_HAS_THUMB)
2388   {
2389     CGUIWindow *pWindow = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2390     if (pWindow)
2391       bReturn = ((CGUIMediaWindow*)pWindow)->CurrentDirectory().HasArt("thumb");
2392   }
2393   else if (condition == CONTAINER_HAS_NEXT || condition == CONTAINER_HAS_PREVIOUS || condition == CONTAINER_SCROLLING)
2394   {
2395     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2396     if (window)
2397     {
2398       const CGUIControl* control = window->GetControl(window->GetViewContainerID());
2399       if (control)
2400         bReturn = control->GetCondition(condition, 0);
2401     }
2402   }
2403   else if (condition == CONTAINER_CAN_FILTER)
2404   {
2405     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2406     if (window)
2407       bReturn = !((CGUIMediaWindow*)window)->CanFilterAdvanced();
2408   }
2409   else if (condition == CONTAINER_CAN_FILTERADVANCED)
2410   {
2411     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2412     if (window)
2413       bReturn = ((CGUIMediaWindow*)window)->CanFilterAdvanced();
2414   }
2415   else if (condition == CONTAINER_FILTERED)
2416   {
2417     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2418     if (window)
2419       bReturn = ((CGUIMediaWindow*)window)->IsFiltered();
2420   }
2421   else if (condition == VIDEOPLAYER_HAS_INFO)
2422     bReturn = ((m_currentFile->HasVideoInfoTag() && !m_currentFile->GetVideoInfoTag()->IsEmpty()) ||
2423                (m_currentFile->HasPVRChannelInfoTag()  && !m_currentFile->GetPVRChannelInfoTag()->IsEmpty()));
2424   else if (condition >= CONTAINER_SCROLL_PREVIOUS && condition <= CONTAINER_SCROLL_NEXT)
2425   {
2426     // no parameters, so we assume it's just requested for a media window.  It therefore
2427     // can only happen if the list has focus.
2428     CGUIWindow *pWindow = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2429     if (pWindow)
2430     {
2431       map<int,int>::const_iterator it = m_containerMoves.find(pWindow->GetViewContainerID());
2432       if (it != m_containerMoves.end())
2433       {
2434         if (condition > CONTAINER_STATIC) // moving up
2435           bReturn = it->second >= std::max(condition - CONTAINER_STATIC, 1);
2436         else
2437           bReturn = it->second <= std::min(condition - CONTAINER_STATIC, -1);
2438       }
2439     }
2440   }
2441   else if (condition == SLIDESHOW_ISPAUSED)
2442   {
2443     CGUIWindowSlideShow *slideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
2444     bReturn = (slideShow && slideShow->IsPaused());
2445   }
2446   else if (condition == SLIDESHOW_ISRANDOM)
2447   {
2448     CGUIWindowSlideShow *slideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
2449     bReturn = (slideShow && slideShow->IsShuffled());
2450   }
2451   else if (condition == SLIDESHOW_ISACTIVE)
2452   {
2453     CGUIWindowSlideShow *slideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
2454     bReturn = (slideShow && slideShow->InSlideShow());
2455   }
2456   else if (condition == SLIDESHOW_ISVIDEO)
2457   {
2458     CGUIWindowSlideShow *slideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
2459     bReturn = (slideShow && slideShow->GetCurrentSlide() && slideShow->GetCurrentSlide()->IsVideo());
2460   }
2461   else if (g_application.m_pPlayer->IsPlaying())
2462   {
2463     switch (condition)
2464     {
2465     case PLAYER_HAS_MEDIA:
2466       bReturn = true;
2467       break;
2468     case PLAYER_HAS_AUDIO:
2469       bReturn = g_application.m_pPlayer->IsPlayingAudio();
2470       break;
2471     case PLAYER_HAS_VIDEO:
2472       bReturn = g_application.m_pPlayer->IsPlayingVideo();
2473       break;
2474     case PLAYER_PLAYING:
2475       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && (g_application.m_pPlayer->GetPlaySpeed() == 1);
2476       break;
2477     case PLAYER_PAUSED:
2478       bReturn = g_application.m_pPlayer->IsPausedPlayback();
2479       break;
2480     case PLAYER_REWINDING:
2481       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() < 1;
2482       break;
2483     case PLAYER_FORWARDING:
2484       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() > 1;
2485       break;
2486     case PLAYER_REWINDING_2x:
2487       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == -2;
2488       break;
2489     case PLAYER_REWINDING_4x:
2490       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == -4;
2491       break;
2492     case PLAYER_REWINDING_8x:
2493       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == -8;
2494       break;
2495     case PLAYER_REWINDING_16x:
2496       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == -16;
2497       break;
2498     case PLAYER_REWINDING_32x:
2499       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == -32;
2500       break;
2501     case PLAYER_FORWARDING_2x:
2502       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == 2;
2503       break;
2504     case PLAYER_FORWARDING_4x:
2505       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == 4;
2506       break;
2507     case PLAYER_FORWARDING_8x:
2508       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == 8;
2509       break;
2510     case PLAYER_FORWARDING_16x:
2511       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == 16;
2512       break;
2513     case PLAYER_FORWARDING_32x:
2514       bReturn = !g_application.m_pPlayer->IsPausedPlayback() && g_application.m_pPlayer->GetPlaySpeed() == 32;
2515       break;
2516     case PLAYER_CAN_RECORD:
2517       bReturn = g_application.m_pPlayer->CanRecord();
2518       break;
2519     case PLAYER_CAN_PAUSE:
2520       bReturn = g_application.m_pPlayer->CanPause();
2521       break;
2522     case PLAYER_CAN_SEEK:
2523       bReturn = g_application.m_pPlayer->CanSeek();
2524       break;
2525     case PLAYER_RECORDING:
2526       bReturn = g_application.m_pPlayer->IsRecording();
2527     break;
2528     case PLAYER_DISPLAY_AFTER_SEEK:
2529       bReturn = GetDisplayAfterSeek();
2530     break;
2531     case PLAYER_CACHING:
2532       bReturn = g_application.m_pPlayer->IsCaching();
2533     break;
2534     case PLAYER_SEEKBAR:
2535       {
2536         CGUIDialog *seekBar = (CGUIDialog*)g_windowManager.GetWindow(WINDOW_DIALOG_SEEK_BAR);
2537         bReturn = seekBar ? seekBar->IsDialogRunning() : false;
2538       }
2539     break;
2540     case PLAYER_SEEKING:
2541       bReturn = m_playerSeeking;
2542     break;
2543     case PLAYER_SHOWTIME:
2544       bReturn = m_playerShowTime;
2545     break;
2546     case PLAYER_PASSTHROUGH:
2547       bReturn = g_application.m_pPlayer->IsPassthrough();
2548       break;
2549     case PLAYER_ISINTERNETSTREAM:
2550       bReturn = m_currentFile && URIUtils::IsInternetStream(m_currentFile->GetPath());
2551       break;
2552     case MUSICPM_ENABLED:
2553       bReturn = g_partyModeManager.IsEnabled();
2554     break;
2555     case MUSICPLAYER_HASPREVIOUS:
2556       {
2557         // requires current playlist be PLAYLIST_MUSIC
2558         bReturn = false;
2559         if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_MUSIC)
2560           bReturn = (g_playlistPlayer.GetCurrentSong() > 0); // not first song
2561       }
2562       break;
2563     case MUSICPLAYER_HASNEXT:
2564       {
2565         // requires current playlist be PLAYLIST_MUSIC
2566         bReturn = false;
2567         if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_MUSIC)
2568           bReturn = (g_playlistPlayer.GetCurrentSong() < (g_playlistPlayer.GetPlaylist(PLAYLIST_MUSIC).size() - 1)); // not last song
2569       }
2570       break;
2571     case MUSICPLAYER_PLAYLISTPLAYING:
2572       {
2573         bReturn = false;
2574         if (g_application.m_pPlayer->IsPlayingAudio() && g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_MUSIC)
2575           bReturn = true;
2576       }
2577       break;
2578     case VIDEOPLAYER_USING_OVERLAYS:
2579       bReturn = (CSettings::Get().GetInt("videoplayer.rendermethod") == RENDER_OVERLAYS);
2580     break;
2581     case VIDEOPLAYER_ISFULLSCREEN:
2582       bReturn = g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO;
2583     break;
2584     case VIDEOPLAYER_HASMENU:
2585       bReturn = g_application.m_pPlayer->HasMenu();
2586     break;
2587     case PLAYLIST_ISRANDOM:
2588       bReturn = g_playlistPlayer.IsShuffled(g_playlistPlayer.GetCurrentPlaylist());
2589     break;
2590     case PLAYLIST_ISREPEAT:
2591       bReturn = g_playlistPlayer.GetRepeat(g_playlistPlayer.GetCurrentPlaylist()) == PLAYLIST::REPEAT_ALL;
2592     break;
2593     case PLAYLIST_ISREPEATONE:
2594       bReturn = g_playlistPlayer.GetRepeat(g_playlistPlayer.GetCurrentPlaylist()) == PLAYLIST::REPEAT_ONE;
2595     break;
2596     case PLAYER_HASDURATION:
2597       bReturn = g_application.GetTotalTime() > 0;
2598       break;
2599     case VIDEOPLAYER_HASTELETEXT:
2600       if (g_application.m_pPlayer->GetTeletextCache())
2601         bReturn = true;
2602       break;
2603     case VIDEOPLAYER_HASSUBTITLES:
2604       bReturn = g_application.m_pPlayer->GetSubtitleCount() > 0;
2605       break;
2606     case VIDEOPLAYER_SUBTITLESENABLED:
2607       bReturn = g_application.m_pPlayer->GetSubtitleVisible();
2608       break;
2609     case VISUALISATION_LOCKED:
2610       {
2611         CGUIMessage msg(GUI_MSG_GET_VISUALISATION, 0, 0);
2612         g_windowManager.SendMessage(msg);
2613         if (msg.GetPointer())
2614         {
2615           CVisualisation *pVis = (CVisualisation *)msg.GetPointer();
2616           bReturn = pVis->IsLocked();
2617         }
2618       }
2619     break;
2620     case VISUALISATION_ENABLED:
2621       bReturn = !CSettings::Get().GetString("musicplayer.visualisation").empty();
2622     break;
2623     case VIDEOPLAYER_HAS_EPG:
2624       if (m_currentFile->HasPVRChannelInfoTag())
2625       {
2626         CEpgInfoTag epgTag;
2627         bReturn = m_currentFile->GetPVRChannelInfoTag()->GetEPGNow(epgTag);
2628       }
2629     break;
2630     case VIDEOPLAYER_IS_STEREOSCOPIC:
2631       if(g_application.m_pPlayer->IsPlaying())
2632       {
2633         UpdateAVInfo();
2634         bReturn = !m_videoInfo.stereoMode.empty();
2635       }
2636       break;
2637     default: // default, use integer value different from 0 as true
2638       {
2639         int val;
2640         bReturn = GetInt(val, condition) && val != 0;
2641       }
2642     }
2643   }
2644   if (condition1 < 0)
2645     bReturn = !bReturn;
2646   return bReturn;
2647 }
2648
2649 /// \brief Examines the multi information sent and returns true or false accordingly.
2650 bool CGUIInfoManager::GetMultiInfoBool(const GUIInfo &info, int contextWindow, const CGUIListItem *item)
2651 {
2652   bool bReturn = false;
2653   int condition = abs(info.m_info);
2654
2655   if (condition >= LISTITEM_START && condition <= LISTITEM_END)
2656   {
2657     if (!item)
2658     {
2659       CGUIWindow *window = NULL;
2660       int data1 = info.GetData1();
2661       if (!data1) // No container specified, so we lookup the current view container
2662       {
2663         window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_HAS_LIST_ITEMS);
2664         if (window && window->IsMediaWindow())
2665           data1 = ((CGUIMediaWindow*)(window))->GetViewContainerID();
2666       }
2667
2668       if (!window) // If we don't have a window already (from lookup above), get one
2669         window = GetWindowWithCondition(contextWindow, 0);
2670
2671       if (window)
2672       {
2673         const CGUIControl *control = window->GetControl(data1);
2674         if (control && control->IsContainer())
2675           item = ((IGUIContainer *)control)->GetListItem(info.GetData2(), info.GetInfoFlag()).get();
2676       }
2677     }
2678     if (item) // If we got a valid item, do the lookup
2679       bReturn = GetItemBool(item, condition); // Image prioritizes images over labels (in the case of music item ratings for instance)
2680   }
2681   else
2682   {
2683     switch (condition)
2684     {
2685       case SKIN_BOOL:
2686         {
2687           bReturn = CSkinSettings::Get().GetBool(info.GetData1());
2688         }
2689         break;
2690       case SKIN_STRING:
2691         {
2692           if (info.GetData2())
2693             bReturn = StringUtils::EqualsNoCase(CSkinSettings::Get().GetString(info.GetData1()), m_stringParameters[info.GetData2()]);
2694           else
2695             bReturn = !CSkinSettings::Get().GetString(info.GetData1()).empty();
2696         }
2697         break;
2698       case SKIN_HAS_THEME:
2699         {
2700           CStdString theme = CSettings::Get().GetString("lookandfeel.skintheme");
2701           StringUtils::ToLower(theme);
2702           URIUtils::RemoveExtension(theme);
2703           bReturn = theme.Equals(m_stringParameters[info.GetData1()]);
2704         }
2705         break;
2706       case STRING_IS_EMPTY:
2707         // note: Get*Image() falls back to Get*Label(), so this should cover all of them
2708         if (item && item->IsFileItem() && info.GetData1() >= LISTITEM_START && info.GetData1() < LISTITEM_END)
2709           bReturn = GetItemImage((const CFileItem *)item, info.GetData1()).empty();
2710         else
2711           bReturn = GetImage(info.GetData1(), contextWindow).empty();
2712         break;
2713       case STRING_COMPARE:
2714         {
2715           CStdString compare;
2716           if (info.GetData2() < 0) // info labels are stored with negative numbers
2717           {
2718             int info2 = -info.GetData2();
2719             if (item && item->IsFileItem() && info2 >= LISTITEM_START && info2 < LISTITEM_END)
2720               compare = GetItemImage((const CFileItem *)item, info2);
2721             else
2722               compare = GetImage(info2, contextWindow);
2723           }
2724           else if (info.GetData2() < (int)m_stringParameters.size())
2725           { // conditional string
2726             compare = m_stringParameters[info.GetData2()];
2727           }
2728           if (item && item->IsFileItem() && info.GetData1() >= LISTITEM_START && info.GetData1() < LISTITEM_END)
2729             bReturn = GetItemImage((const CFileItem *)item, info.GetData1()).Equals(compare);
2730           else
2731             bReturn = GetImage(info.GetData1(), contextWindow).Equals(compare);
2732         }
2733         break;
2734       case INTEGER_GREATER_THAN:
2735         {
2736           int integer;
2737           if (GetInt(integer, info.GetData1(), contextWindow, item))
2738             bReturn = integer > info.GetData2();
2739           else
2740           {
2741             CStdString value;
2742
2743             if (item && item->IsFileItem() && info.GetData1() >= LISTITEM_START && info.GetData1() < LISTITEM_END)
2744               value = GetItemImage((const CFileItem *)item, info.GetData1());
2745             else
2746               value = GetImage(info.GetData1(), contextWindow);
2747
2748             // Handle the case when a value contains time separator (:). This makes IntegerGreaterThan
2749             // useful for Player.Time* members without adding a separate set of members returning time in seconds
2750             if ( value.find_first_of( ':' ) != value.npos )
2751               bReturn = StringUtils::TimeStringToSeconds( value ) > info.GetData2();
2752             else
2753               bReturn = atoi( value.c_str() ) > info.GetData2();
2754           }
2755         }
2756         break;
2757       case STRING_STR:
2758       case STRING_STR_LEFT:
2759       case STRING_STR_RIGHT:
2760         {
2761           CStdString compare = m_stringParameters[info.GetData2()];
2762           // our compare string is already in lowercase, so lower case our label as well
2763           // as CStdString::Find() is case sensitive
2764           CStdString label;
2765           if (item && item->IsFileItem() && info.GetData1() >= LISTITEM_START && info.GetData1() < LISTITEM_END)
2766           {
2767             label = GetItemImage((const CFileItem *)item, info.GetData1());
2768             StringUtils::ToLower(label);
2769           }
2770           else
2771           {
2772             label = GetImage(info.GetData1(), contextWindow);
2773             StringUtils::ToLower(label);
2774           }
2775           if (condition == STRING_STR_LEFT)
2776             bReturn = StringUtils::StartsWith(label, compare);
2777           else if (condition == STRING_STR_RIGHT)
2778             bReturn = StringUtils::EndsWith(label, compare);
2779           else
2780             bReturn = label.find(compare) != std::string::npos;
2781         }
2782         break;
2783       case SYSTEM_ALARM_LESS_OR_EQUAL:
2784         {
2785           int time = lrint(g_alarmClock.GetRemaining(m_stringParameters[info.GetData1()]));
2786           int timeCompare = atoi(m_stringParameters[info.GetData2()]);
2787           if (time > 0)
2788             bReturn = timeCompare >= time;
2789           else
2790             bReturn = false;
2791         }
2792         break;
2793       case SYSTEM_IDLE_TIME:
2794         bReturn = g_application.GlobalIdleTime() >= (int)info.GetData1();
2795         break;
2796       case CONTROL_GROUP_HAS_FOCUS:
2797         {
2798           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2799           if (window)
2800             bReturn = window->ControlGroupHasFocus(info.GetData1(), info.GetData2());
2801         }
2802         break;
2803       case CONTROL_IS_VISIBLE:
2804         {
2805           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2806           if (window)
2807           {
2808             // Note: This'll only work for unique id's
2809             const CGUIControl *control = window->GetControl(info.GetData1());
2810             if (control)
2811               bReturn = control->IsVisible();
2812           }
2813         }
2814         break;
2815       case CONTROL_IS_ENABLED:
2816         {
2817           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2818           if (window)
2819           {
2820             // Note: This'll only work for unique id's
2821             const CGUIControl *control = window->GetControl(info.GetData1());
2822             if (control)
2823               bReturn = !control->IsDisabled();
2824           }
2825         }
2826         break;
2827       case CONTROL_HAS_FOCUS:
2828         {
2829           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2830           if (window)
2831             bReturn = (window->GetFocusedControlID() == (int)info.GetData1());
2832         }
2833         break;
2834       case WINDOW_NEXT:
2835         if (info.GetData1())
2836           bReturn = ((int)info.GetData1() == m_nextWindowID);
2837         else
2838         {
2839           CGUIWindow *window = g_windowManager.GetWindow(m_nextWindowID);
2840           if (window && URIUtils::GetFileName(window->GetProperty("xmlfile").asString()).Equals(m_stringParameters[info.GetData2()]))
2841             bReturn = true;
2842         }
2843         break;
2844       case WINDOW_PREVIOUS:
2845         if (info.GetData1())
2846           bReturn = ((int)info.GetData1() == m_prevWindowID);
2847         else
2848         {
2849           CGUIWindow *window = g_windowManager.GetWindow(m_prevWindowID);
2850           if (window && URIUtils::GetFileName(window->GetProperty("xmlfile").asString()).Equals(m_stringParameters[info.GetData2()]))
2851             bReturn = true;
2852         }
2853         break;
2854       case WINDOW_IS_VISIBLE:
2855         if (info.GetData1())
2856           bReturn = g_windowManager.IsWindowVisible(info.GetData1());
2857         else
2858           bReturn = g_windowManager.IsWindowVisible(m_stringParameters[info.GetData2()]);
2859         break;
2860       case WINDOW_IS_TOPMOST:
2861         if (info.GetData1())
2862           bReturn = g_windowManager.IsWindowTopMost(info.GetData1());
2863         else
2864           bReturn = g_windowManager.IsWindowTopMost(m_stringParameters[info.GetData2()]);
2865         break;
2866       case WINDOW_IS_ACTIVE:
2867         if (info.GetData1())
2868           bReturn = g_windowManager.IsWindowActive(info.GetData1());
2869         else
2870           bReturn = g_windowManager.IsWindowActive(m_stringParameters[info.GetData2()]);
2871         break;
2872       case SYSTEM_HAS_ALARM:
2873         bReturn = g_alarmClock.HasAlarm(m_stringParameters[info.GetData1()]);
2874         break;
2875       case SYSTEM_GET_BOOL:
2876         bReturn = CSettings::Get().GetBool(m_stringParameters[info.GetData1()]);
2877         break;
2878       case SYSTEM_HAS_CORE_ID:
2879         bReturn = g_cpuInfo.HasCoreId(info.GetData1());
2880         break;
2881       case SYSTEM_SETTING:
2882         {
2883           if ( m_stringParameters[info.GetData1()].Equals("hidewatched") )
2884           {
2885             CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2886             if (window)
2887               bReturn = CMediaSettings::Get().GetWatchedMode(((CGUIMediaWindow *)window)->CurrentDirectory().GetContent()) == WatchedModeUnwatched;
2888           }
2889         }
2890         break;
2891       case SYSTEM_HAS_ADDON:
2892       {
2893         AddonPtr addon;
2894         bReturn = CAddonMgr::Get().GetAddon(m_stringParameters[info.GetData1()],addon) && addon;
2895         break;
2896       }
2897       case CONTAINER_SCROLL_PREVIOUS:
2898       case CONTAINER_MOVE_PREVIOUS:
2899       case CONTAINER_MOVE_NEXT:
2900       case CONTAINER_SCROLL_NEXT:
2901         {
2902           map<int,int>::const_iterator it = m_containerMoves.find(info.GetData1());
2903           if (it != m_containerMoves.end())
2904           {
2905             if (condition > CONTAINER_STATIC) // moving up
2906               bReturn = it->second >= std::max(condition - CONTAINER_STATIC, 1);
2907             else
2908               bReturn = it->second <= std::min(condition - CONTAINER_STATIC, -1);
2909           }
2910         }
2911         break;
2912       case CONTAINER_CONTENT:
2913         {
2914           CStdString content;
2915           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2916           if (window)
2917           {
2918             if (window->GetID() == WINDOW_DIALOG_MUSIC_INFO)
2919               content = ((CGUIDialogMusicInfo *)window)->CurrentDirectory().GetContent();
2920             else if (window->GetID() == WINDOW_DIALOG_VIDEO_INFO)
2921               content = ((CGUIDialogVideoInfo *)window)->CurrentDirectory().GetContent();
2922           }
2923           if (content.empty())
2924           {
2925             window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2926             if (window)
2927               content = ((CGUIMediaWindow *)window)->CurrentDirectory().GetContent();
2928           }
2929           bReturn = m_stringParameters[info.GetData2()].Equals(content);
2930         }
2931         break;
2932       case CONTAINER_ROW:
2933       case CONTAINER_COLUMN:
2934       case CONTAINER_POSITION:
2935       case CONTAINER_HAS_NEXT:
2936       case CONTAINER_HAS_PREVIOUS:
2937       case CONTAINER_SCROLLING:
2938       case CONTAINER_SUBITEM:
2939         {
2940           const CGUIControl *control = NULL;
2941           if (info.GetData1())
2942           { // container specified
2943             CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2944             if (window)
2945               control = window->GetControl(info.GetData1());
2946           }
2947           else
2948           { // no container specified - assume a mediawindow
2949             CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2950             if (window)
2951               control = window->GetControl(window->GetViewContainerID());
2952           }
2953           if (control)
2954             bReturn = control->GetCondition(condition, info.GetData2());
2955         }
2956         break;
2957       case CONTAINER_HAS_FOCUS:
2958         { // grab our container
2959           CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
2960           if (window)
2961           {
2962             const CGUIControl *control = window->GetControl(info.GetData1());
2963             if (control && control->IsContainer())
2964             {
2965               CFileItemPtr item = boost::static_pointer_cast<CFileItem>(((IGUIContainer *)control)->GetListItem(0));
2966               if (item && item->m_iprogramCount == info.GetData2())  // programcount used to store item id
2967                 bReturn = true;
2968             }
2969           }
2970           break;
2971         }
2972       case VIDEOPLAYER_CONTENT:
2973         {
2974           CStdString strContent="files";
2975           if (m_currentFile->HasVideoInfoTag() && m_currentFile->GetVideoInfoTag()->m_type == "movie")
2976             strContent = "movies";
2977           if (m_currentFile->HasVideoInfoTag() && m_currentFile->GetVideoInfoTag()->m_iSeason > -1) // episode
2978             strContent = "episodes";
2979           if (m_currentFile->HasVideoInfoTag() && !m_currentFile->GetVideoInfoTag()->m_artist.empty())
2980             strContent = "musicvideos";
2981           if (m_currentFile->HasVideoInfoTag() && m_currentFile->GetVideoInfoTag()->m_strStatus == "livetv")
2982             strContent = "livetv";
2983           if (m_currentFile->HasPVRChannelInfoTag())
2984             strContent = "livetv";
2985           bReturn = m_stringParameters[info.GetData1()].Equals(strContent);
2986         }
2987         break;
2988       case CONTAINER_SORT_METHOD:
2989       {
2990         CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
2991         if (window)
2992         {
2993           const CGUIViewState *viewState = ((CGUIMediaWindow*)window)->GetViewState();
2994           if (viewState)
2995             bReturn = ((unsigned int)viewState->GetSortMethod().sortBy == info.GetData1());
2996         }
2997         break;
2998       }
2999       case CONTAINER_SORT_DIRECTION:
3000       {
3001         CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
3002         if (window)
3003         {
3004           const CGUIViewState *viewState = ((CGUIMediaWindow*)window)->GetViewState();
3005           if (viewState)
3006             bReturn = ((unsigned int)viewState->GetDisplaySortOrder() == info.GetData1());
3007         }
3008         break;
3009       }
3010       case SYSTEM_DATE:
3011         {
3012           if (info.GetData2() == -1) // info doesn't contain valid startDate
3013             return false;
3014           CDateTime date = CDateTime::GetCurrentDateTime();
3015           int currentDate = date.GetMonth()*100+date.GetDay();
3016           int startDate = info.GetData1();
3017           int stopDate = info.GetData2();
3018
3019           if (stopDate < startDate)
3020             bReturn = currentDate >= startDate || currentDate < stopDate;
3021           else
3022             bReturn = currentDate >= startDate && currentDate < stopDate;
3023         }
3024         break;
3025       case SYSTEM_TIME:
3026         {
3027           CDateTime time=CDateTime::GetCurrentDateTime();
3028           int currentTime = time.GetMinuteOfDay();
3029           int startTime = info.GetData1();
3030           int stopTime = info.GetData2();
3031
3032           if (stopTime < startTime)
3033             bReturn = currentTime >= startTime || currentTime < stopTime;
3034           else
3035             bReturn = currentTime >= startTime && currentTime < stopTime;
3036         }
3037         break;
3038       case MUSICPLAYER_EXISTS:
3039         {
3040           int index = info.GetData2();
3041           if (info.GetData1() == 1)
3042           { // relative index
3043             if (g_playlistPlayer.GetCurrentPlaylist() != PLAYLIST_MUSIC)
3044             {
3045               bReturn = false;
3046               break;
3047             }
3048             index += g_playlistPlayer.GetCurrentSong();
3049           }
3050           bReturn = (index >= 0 && index < g_playlistPlayer.GetPlaylist(PLAYLIST_MUSIC).size());
3051         }
3052         break;
3053
3054       case PLAYLIST_ISRANDOM:
3055         {
3056           int playlistid = info.GetData1();
3057           if (playlistid > PLAYLIST_NONE)
3058             bReturn = g_playlistPlayer.IsShuffled(playlistid);
3059         }
3060         break;
3061
3062       case PLAYLIST_ISREPEAT:
3063         {
3064           int playlistid = info.GetData1();
3065           if (playlistid > PLAYLIST_NONE)
3066             bReturn = g_playlistPlayer.GetRepeat(playlistid) == PLAYLIST::REPEAT_ALL;
3067         }
3068         break;
3069
3070       case PLAYLIST_ISREPEATONE:
3071         {
3072           int playlistid = info.GetData1();
3073           if (playlistid > PLAYLIST_NONE)
3074             bReturn = g_playlistPlayer.GetRepeat(playlistid) == PLAYLIST::REPEAT_ONE;
3075         }
3076         break;
3077     }
3078   }
3079   return (info.m_info < 0) ? !bReturn : bReturn;
3080 }
3081
3082 bool CGUIInfoManager::GetMultiInfoInt(int &value, const GUIInfo &info, int contextWindow) const
3083 {
3084   if (info.m_info >= LISTITEM_START && info.m_info <= LISTITEM_END)
3085   {
3086     CFileItemPtr item;
3087     CGUIWindow *window = NULL;
3088
3089     int data1 = info.GetData1();
3090     if (!data1) // No container specified, so we lookup the current view container
3091     {
3092       window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_HAS_LIST_ITEMS);
3093       if (window && window->IsMediaWindow())
3094         data1 = ((CGUIMediaWindow*)(window))->GetViewContainerID();
3095     }
3096
3097     if (!window) // If we don't have a window already (from lookup above), get one
3098       window = GetWindowWithCondition(contextWindow, 0);
3099
3100     if (window)
3101     {
3102       const CGUIControl *control = window->GetControl(data1);
3103       if (control && control->IsContainer())
3104         item = boost::static_pointer_cast<CFileItem>(((IGUIContainer *)control)->GetListItem(info.GetData2(), info.GetInfoFlag()));
3105     }
3106
3107     if (item) // If we got a valid item, do the lookup
3108       return GetItemInt(value, item.get(), info.m_info);
3109   }
3110
3111   return 0;
3112 }
3113
3114 /// \brief Examines the multi information sent and returns the string as appropriate
3115 CStdString CGUIInfoManager::GetMultiInfoLabel(const GUIInfo &info, int contextWindow, CStdString *fallback)
3116 {
3117   if (info.m_info == SKIN_STRING)
3118   {
3119     return CSkinSettings::Get().GetString(info.GetData1());
3120   }
3121   else if (info.m_info == SKIN_BOOL)
3122   {
3123     bool bInfo = CSkinSettings::Get().GetBool(info.GetData1());
3124     if (bInfo)
3125       return g_localizeStrings.Get(20122);
3126   }
3127   if (info.m_info >= LISTITEM_START && info.m_info <= LISTITEM_END)
3128   {
3129     CFileItemPtr item;
3130     CGUIWindow *window = NULL;
3131
3132     int data1 = info.GetData1();
3133     if (!data1) // No container specified, so we lookup the current view container
3134     {
3135       window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_HAS_LIST_ITEMS);
3136       if (window && window->IsMediaWindow())
3137         data1 = ((CGUIMediaWindow*)(window))->GetViewContainerID();
3138     }
3139
3140     if (!window) // If we don't have a window already (from lookup above), get one
3141       window = GetWindowWithCondition(contextWindow, 0);
3142
3143     if (window)
3144     {
3145       const CGUIControl *control = window->GetControl(data1);
3146       if (control && control->IsContainer())
3147         item = boost::static_pointer_cast<CFileItem>(((IGUIContainer *)control)->GetListItem(info.GetData2(), info.GetInfoFlag()));
3148     }
3149
3150     if (item) // If we got a valid item, do the lookup
3151       return GetItemImage(item.get(), info.m_info, fallback); // Image prioritizes images over labels (in the case of music item ratings for instance)
3152   }
3153   else if (info.m_info == PLAYER_TIME)
3154   {
3155     return GetCurrentPlayTime((TIME_FORMAT)info.GetData1());
3156   }
3157   else if (info.m_info == PLAYER_TIME_REMAINING)
3158   {
3159     return GetCurrentPlayTimeRemaining((TIME_FORMAT)info.GetData1());
3160   }
3161   else if (info.m_info == PLAYER_FINISH_TIME)
3162   {
3163     CDateTime time;
3164     CEpgInfoTag currentTag;
3165     if (GetEpgInfoTag(currentTag))
3166       time = currentTag.EndAsLocalTime();
3167     else
3168     {
3169       time = CDateTime::GetCurrentDateTime();
3170       time += CDateTimeSpan(0, 0, 0, GetPlayTimeRemaining());
3171     }
3172     return LocalizeTime(time, (TIME_FORMAT)info.GetData1());
3173   }
3174   else if (info.m_info == PLAYER_START_TIME)
3175   {
3176     CDateTime time;
3177     CEpgInfoTag currentTag;
3178     if (GetEpgInfoTag(currentTag))
3179       time = currentTag.StartAsLocalTime();
3180     else
3181     {
3182       time = CDateTime::GetCurrentDateTime();
3183       time -= CDateTimeSpan(0, 0, 0, (int)GetPlayTime());
3184     }
3185     return LocalizeTime(time, (TIME_FORMAT)info.GetData1());
3186   }
3187   else if (info.m_info == PLAYER_TIME_SPEED)
3188   {
3189     CStdString strTime;
3190     if (g_application.m_pPlayer->GetPlaySpeed() != 1)
3191       strTime = StringUtils::Format("%s (%ix)", GetCurrentPlayTime((TIME_FORMAT)info.GetData1()).c_str(), g_application.m_pPlayer->GetPlaySpeed());
3192     else
3193       strTime = GetCurrentPlayTime();
3194     return strTime;
3195   }
3196   else if (info.m_info == PLAYER_DURATION)
3197   {
3198     return GetDuration((TIME_FORMAT)info.GetData1());
3199   }
3200   else if (info.m_info == PLAYER_SEEKTIME)
3201   {
3202     return GetCurrentSeekTime((TIME_FORMAT)info.GetData1());
3203   }
3204   else if (info.m_info == PLAYER_SEEKOFFSET)
3205   {
3206     CStdString seekOffset = StringUtils::SecondsToTimeString(abs(m_seekOffset), (TIME_FORMAT)info.GetData1());
3207     if (m_seekOffset < 0)
3208       return "-" + seekOffset;
3209     if (m_seekOffset > 0)
3210       return "+" + seekOffset;
3211   }
3212   else if (info.m_info == PLAYER_ITEM_ART)
3213   {
3214     return m_currentFile->GetArt(m_stringParameters[info.GetData1()]);
3215   }
3216   else if (info.m_info == SYSTEM_TIME)
3217   {
3218     return GetTime((TIME_FORMAT)info.GetData1());
3219   }
3220   else if (info.m_info == SYSTEM_DATE)
3221   {
3222     CDateTime time=CDateTime::GetCurrentDateTime();
3223     return time.GetAsLocalizedDate(m_stringParameters[info.GetData1()],false);
3224   }
3225   else if (info.m_info == CONTAINER_NUM_PAGES || info.m_info == CONTAINER_CURRENT_PAGE ||
3226            info.m_info == CONTAINER_NUM_ITEMS || info.m_info == CONTAINER_POSITION)
3227   {
3228     const CGUIControl *control = NULL;
3229     if (info.GetData1())
3230     { // container specified
3231       CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
3232       if (window)
3233         control = window->GetControl(info.GetData1());
3234     }
3235     else
3236     { // no container specified - assume a mediawindow
3237       CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
3238       if (window)
3239         control = window->GetControl(window->GetViewContainerID());
3240     }
3241     if (control)
3242     {
3243       if (control->IsContainer())
3244         return ((IGUIContainer *)control)->GetLabel(info.m_info);
3245       else if (control->GetControlType() == CGUIControl::GUICONTROL_TEXTBOX)
3246         return ((CGUITextBox *)control)->GetLabel(info.m_info);
3247     }
3248   }
3249   else if (info.m_info == SYSTEM_GET_CORE_USAGE)
3250   {
3251     CStdString strCpu = StringUtils::Format("%4.2f", g_cpuInfo.GetCoreInfo(atoi(m_stringParameters[info.GetData1()].c_str())).m_fPct);
3252     return strCpu;
3253   }
3254   else if (info.m_info >= MUSICPLAYER_TITLE && info.m_info <= MUSICPLAYER_ALBUM_ARTIST)
3255     return GetMusicPlaylistInfo(info);
3256   else if (info.m_info == CONTAINER_PROPERTY)
3257   {
3258     CGUIWindow *window = NULL;
3259     if (info.GetData1())
3260     { // container specified
3261       window = GetWindowWithCondition(contextWindow, 0);
3262     }
3263     else
3264     { // no container specified - assume a mediawindow
3265       window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
3266     }
3267     if (window)
3268       return ((CGUIMediaWindow *)window)->CurrentDirectory().GetProperty(m_stringParameters[info.GetData2()]).asString();
3269   }
3270   else if (info.m_info == CONTROL_GET_LABEL)
3271   {
3272     CGUIWindow *window = GetWindowWithCondition(contextWindow, 0);
3273     if (window)
3274     {
3275       const CGUIControl *control = window->GetControl(info.GetData1());
3276       if (control)
3277         return control->GetDescription();
3278     }
3279   }
3280   else if (info.m_info == WINDOW_PROPERTY)
3281   {
3282     CGUIWindow *window = NULL;
3283     if (info.GetData1())
3284     { // window specified
3285       window = g_windowManager.GetWindow(info.GetData1());//GetWindowWithCondition(contextWindow, 0);
3286     }
3287     else
3288     { // no window specified - assume active
3289       window = GetWindowWithCondition(contextWindow, 0);
3290     }
3291
3292     if (window)
3293       return window->GetProperty(m_stringParameters[info.GetData2()]).asString();
3294   }
3295   else if (info.m_info == SYSTEM_ADDON_TITLE ||
3296            info.m_info == SYSTEM_ADDON_ICON ||
3297            info.m_info == SYSTEM_ADDON_VERSION)
3298   {
3299     // This logic does not check/care whether an addon has been disabled/marked as broken,
3300     // it simply retrieves it's name or icon that means if an addon is placed on the home screen it
3301     // will stay there even if it's disabled/marked as broken. This might need to be changed/fixed
3302     // in the future.
3303     AddonPtr addon;
3304     if (info.GetData2() == 0)
3305       CAddonMgr::Get().GetAddon(const_cast<CGUIInfoManager*>(this)->GetLabel(info.GetData1(), contextWindow),addon,ADDON_UNKNOWN,false);
3306     else
3307       CAddonMgr::Get().GetAddon(m_stringParameters[info.GetData1()],addon,ADDON_UNKNOWN,false);
3308     if (addon && info.m_info == SYSTEM_ADDON_TITLE)
3309       return addon->Name();
3310     if (addon && info.m_info == SYSTEM_ADDON_ICON)
3311       return addon->Icon();
3312     if (addon && info.m_info == SYSTEM_ADDON_VERSION)
3313       return addon->Version().c_str();
3314   }
3315   else if (info.m_info == PLAYLIST_LENGTH ||
3316            info.m_info == PLAYLIST_POSITION ||
3317            info.m_info == PLAYLIST_RANDOM ||
3318            info.m_info == PLAYLIST_REPEAT)
3319   {
3320     int playlistid = info.GetData1();
3321     if (playlistid > PLAYLIST_NONE)
3322       return GetPlaylistLabel(info.m_info, playlistid);
3323   }
3324
3325   return StringUtils::EmptyString;
3326 }
3327
3328 /// \brief Obtains the filename of the image to show from whichever subsystem is needed
3329 CStdString CGUIInfoManager::GetImage(int info, int contextWindow, CStdString *fallback)
3330 {
3331   if (info >= CONDITIONAL_LABEL_START && info <= CONDITIONAL_LABEL_END)
3332     return GetSkinVariableString(info, true);
3333
3334   if (info >= MULTI_INFO_START && info <= MULTI_INFO_END)
3335   {
3336     return GetMultiInfoLabel(m_multiInfo[info - MULTI_INFO_START], contextWindow, fallback);
3337   }
3338   else if (info == WEATHER_CONDITIONS)
3339     return g_weatherManager.GetInfo(WEATHER_IMAGE_CURRENT_ICON);
3340   else if (info == SYSTEM_PROFILETHUMB)
3341   {
3342     CStdString thumb = CProfilesManager::Get().GetCurrentProfile().getThumb();
3343     if (thumb.empty())
3344       thumb = "unknown-user.png";
3345     return thumb;
3346   }
3347   else if (info == MUSICPLAYER_COVER)
3348   {
3349     if (!g_application.m_pPlayer->IsPlayingAudio()) return "";
3350     if (fallback)
3351       *fallback = "DefaultAlbumCover.png";
3352     return m_currentFile->HasArt("thumb") ? m_currentFile->GetArt("thumb") : "DefaultAlbumCover.png";
3353   }
3354   else if (info == MUSICPLAYER_RATING)
3355   {
3356     if (!g_application.m_pPlayer->IsPlayingAudio()) return "";
3357     return GetItemImage(m_currentFile, LISTITEM_RATING);
3358   }
3359   else if (info == PLAYER_STAR_RATING)
3360   {
3361     if (!g_application.m_pPlayer->IsPlaying()) return "";
3362     return GetItemImage(m_currentFile, LISTITEM_STAR_RATING);
3363   }
3364   else if (info == VIDEOPLAYER_COVER)
3365   {
3366     if (!g_application.m_pPlayer->IsPlayingVideo()) return "";
3367     if (fallback)
3368       *fallback = "DefaultVideoCover.png";
3369     if(m_currentMovieThumb.empty())
3370       return m_currentFile->HasArt("thumb") ? m_currentFile->GetArt("thumb") : "DefaultVideoCover.png";
3371     else return m_currentMovieThumb;
3372   }
3373   else if (info == CONTAINER_FOLDERTHUMB)
3374   {
3375     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
3376     if (window)
3377       return GetItemImage(&const_cast<CFileItemList&>(((CGUIMediaWindow*)window)->CurrentDirectory()), LISTITEM_THUMB, fallback);
3378   }
3379   else if (info == CONTAINER_TVSHOWTHUMB)
3380   {
3381     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
3382     if (window)
3383       return ((CGUIMediaWindow *)window)->CurrentDirectory().GetArt("tvshow.thumb");
3384   }
3385   else if (info == CONTAINER_SEASONTHUMB)
3386   {
3387     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_IS_MEDIA_WINDOW);
3388     if (window)
3389       return ((CGUIMediaWindow *)window)->CurrentDirectory().GetArt("season.thumb");
3390   }
3391   else if (info == LISTITEM_THUMB || info == LISTITEM_ICON || info == LISTITEM_ACTUAL_ICON ||
3392           info == LISTITEM_OVERLAY || info == LISTITEM_RATING || info == LISTITEM_STAR_RATING)
3393   {
3394     CGUIWindow *window = GetWindowWithCondition(contextWindow, WINDOW_CONDITION_HAS_LIST_ITEMS);
3395     if (window)
3396     {
3397       CFileItemPtr item = window->GetCurrentListItem();
3398       if (item)
3399         return GetItemImage(item.get(), info, fallback);
3400     }
3401   }
3402   return GetLabel(info, contextWindow, fallback);
3403 }
3404
3405 CStdString CGUIInfoManager::GetDate(bool bNumbersOnly)
3406 {
3407   CDateTime time=CDateTime::GetCurrentDateTime();
3408   return time.GetAsLocalizedDate(!bNumbersOnly);
3409 }
3410
3411 CStdString CGUIInfoManager::GetTime(TIME_FORMAT format) const
3412 {
3413   CDateTime time=CDateTime::GetCurrentDateTime();
3414   return LocalizeTime(time, format);
3415 }
3416
3417 CStdString CGUIInfoManager::LocalizeTime(const CDateTime &time, TIME_FORMAT format) const
3418 {
3419   const CStdString timeFormat = g_langInfo.GetTimeFormat();
3420   bool use12hourclock = timeFormat.find('h') != std::string::npos;
3421   switch (format)
3422   {
3423   case TIME_FORMAT_GUESS:
3424     return time.GetAsLocalizedTime("", false);
3425   case TIME_FORMAT_SS:
3426     return time.GetAsLocalizedTime("ss", true);
3427   case TIME_FORMAT_MM:
3428     return time.GetAsLocalizedTime("mm", true);
3429   case TIME_FORMAT_MM_SS:
3430     return time.GetAsLocalizedTime("mm:ss", true);
3431   case TIME_FORMAT_HH:  // this forces it to a 12 hour clock
3432     return time.GetAsLocalizedTime(use12hourclock ? "h" : "HH", false);
3433   case TIME_FORMAT_HH_MM:
3434     return time.GetAsLocalizedTime(use12hourclock ? "h:mm" : "HH:mm", false);
3435   case TIME_FORMAT_HH_MM_XX:
3436       return time.GetAsLocalizedTime(use12hourclock ? "h:mm xx" : "HH:mm", false);
3437   case TIME_FORMAT_HH_MM_SS:
3438     return time.GetAsLocalizedTime(use12hourclock ? "hh:mm:ss" : "HH:mm:ss", true);
3439   case TIME_FORMAT_HH_MM_SS_XX:
3440     return time.GetAsLocalizedTime(use12hourclock ? "hh:mm:ss xx" : "HH:mm:ss", true);
3441   case TIME_FORMAT_H:
3442     return time.GetAsLocalizedTime("h", false);
3443   case TIME_FORMAT_H_MM_SS:
3444     return time.GetAsLocalizedTime("h:mm:ss", true);
3445   case TIME_FORMAT_H_MM_SS_XX:
3446     return time.GetAsLocalizedTime("h:mm:ss xx", true);
3447   case TIME_FORMAT_XX:
3448     return use12hourclock ? time.GetAsLocalizedTime("xx", false) : "";
3449   default:
3450     break;
3451   }
3452   return time.GetAsLocalizedTime("", false);
3453 }
3454
3455 CStdString CGUIInfoManager::GetDuration(TIME_FORMAT format) const
3456 {
3457   if (g_application.m_pPlayer->IsPlayingAudio() && m_currentFile->HasMusicInfoTag())
3458   {
3459     const CMusicInfoTag& tag = *m_currentFile->GetMusicInfoTag();
3460     if (tag.GetDuration() > 0)
3461       return StringUtils::SecondsToTimeString(tag.GetDuration(), format);
3462   }
3463   if (g_application.m_pPlayer->IsPlayingVideo() && !m_currentMovieDuration.empty())
3464     return m_currentMovieDuration;  // for tuxbox
3465   unsigned int iTotal = (unsigned int)g_application.GetTotalTime();
3466   if (iTotal > 0)
3467     return StringUtils::SecondsToTimeString(iTotal, format);
3468   return "";
3469 }
3470
3471 CStdString CGUIInfoManager::GetMusicPartyModeLabel(int item)
3472 {
3473   // get song counts
3474   if (item >= MUSICPM_SONGSPLAYED && item <= MUSICPM_RANDOMSONGSPICKED)
3475   {
3476     int iSongs = -1;
3477     switch (item)
3478     {
3479     case MUSICPM_SONGSPLAYED:
3480       {
3481         iSongs = g_partyModeManager.GetSongsPlayed();
3482         break;
3483       }
3484     case MUSICPM_MATCHINGSONGS:
3485       {
3486         iSongs = g_partyModeManager.GetMatchingSongs();
3487         break;
3488       }
3489     case MUSICPM_MATCHINGSONGSPICKED:
3490       {
3491         iSongs = g_partyModeManager.GetMatchingSongsPicked();
3492         break;
3493       }
3494     case MUSICPM_MATCHINGSONGSLEFT:
3495       {
3496         iSongs = g_partyModeManager.GetMatchingSongsLeft();
3497         break;
3498       }
3499     case MUSICPM_RELAXEDSONGSPICKED:
3500       {
3501         iSongs = g_partyModeManager.GetRelaxedSongs();
3502         break;
3503       }
3504     case MUSICPM_RANDOMSONGSPICKED:
3505       {
3506         iSongs = g_partyModeManager.GetRandomSongs();
3507         break;
3508       }
3509     }
3510     if (iSongs < 0)
3511       return "";
3512     CStdString strLabel = StringUtils::Format("%i", iSongs);
3513     return strLabel;
3514   }
3515   return "";
3516 }
3517
3518 const CStdString CGUIInfoManager::GetMusicPlaylistInfo(const GUIInfo& info)
3519 {
3520   PLAYLIST::CPlayList& playlist = g_playlistPlayer.GetPlaylist(PLAYLIST_MUSIC);
3521   if (playlist.size() < 1)
3522     return "";
3523   int index = info.GetData2();
3524   if (info.GetData1() == 1)
3525   { // relative index (requires current playlist is PLAYLIST_MUSIC)
3526     if (g_playlistPlayer.GetCurrentPlaylist() != PLAYLIST_MUSIC)
3527       return "";
3528     index = g_playlistPlayer.GetNextSong(index);
3529   }
3530   if (index < 0 || index >= playlist.size())
3531     return "";
3532   CFileItemPtr playlistItem = playlist[index];
3533   if (!playlistItem->GetMusicInfoTag()->Loaded())
3534   {
3535     playlistItem->LoadMusicTag();
3536     playlistItem->GetMusicInfoTag()->SetLoaded();
3537   }
3538   // try to set a thumbnail
3539   if (!playlistItem->HasArt("thumb"))
3540   {
3541     CMusicThumbLoader loader;
3542     loader.LoadItem(playlistItem.get());
3543     // still no thumb? then just the set the default cover
3544     if (!playlistItem->HasArt("thumb"))
3545       playlistItem->SetArt("thumb", "DefaultAlbumCover.png");
3546   }
3547   if (info.m_info == MUSICPLAYER_PLAYLISTPOS)
3548   {
3549     CStdString strPosition = StringUtils::Format("%i", index + 1);
3550     return strPosition;
3551   }
3552   else if (info.m_info == MUSICPLAYER_COVER)
3553     return playlistItem->GetArt("thumb");
3554   return GetMusicTagLabel(info.m_info, playlistItem.get());
3555 }
3556
3557 CStdString CGUIInfoManager::GetPlaylistLabel(int item, int playlistid /* = PLAYLIST_NONE */) const
3558 {
3559   if (playlistid <= PLAYLIST_NONE && !g_application.m_pPlayer->IsPlaying())
3560     return "";
3561
3562   int iPlaylist = playlistid == PLAYLIST_NONE ? g_playlistPlayer.GetCurrentPlaylist() : playlistid;
3563   switch (item)
3564   {
3565   case PLAYLIST_LENGTH:
3566     {
3567       return StringUtils::Format("%i", g_playlistPlayer.GetPlaylist(iPlaylist).size());;
3568     }
3569   case PLAYLIST_POSITION:
3570     {
3571       return StringUtils::Format("%i", g_playlistPlayer.GetCurrentSong() + 1);
3572     }
3573   case PLAYLIST_RANDOM:
3574     {
3575       if (g_playlistPlayer.IsShuffled(iPlaylist))
3576         return g_localizeStrings.Get(590); // 590: Random
3577       else
3578         return g_localizeStrings.Get(591); // 591: Off
3579     }
3580   case PLAYLIST_REPEAT:
3581     {
3582       PLAYLIST::REPEAT_STATE state = g_playlistPlayer.GetRepeat(iPlaylist);
3583       if (state == PLAYLIST::REPEAT_ONE)
3584         return g_localizeStrings.Get(592); // 592: One
3585       else if (state == PLAYLIST::REPEAT_ALL)
3586         return g_localizeStrings.Get(593); // 593: All
3587       else
3588         return g_localizeStrings.Get(594); // 594: Off
3589     }
3590   }
3591   return "";
3592 }
3593
3594 CStdString CGUIInfoManager::GetMusicLabel(int item)
3595 {
3596   if (!g_application.m_pPlayer->IsPlaying() || !m_currentFile->HasMusicInfoTag()) return "";
3597
3598   UpdateAVInfo();
3599   switch (item)
3600   {
3601   case MUSICPLAYER_PLAYLISTLEN:
3602     {
3603       if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_MUSIC)
3604         return GetPlaylistLabel(PLAYLIST_LENGTH);
3605     }
3606     break;
3607   case MUSICPLAYER_PLAYLISTPOS:
3608     {
3609       if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_MUSIC)
3610         return GetPlaylistLabel(PLAYLIST_POSITION);
3611     }
3612     break;
3613   case MUSICPLAYER_BITRATE:
3614     {
3615       CStdString strBitrate = "";
3616       if (m_audioInfo.bitrate > 0)
3617         strBitrate = StringUtils::Format("%i", MathUtils::round_int((double)m_audioInfo.bitrate / 1000.0));
3618       return strBitrate;
3619     }
3620     break;
3621   case MUSICPLAYER_CHANNELS:
3622     {
3623       CStdString strChannels = "";
3624       if (m_audioInfo.channels > 0)
3625       {
3626         strChannels = StringUtils::Format("%i", m_audioInfo.channels);
3627       }
3628       return strChannels;
3629     }
3630     break;
3631   case MUSICPLAYER_BITSPERSAMPLE:
3632     {
3633       CStdString strBitsPerSample = "";
3634       if (m_audioInfo.bitspersample > 0)
3635         strBitsPerSample = StringUtils::Format("%i", m_audioInfo.bitspersample);
3636       return strBitsPerSample;
3637     }
3638     break;
3639   case MUSICPLAYER_SAMPLERATE:
3640     {
3641       CStdString strSampleRate = "";
3642       if (m_audioInfo.samplerate > 0)
3643         strSampleRate = StringUtils::Format("%.5g", ((double)m_audioInfo.samplerate / 1000.0));
3644       return strSampleRate;
3645     }
3646     break;
3647   case MUSICPLAYER_CODEC:
3648     {
3649       return StringUtils::Format("%s", m_audioInfo.audioCodecName.c_str());
3650     }
3651     break;
3652   case MUSICPLAYER_LYRICS:
3653     return GetItemLabel(m_currentFile, AddListItemProp("lyrics"));
3654   }
3655   return GetMusicTagLabel(item, m_currentFile);
3656 }
3657
3658 CStdString CGUIInfoManager::GetMusicTagLabel(int info, const CFileItem *item)
3659 {
3660   if (!item->HasMusicInfoTag()) return "";
3661   const CMusicInfoTag &tag = *item->GetMusicInfoTag();
3662   switch (info)
3663   {
3664   case MUSICPLAYER_TITLE:
3665     if (tag.GetTitle().size()) { return tag.GetTitle(); }
3666     break;
3667   case MUSICPLAYER_ALBUM:
3668     if (tag.GetAlbum().size()) { return tag.GetAlbum(); }
3669     break;
3670   case MUSICPLAYER_ARTIST:
3671     if (tag.GetArtist().size()) { return StringUtils::Join(tag.GetArtist(), g_advancedSettings.m_musicItemSeparator); }
3672     break;
3673   case MUSICPLAYER_ALBUM_ARTIST:
3674     if (tag.GetAlbumArtist().size()) { return StringUtils::Join(tag.GetAlbumArtist(), g_advancedSettings.m_musicItemSeparator); }
3675     break;
3676   case MUSICPLAYER_YEAR:
3677     if (tag.GetYear()) { return tag.GetYearString(); }
3678     break;
3679   case MUSICPLAYER_GENRE:
3680     if (tag.GetGenre().size()) { return StringUtils::Join(tag.GetGenre(), g_advancedSettings.m_musicItemSeparator); }
3681     break;
3682   case MUSICPLAYER_LYRICS:
3683     if (tag.GetLyrics().size()) { return tag.GetLyrics(); }
3684   break;
3685   case MUSICPLAYER_TRACK_NUMBER:
3686     {
3687       CStdString strTrack;
3688       if (tag.Loaded() && tag.GetTrackNumber() > 0)
3689       {
3690         return StringUtils::Format("%02i", tag.GetTrackNumber());
3691       }
3692     }
3693     break;
3694   case MUSICPLAYER_DISC_NUMBER:
3695     return GetItemLabel(item, LISTITEM_DISC_NUMBER);
3696   case MUSICPLAYER_RATING:
3697     return GetItemLabel(item, LISTITEM_RATING);
3698   case MUSICPLAYER_COMMENT:
3699     return GetItemLabel(item, LISTITEM_COMMENT);
3700   case MUSICPLAYER_DURATION:
3701     return GetItemLabel(item, LISTITEM_DURATION);
3702   case MUSICPLAYER_CHANNEL_NAME:
3703     {
3704       CPVRChannel* channeltag = m_currentFile->GetPVRChannelInfoTag();
3705       if (channeltag)
3706         return channeltag->ChannelName();
3707     }
3708     break;
3709   case MUSICPLAYER_CHANNEL_NUMBER:
3710     {
3711       CPVRChannel* channeltag = m_currentFile->GetPVRChannelInfoTag();
3712       if (channeltag)
3713       {
3714         return StringUtils::Format("%i", channeltag->ChannelNumber());
3715       }
3716     }
3717     break;
3718   case MUSICPLAYER_CHANNEL_GROUP:
3719     {
3720       CPVRChannel* channeltag = m_currentFile->GetPVRChannelInfoTag();
3721       if (channeltag && channeltag->IsRadio())
3722         return g_PVRManager.GetPlayingGroup(true)->GroupName();
3723     }
3724     break;
3725   case MUSICPLAYER_PLAYCOUNT:
3726     return GetItemLabel(item, LISTITEM_PLAYCOUNT);
3727   case MUSICPLAYER_LASTPLAYED:
3728     return GetItemLabel(item, LISTITEM_LASTPLAYED);
3729   }
3730   return "";
3731 }
3732
3733 CStdString CGUIInfoManager::GetVideoLabel(int item)
3734 {
3735   if (!g_application.m_pPlayer->IsPlaying())
3736     return "";
3737
3738   if (item == VIDEOPLAYER_TITLE)
3739   {
3740     if(g_application.m_pPlayer->IsPlayingVideo())
3741        return GetLabel(PLAYER_TITLE);
3742   }
3743   else if (item == VIDEOPLAYER_PLAYLISTLEN)
3744   {
3745     if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_VIDEO)
3746       return GetPlaylistLabel(PLAYLIST_LENGTH);
3747   }
3748   else if (item == VIDEOPLAYER_PLAYLISTPOS)
3749   {
3750     if (g_playlistPlayer.GetCurrentPlaylist() == PLAYLIST_VIDEO)
3751       return GetPlaylistLabel(PLAYLIST_POSITION);
3752   }
3753   else if (m_currentFile->HasPVRChannelInfoTag())
3754   {
3755     CPVRChannel* tag = m_currentFile->GetPVRChannelInfoTag();
3756     CEpgInfoTag epgTag;
3757
3758     switch (item)
3759     {
3760     /* Now playing infos */
3761     case VIDEOPLAYER_ORIGINALTITLE:
3762       return tag->GetEPGNow(epgTag) ?
3763           epgTag.Title() :
3764           CSettings::Get().GetBool("epg.hidenoinfoavailable") ?
3765               StringUtils::EmptyString :
3766               g_localizeStrings.Get(19055); // no information available
3767     case VIDEOPLAYER_GENRE:
3768       return tag->GetEPGNow(epgTag) ? StringUtils::Join(epgTag.Genre(), g_advancedSettings.m_videoItemSeparator) : StringUtils::EmptyString;
3769     case VIDEOPLAYER_PLOT:
3770       return tag->GetEPGNow(epgTag) ? epgTag.Plot() : StringUtils::EmptyString;
3771     case VIDEOPLAYER_PLOT_OUTLINE:
3772       return tag->GetEPGNow(epgTag) ? epgTag.PlotOutline() : StringUtils::EmptyString;
3773     case VIDEOPLAYER_STARTTIME:
3774       return tag->GetEPGNow(epgTag) ? epgTag.StartAsLocalTime().GetAsLocalizedTime("", false) : CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
3775     case VIDEOPLAYER_ENDTIME:
3776       return tag->GetEPGNow(epgTag) ? epgTag.EndAsLocalTime().GetAsLocalizedTime("", false) : CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
3777
3778     /* Next playing infos */
3779     case VIDEOPLAYER_NEXT_TITLE:
3780       return tag->GetEPGNext(epgTag) ?
3781           epgTag.Title() :
3782           CSettings::Get().GetBool("epg.hidenoinfoavailable") ?
3783               StringUtils::EmptyString :
3784               g_localizeStrings.Get(19055); // no information available
3785     case VIDEOPLAYER_NEXT_GENRE:
3786       return tag->GetEPGNext(epgTag) ? StringUtils::Join(epgTag.Genre(), g_advancedSettings.m_videoItemSeparator) : StringUtils::EmptyString;
3787     case VIDEOPLAYER_NEXT_PLOT:
3788       return tag->GetEPGNext(epgTag) ? epgTag.Plot() : StringUtils::EmptyString;
3789     case VIDEOPLAYER_NEXT_PLOT_OUTLINE:
3790       return tag->GetEPGNext(epgTag) ? epgTag.PlotOutline() : StringUtils::EmptyString;
3791     case VIDEOPLAYER_NEXT_STARTTIME:
3792       return tag->GetEPGNext(epgTag) ? epgTag.StartAsLocalTime().GetAsLocalizedTime("", false) : CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
3793     case VIDEOPLAYER_NEXT_ENDTIME:
3794       return tag->GetEPGNext(epgTag) ? epgTag.EndAsLocalTime().GetAsLocalizedTime("", false) : CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
3795     case VIDEOPLAYER_NEXT_DURATION:
3796       {
3797         CStdString duration;
3798         if (tag->GetEPGNext(epgTag) && epgTag.GetDuration() > 0)
3799           duration = StringUtils::SecondsToTimeString(epgTag.GetDuration());
3800         return duration;
3801       }
3802
3803     case VIDEOPLAYER_PARENTAL_RATING:
3804       {
3805         CStdString rating;
3806         if (tag->GetEPGNow(epgTag) && epgTag.ParentalRating() > 0)
3807           rating = StringUtils::Format("%i", epgTag.ParentalRating());
3808         return rating;
3809       }
3810       break;
3811
3812     /* General channel infos */
3813     case VIDEOPLAYER_CHANNEL_NAME:
3814       return tag->ChannelName();
3815     case VIDEOPLAYER_CHANNEL_NUMBER:
3816       {
3817         return StringUtils::Format("%i", tag->ChannelNumber());;
3818       }
3819     case VIDEOPLAYER_CHANNEL_GROUP:
3820       {
3821         if (tag && !tag->IsRadio())
3822           return g_PVRManager.GetPlayingGroup(false)->GroupName();
3823       }
3824     }
3825   }
3826   else if (m_currentFile->HasVideoInfoTag())
3827   {
3828     switch (item)
3829     {
3830     case VIDEOPLAYER_ORIGINALTITLE:
3831       return m_currentFile->GetVideoInfoTag()->m_strOriginalTitle;
3832       break;
3833     case VIDEOPLAYER_GENRE:
3834       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_genre, g_advancedSettings.m_videoItemSeparator);
3835       break;
3836     case VIDEOPLAYER_DIRECTOR:
3837       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_director, g_advancedSettings.m_videoItemSeparator);
3838       break;
3839     case VIDEOPLAYER_RATING:
3840       {
3841         CStdString strRating;
3842         if (m_currentFile->GetVideoInfoTag()->m_fRating > 0.f)
3843           strRating = StringUtils::Format("%.1f", m_currentFile->GetVideoInfoTag()->m_fRating);
3844         return strRating;
3845       }
3846       break;
3847     case VIDEOPLAYER_RATING_AND_VOTES:
3848       {
3849         CStdString strRatingAndVotes;
3850         if (m_currentFile->GetVideoInfoTag()->m_fRating > 0.f)
3851         {
3852           if (m_currentFile->GetVideoInfoTag()->m_strVotes.empty())
3853             strRatingAndVotes = StringUtils::Format("%.1f",
3854                                                     m_currentFile->GetVideoInfoTag()->m_fRating);
3855           else
3856             strRatingAndVotes = StringUtils::Format("%.1f (%s %s)",
3857                                                     m_currentFile->GetVideoInfoTag()->m_fRating,
3858                                                     m_currentFile->GetVideoInfoTag()->m_strVotes.c_str(),
3859                                                     g_localizeStrings.Get(20350).c_str());
3860         }
3861         return strRatingAndVotes;
3862       }
3863       break;
3864     case VIDEOPLAYER_VOTES:
3865       return m_currentFile->GetVideoInfoTag()->m_strVotes;
3866     case VIDEOPLAYER_YEAR:
3867       {
3868         CStdString strYear;
3869         if (m_currentFile->GetVideoInfoTag()->m_iYear > 0)
3870           strYear = StringUtils::Format("%i", m_currentFile->GetVideoInfoTag()->m_iYear);
3871         return strYear;
3872       }
3873       break;
3874     case VIDEOPLAYER_PREMIERED:
3875       {
3876         CDateTime dateTime;
3877         if (m_currentFile->GetVideoInfoTag()->m_firstAired.IsValid())
3878           dateTime = m_currentFile->GetVideoInfoTag()->m_firstAired;
3879         else if (m_currentFile->GetVideoInfoTag()->m_premiered.IsValid())
3880           dateTime = m_currentFile->GetVideoInfoTag()->m_premiered;
3881
3882         if (dateTime.IsValid())
3883           return dateTime.GetAsLocalizedDate();
3884         break;
3885       }
3886       break;
3887     case VIDEOPLAYER_PLOT:
3888       return m_currentFile->GetVideoInfoTag()->m_strPlot;
3889     case VIDEOPLAYER_TRAILER:
3890       return m_currentFile->GetVideoInfoTag()->m_strTrailer;
3891     case VIDEOPLAYER_PLOT_OUTLINE:
3892       return m_currentFile->GetVideoInfoTag()->m_strPlotOutline;
3893     case VIDEOPLAYER_EPISODE:
3894       if (m_currentFile->GetVideoInfoTag()->m_iEpisode > 0)
3895       {
3896         CStdString strEpisode;
3897         if (m_currentFile->GetVideoInfoTag()->m_iSeason == 0) // prefix episode with 'S'
3898           strEpisode = StringUtils::Format("S%i", m_currentFile->GetVideoInfoTag()->m_iEpisode);
3899         else 
3900           strEpisode = StringUtils::Format("%i", m_currentFile->GetVideoInfoTag()->m_iEpisode);
3901         return strEpisode;
3902       }
3903       break;
3904     case VIDEOPLAYER_SEASON:
3905       if (m_currentFile->GetVideoInfoTag()->m_iSeason > 0)
3906       {
3907         return StringUtils::Format("%i", m_currentFile->GetVideoInfoTag()->m_iSeason);
3908       }
3909       break;
3910     case VIDEOPLAYER_TVSHOW:
3911       return m_currentFile->GetVideoInfoTag()->m_strShowTitle;
3912
3913     case VIDEOPLAYER_STUDIO:
3914       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_studio, g_advancedSettings.m_videoItemSeparator);
3915     case VIDEOPLAYER_COUNTRY:
3916       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_country, g_advancedSettings.m_videoItemSeparator);
3917     case VIDEOPLAYER_MPAA:
3918       return m_currentFile->GetVideoInfoTag()->m_strMPAARating;
3919     case VIDEOPLAYER_TOP250:
3920       {
3921         CStdString strTop250;
3922         if (m_currentFile->GetVideoInfoTag()->m_iTop250 > 0)
3923           strTop250 = StringUtils::Format("%i", m_currentFile->GetVideoInfoTag()->m_iTop250);
3924         return strTop250;
3925       }
3926       break;
3927     case VIDEOPLAYER_CAST:
3928       return m_currentFile->GetVideoInfoTag()->GetCast();
3929     case VIDEOPLAYER_CAST_AND_ROLE:
3930       return m_currentFile->GetVideoInfoTag()->GetCast(true);
3931     case VIDEOPLAYER_ARTIST:
3932       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator);
3933     case VIDEOPLAYER_ALBUM:
3934       return m_currentFile->GetVideoInfoTag()->m_strAlbum;
3935     case VIDEOPLAYER_WRITER:
3936       return StringUtils::Join(m_currentFile->GetVideoInfoTag()->m_writingCredits, g_advancedSettings.m_videoItemSeparator);
3937     case VIDEOPLAYER_TAGLINE:
3938       return m_currentFile->GetVideoInfoTag()->m_strTagLine;
3939     case VIDEOPLAYER_LASTPLAYED:
3940       {
3941         if (m_currentFile->GetVideoInfoTag()->m_lastPlayed.IsValid())
3942           return m_currentFile->GetVideoInfoTag()->m_lastPlayed.GetAsLocalizedDateTime();
3943         break;
3944       }
3945     case VIDEOPLAYER_PLAYCOUNT:
3946       {
3947         CStdString strPlayCount;
3948         if (m_currentFile->GetVideoInfoTag()->m_playCount > 0)
3949           strPlayCount = StringUtils::Format("%i", m_currentFile->GetVideoInfoTag()->m_playCount);
3950         return strPlayCount;
3951       }
3952     }
3953   }
3954   return "";
3955 }
3956
3957 int64_t CGUIInfoManager::GetPlayTime() const
3958 {
3959   if (g_application.m_pPlayer->IsPlaying())
3960   {
3961     int64_t lPTS = (int64_t)(g_application.GetTime() * 1000);
3962     if (lPTS < 0) lPTS = 0;
3963     return lPTS;
3964   }
3965   return 0;
3966 }
3967
3968 CStdString CGUIInfoManager::GetCurrentPlayTime(TIME_FORMAT format) const
3969 {
3970   if (format == TIME_FORMAT_GUESS && GetTotalPlayTime() >= 3600)
3971     format = TIME_FORMAT_HH_MM_SS;
3972   if (g_application.m_pPlayer->IsPlaying())
3973     return StringUtils::SecondsToTimeString((int)(GetPlayTime()/1000), format);
3974   return "";
3975 }
3976
3977 CStdString CGUIInfoManager::GetCurrentSeekTime(TIME_FORMAT format) const
3978 {
3979   if (format == TIME_FORMAT_GUESS && GetTotalPlayTime() >= 3600)
3980     format = TIME_FORMAT_HH_MM_SS;
3981   float time = GetTotalPlayTime() * g_application.GetSeekHandler()->GetPercent() * 0.01f;
3982   return StringUtils::SecondsToTimeString((int)time, format);
3983 }
3984
3985 int CGUIInfoManager::GetTotalPlayTime() const
3986 {
3987   int iTotalTime = (int)g_application.GetTotalTime();
3988   return iTotalTime > 0 ? iTotalTime : 0;
3989 }
3990
3991 int CGUIInfoManager::GetPlayTimeRemaining() const
3992 {
3993   int iReverse = GetTotalPlayTime() - (int)g_application.GetTime();
3994   return iReverse > 0 ? iReverse : 0;
3995 }
3996
3997 CStdString CGUIInfoManager::GetCurrentPlayTimeRemaining(TIME_FORMAT format) const
3998 {
3999   if (format == TIME_FORMAT_GUESS && GetTotalPlayTime() >= 3600)
4000     format = TIME_FORMAT_HH_MM_SS;
4001   int timeRemaining = GetPlayTimeRemaining();
4002   if (timeRemaining && g_application.m_pPlayer->IsPlaying())
4003     return StringUtils::SecondsToTimeString(timeRemaining, format);
4004   return "";
4005 }
4006
4007 void CGUIInfoManager::ResetCurrentItem()
4008 {
4009   m_currentFile->Reset();
4010   m_currentMovieThumb = "";
4011   m_currentMovieDuration = "";
4012 }
4013
4014 void CGUIInfoManager::SetCurrentItem(CFileItem &item)
4015 {
4016   ResetCurrentItem();
4017
4018   if (item.IsAudio())
4019     SetCurrentSong(item);
4020   else
4021     SetCurrentMovie(item);
4022
4023   if (item.HasEPGInfoTag())
4024     *m_currentFile->GetEPGInfoTag() = *item.GetEPGInfoTag();
4025   else if (item.HasPVRChannelInfoTag())
4026   {
4027     CEpgInfoTag tag;
4028     if (item.GetPVRChannelInfoTag()->GetEPGNow(tag))
4029       *m_currentFile->GetEPGInfoTag() = tag;
4030   }
4031
4032   SetChanged();
4033   NotifyObservers(ObservableMessageCurrentItem);
4034 }
4035
4036 void CGUIInfoManager::SetCurrentAlbumThumb(const CStdString &thumbFileName)
4037 {
4038   if (CFile::Exists(thumbFileName))
4039     m_currentFile->SetArt("thumb", thumbFileName);
4040   else
4041   {
4042     m_currentFile->SetArt("thumb", "");
4043     m_currentFile->FillInDefaultIcon();
4044   }
4045 }
4046
4047 void CGUIInfoManager::SetCurrentSong(CFileItem &item)
4048 {
4049   CLog::Log(LOGDEBUG,"CGUIInfoManager::SetCurrentSong(%s)",item.GetPath().c_str());
4050   *m_currentFile = item;
4051
4052   m_currentFile->LoadMusicTag();
4053   if (m_currentFile->GetMusicInfoTag()->GetTitle().empty())
4054   {
4055     // No title in tag, show filename only
4056     m_currentFile->GetMusicInfoTag()->SetTitle(CUtil::GetTitleFromPath(m_currentFile->GetPath()));
4057   }
4058   m_currentFile->GetMusicInfoTag()->SetLoaded(true);
4059
4060   // find a thumb for this file.
4061   if (m_currentFile->IsInternetStream())
4062   {
4063     if (!g_application.m_strPlayListFile.empty())
4064     {
4065       CLog::Log(LOGDEBUG,"Streaming media detected... using %s to find a thumb", g_application.m_strPlayListFile.c_str());
4066       CFileItem streamingItem(g_application.m_strPlayListFile,false);
4067
4068       CMusicThumbLoader loader;
4069       loader.FillThumb(streamingItem);
4070       if (streamingItem.HasArt("thumb"))
4071         m_currentFile->SetArt("thumb", streamingItem.GetArt("thumb"));
4072     }
4073   }
4074   else
4075   {
4076     CMusicThumbLoader loader;
4077     loader.LoadItem(m_currentFile);
4078   }
4079   m_currentFile->FillInDefaultIcon();
4080
4081   CMusicInfoLoader::LoadAdditionalTagInfo(m_currentFile);
4082 }
4083
4084 void CGUIInfoManager::SetCurrentMovie(CFileItem &item)
4085 {
4086   CLog::Log(LOGDEBUG,"CGUIInfoManager::SetCurrentMovie(%s)", CURL::GetRedacted(item.GetPath()).c_str());
4087   *m_currentFile = item;
4088
4089   /* also call GetMovieInfo() when a VideoInfoTag is already present or additional info won't be present in the tag */
4090   if (!m_currentFile->HasPVRChannelInfoTag())
4091   {
4092     CVideoDatabase dbs;
4093     if (dbs.Open())
4094     {
4095       CStdString path = item.GetPath();
4096       CStdString videoInfoTagPath(item.GetVideoInfoTag()->m_strFileNameAndPath);
4097       if (videoInfoTagPath.find("removable://") == 0)
4098         path = videoInfoTagPath;
4099       dbs.LoadVideoInfo(path, *m_currentFile->GetVideoInfoTag());
4100       dbs.Close();
4101     }
4102   }
4103
4104   // Find a thumb for this file.
4105   if (!item.HasArt("thumb"))
4106   {
4107     CVideoThumbLoader loader;
4108     loader.LoadItem(m_currentFile);
4109   }
4110
4111   // find a thumb for this stream
4112   if (item.IsInternetStream())
4113   {
4114     // case where .strm is used to start an audio stream
4115     if (g_application.m_pPlayer->IsPlayingAudio())
4116     {
4117       SetCurrentSong(item);
4118       return;
4119     }
4120
4121     // else its a video
4122     if (!g_application.m_strPlayListFile.empty())
4123     {
4124       CLog::Log(LOGDEBUG,"Streaming media detected... using %s to find a thumb", g_application.m_strPlayListFile.c_str());
4125       CFileItem thumbItem(g_application.m_strPlayListFile,false);
4126
4127       CVideoThumbLoader loader;
4128       if (loader.FillThumb(thumbItem))
4129         item.SetArt("thumb", thumbItem.GetArt("thumb"));
4130     }
4131   }
4132
4133   item.FillInDefaultIcon();
4134   m_currentMovieThumb = item.GetArt("thumb");
4135 }
4136
4137 string CGUIInfoManager::GetSystemHeatInfo(int info)
4138 {
4139   if (CTimeUtils::GetFrameTime() - m_lastSysHeatInfoTime >= SYSHEATUPDATEINTERVAL)
4140   { // update our variables
4141     m_lastSysHeatInfoTime = CTimeUtils::GetFrameTime();
4142 #if defined(TARGET_POSIX)
4143     g_cpuInfo.getTemperature(m_cpuTemp);
4144     m_gpuTemp = GetGPUTemperature();
4145 #endif
4146   }
4147
4148   CStdString text;
4149   switch(info)
4150   {
4151     case SYSTEM_CPU_TEMPERATURE:
4152       return m_cpuTemp.IsValid() ? m_cpuTemp.ToString() : "?";
4153       break;
4154     case SYSTEM_GPU_TEMPERATURE:
4155       return m_gpuTemp.IsValid() ? m_gpuTemp.ToString() : "?";
4156       break;
4157     case SYSTEM_FAN_SPEED:
4158       text = StringUtils::Format("%i%%", m_fanSpeed * 2);
4159       break;
4160     case SYSTEM_CPU_USAGE:
4161 #if defined(TARGET_DARWIN_OSX)
4162       text = StringUtils::Format("%4.2f%%", m_resourceCounter.GetCPUUsage());
4163 #elif defined(TARGET_DARWIN) || defined(TARGET_WINDOWS)
4164       text = StringUtils::Format("%d%%", g_cpuInfo.getUsedPercentage());
4165 #else
4166       text = StringUtils::Format("%s", g_cpuInfo.GetCoresUsageString().c_str());
4167 #endif
4168       break;
4169   }
4170   return text;
4171 }
4172
4173 CTemperature CGUIInfoManager::GetGPUTemperature()
4174 {
4175   int  value = 0;
4176   char scale = 0;
4177
4178 #if defined(TARGET_DARWIN_OSX)
4179   value = SMCGetTemperature(SMC_KEY_GPU_TEMP);
4180   return CTemperature::CreateFromCelsius(value);
4181 #else
4182   CStdString  cmd   = g_advancedSettings.m_gpuTempCmd;
4183   int         ret   = 0;
4184   FILE        *p    = NULL;
4185
4186   if (cmd.empty() || !(p = popen(cmd.c_str(), "r")))
4187     return CTemperature();
4188
4189   ret = fscanf(p, "%d %c", &value, &scale);
4190   pclose(p);
4191
4192   if (ret != 2)
4193     return CTemperature();
4194 #endif
4195
4196   if (scale == 'C' || scale == 'c')
4197     return CTemperature::CreateFromCelsius(value);
4198   if (scale == 'F' || scale == 'f')
4199     return CTemperature::CreateFromFahrenheit(value);
4200   return CTemperature();
4201 }
4202
4203 // Version string MUST NOT contain spaces.  It is used
4204 // in the HTTP request user agent.
4205 CStdString CGUIInfoManager::GetVersion()
4206 {
4207   CStdString tmp;
4208   if (GetXbmcGitRevision())
4209     tmp = StringUtils::Format("%d.%d%s Git:%s", VERSION_MAJOR, VERSION_MINOR, VERSION_TAG, GetXbmcGitRevision());
4210   else
4211     tmp = StringUtils::Format("%d.%d%s", VERSION_MAJOR, VERSION_MINOR, VERSION_TAG);
4212   return tmp;
4213 }
4214
4215 CStdString CGUIInfoManager::GetBuild()
4216 {
4217   return StringUtils::Format("%s", __DATE__);
4218 }
4219
4220 void CGUIInfoManager::SetDisplayAfterSeek(unsigned int timeOut, int seekOffset)
4221 {
4222   g_infoManager.m_performingSeek = false;
4223   if (timeOut>0)
4224   {
4225     m_AfterSeekTimeout = CTimeUtils::GetFrameTime() +  timeOut;
4226     if (seekOffset)
4227       m_seekOffset = seekOffset;
4228   }
4229   else
4230     m_AfterSeekTimeout = 0;
4231 }
4232
4233 bool CGUIInfoManager::GetDisplayAfterSeek()
4234 {
4235   if (CTimeUtils::GetFrameTime() < m_AfterSeekTimeout)
4236     return true;
4237   m_seekOffset = 0;
4238   return false;
4239 }
4240
4241 void CGUIInfoManager::Clear()
4242 {
4243   CSingleLock lock(m_critInfo);
4244   m_skinVariableStrings.clear();
4245
4246   /*
4247     Erase any info bools that are unused. We do this repeatedly as each run
4248     will remove those bools that are no longer dependencies of other bools
4249     in the vector.
4250    */
4251   vector<InfoPtr>::iterator i = remove_if(m_bools.begin(), m_bools.end(), std::mem_fun_ref(&InfoPtr::unique));
4252   while (i != m_bools.end())
4253   {
4254     m_bools.erase(i, m_bools.end());
4255     i = remove_if(m_bools.begin(), m_bools.end(), std::mem_fun_ref(&InfoPtr::unique));
4256   }
4257   // log which ones are used - they should all be gone by now
4258   for (vector<InfoPtr>::const_iterator i = m_bools.begin(); i != m_bools.end(); ++i)
4259     CLog::Log(LOGDEBUG, "Infobool '%s' still used by %u instances", (*i)->GetExpression().c_str(), (unsigned int) i->use_count());
4260 }
4261
4262 void CGUIInfoManager::UpdateFPS()
4263 {
4264   m_frameCounter++;
4265   unsigned int curTime = CTimeUtils::GetFrameTime();
4266
4267   float fTimeSpan = (float)(curTime - m_lastFPSTime);
4268   if (fTimeSpan >= 1000.0f)
4269   {
4270     fTimeSpan /= 1000.0f;
4271     m_fps = m_frameCounter / fTimeSpan;
4272     m_lastFPSTime = curTime;
4273     m_frameCounter = 0;
4274   }
4275 }
4276
4277 void CGUIInfoManager::UpdateAVInfo()
4278 {
4279   if(g_application.m_pPlayer->IsPlaying())
4280   {
4281     if (!m_AVInfoValid)
4282     {
4283       SPlayerVideoStreamInfo video;
4284       SPlayerAudioStreamInfo audio;
4285
4286       g_application.m_pPlayer->GetVideoStreamInfo(video);
4287       g_application.m_pPlayer->GetAudioStreamInfo(g_application.m_pPlayer->GetAudioStream(), audio);
4288
4289       m_videoInfo = video;
4290       m_audioInfo = audio;
4291       m_AVInfoValid = true;
4292     }
4293   }
4294 }
4295
4296 int CGUIInfoManager::AddListItemProp(const CStdString &str, int offset)
4297 {
4298   for (int i=0; i < (int)m_listitemProperties.size(); i++)
4299     if (m_listitemProperties[i] == str)
4300       return (LISTITEM_PROPERTY_START+offset + i);
4301
4302   if (m_listitemProperties.size() < LISTITEM_PROPERTY_END - LISTITEM_PROPERTY_START)
4303   {
4304     m_listitemProperties.push_back(str);
4305     return LISTITEM_PROPERTY_START + offset + m_listitemProperties.size() - 1;
4306   }
4307
4308   CLog::Log(LOGERROR,"%s - not enough listitem property space!", __FUNCTION__);
4309   return 0;
4310 }
4311
4312 int CGUIInfoManager::AddMultiInfo(const GUIInfo &info)
4313 {
4314   // check to see if we have this info already
4315   for (unsigned int i = 0; i < m_multiInfo.size(); i++)
4316     if (m_multiInfo[i] == info)
4317       return (int)i + MULTI_INFO_START;
4318   // return the new offset
4319   m_multiInfo.push_back(info);
4320   int id = (int)m_multiInfo.size() + MULTI_INFO_START - 1;
4321   if (id > MULTI_INFO_END)
4322     CLog::Log(LOGERROR, "%s - too many multiinfo bool/labels in this skin", __FUNCTION__);
4323   return id;
4324 }
4325
4326 int CGUIInfoManager::ConditionalStringParameter(const CStdString &parameter, bool caseSensitive /*= false*/)
4327 {
4328   // check to see if we have this parameter already
4329   for (unsigned int i = 0; i < m_stringParameters.size(); i++)
4330     if (parameter.Equals(m_stringParameters[i], caseSensitive))
4331       return (int)i;
4332   // return the new offset
4333   m_stringParameters.push_back(parameter);
4334   return (int)m_stringParameters.size() - 1;
4335 }
4336
4337 bool CGUIInfoManager::GetItemInt(int &value, const CGUIListItem *item, int info) const
4338 {
4339   if (!item)
4340   {
4341     value = 0;
4342     return false;
4343   }
4344
4345   if (info >= LISTITEM_PROPERTY_START && info - LISTITEM_PROPERTY_START < (int)m_listitemProperties.size())
4346   { // grab the property
4347     CStdString property = m_listitemProperties[info - LISTITEM_PROPERTY_START];
4348     CStdString val = item->GetProperty(property).asString();
4349     value = atoi(val);
4350     return true;
4351   }
4352
4353   switch (info)
4354   {
4355     case LISTITEM_PROGRESS:
4356     {
4357       value = 0;
4358       if (item->IsFileItem())
4359       {
4360         const CFileItem *pItem = (const CFileItem *)item;
4361         if (pItem && pItem->HasPVRChannelInfoTag())
4362         {
4363           CEpgInfoTag epgNow;
4364           if (pItem->GetPVRChannelInfoTag()->GetEPGNow(epgNow))
4365             value = (int) epgNow.ProgressPercentage();
4366         }
4367         else if (pItem && pItem->HasEPGInfoTag())
4368         {
4369           value = (int) pItem->GetEPGInfoTag()->ProgressPercentage();
4370         }
4371       }
4372
4373       return true;
4374     }
4375     break;
4376   case LISTITEM_PERCENT_PLAYED:
4377     if (item->IsFileItem() && ((const CFileItem *)item)->HasVideoInfoTag() && ((const CFileItem *)item)->GetVideoInfoTag()->m_resumePoint.IsPartWay())
4378       value = (int)(100 * ((const CFileItem *)item)->GetVideoInfoTag()->m_resumePoint.timeInSeconds / ((const CFileItem *)item)->GetVideoInfoTag()->m_resumePoint.totalTimeInSeconds);
4379     else if (item->IsFileItem() && ((const CFileItem *)item)->HasPVRRecordingInfoTag() && ((const CFileItem *)item)->GetPVRRecordingInfoTag()->m_resumePoint.IsPartWay())
4380       value = (int)(100 * ((const CFileItem *)item)->GetPVRRecordingInfoTag()->m_resumePoint.timeInSeconds / ((const CFileItem *)item)->GetPVRRecordingInfoTag()->m_resumePoint.totalTimeInSeconds);
4381     else
4382       value = 0;
4383     return true;
4384   }
4385
4386   value = 0;
4387   return false;
4388 }
4389
4390 CStdString CGUIInfoManager::GetItemLabel(const CFileItem *item, int info, CStdString *fallback)
4391 {
4392   if (!item) return "";
4393
4394   if (info >= CONDITIONAL_LABEL_START && info <= CONDITIONAL_LABEL_END)
4395     return GetSkinVariableString(info, false, item);
4396
4397   if (info >= LISTITEM_PROPERTY_START + LISTITEM_ART_OFFSET && info - (LISTITEM_PROPERTY_START + LISTITEM_ART_OFFSET) < (int)m_listitemProperties.size())
4398   { // grab the art
4399     std::string art = m_listitemProperties[info - (LISTITEM_PROPERTY_START + LISTITEM_ART_OFFSET)];
4400     return item->GetArt(art);
4401   }
4402
4403   if (info >= LISTITEM_PROPERTY_START && info - LISTITEM_PROPERTY_START < (int)m_listitemProperties.size())
4404   { // grab the property
4405     CStdString property = m_listitemProperties[info - LISTITEM_PROPERTY_START];
4406     return item->GetProperty(property).asString();
4407   }
4408
4409   if (info >= LISTITEM_PICTURE_START && info <= LISTITEM_PICTURE_END && item->HasPictureInfoTag())
4410     return item->GetPictureInfoTag()->GetInfo(picture_slide_map[info - LISTITEM_PICTURE_START]);
4411
4412   switch (info)
4413   {
4414   case LISTITEM_LABEL:
4415     return item->GetLabel();
4416   case LISTITEM_LABEL2:
4417     return item->GetLabel2();
4418   case LISTITEM_TITLE:
4419     if (item->HasPVRChannelInfoTag())
4420     {
4421       CEpgInfoTag epgTag;
4422       return item->GetPVRChannelInfoTag()->GetEPGNow(epgTag) ?
4423           epgTag.Title() :
4424           CSettings::Get().GetBool("epg.hidenoinfoavailable") ?
4425               StringUtils::EmptyString :
4426               g_localizeStrings.Get(19055); // no information available
4427     }
4428     if (item->HasPVRRecordingInfoTag())
4429       return item->GetPVRRecordingInfoTag()->m_strTitle;
4430     if (item->HasEPGInfoTag())
4431       return item->GetEPGInfoTag()->Title();
4432     if (item->HasPVRTimerInfoTag())
4433       return item->GetPVRTimerInfoTag()->Title();
4434     if (item->HasVideoInfoTag())
4435       return item->GetVideoInfoTag()->m_strTitle;
4436     if (item->HasMusicInfoTag())
4437       return item->GetMusicInfoTag()->GetTitle();
4438     break;
4439   case LISTITEM_ORIGINALTITLE:
4440     if (item->HasVideoInfoTag())
4441       return item->GetVideoInfoTag()->m_strOriginalTitle;
4442     break;
4443   case LISTITEM_PLAYCOUNT:
4444     {
4445       CStdString strPlayCount;
4446       if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_playCount > 0)
4447         strPlayCount = StringUtils::Format("%i", item->GetVideoInfoTag()->m_playCount);
4448       if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetPlayCount() > 0)
4449         strPlayCount = StringUtils::Format("%i", item->GetMusicInfoTag()->GetPlayCount());
4450       return strPlayCount;
4451     }
4452   case LISTITEM_LASTPLAYED:
4453     {
4454       CDateTime dateTime;
4455       if (item->HasVideoInfoTag())
4456         dateTime = item->GetVideoInfoTag()->m_lastPlayed;
4457       else if (item->HasMusicInfoTag())
4458         dateTime = item->GetMusicInfoTag()->GetLastPlayed();
4459
4460       if (dateTime.IsValid())
4461         return dateTime.GetAsLocalizedDate();
4462       break;
4463     }
4464   case LISTITEM_TRACKNUMBER:
4465     {
4466       CStdString track;
4467       if (item->HasMusicInfoTag())
4468         track = StringUtils::Format("%i", item->GetMusicInfoTag()->GetTrackNumber());
4469       if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iTrack > -1 )
4470         track = StringUtils::Format("%i", item->GetVideoInfoTag()->m_iTrack);
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       return path;
4751     }
4752   case LISTITEM_FILENAME_AND_PATH:
4753     {
4754       CStdString path;
4755       if (item->IsMusicDb() && item->HasMusicInfoTag())
4756         path = item->GetMusicInfoTag()->GetURL();
4757       else if (item->IsVideoDb() && item->HasVideoInfoTag())
4758         path = item->GetVideoInfoTag()->m_strFileNameAndPath;
4759       else
4760         path = item->GetPath();
4761       path = CURL(path).GetWithoutUserDetails();
4762       return path;
4763     }
4764   case LISTITEM_PICTURE_PATH:
4765     if (item->IsPicture() && (!item->IsZIP() || item->IsRAR() || item->IsCBZ() || item->IsCBR()))
4766       return item->GetPath();
4767     break;
4768   case LISTITEM_STUDIO:
4769     if (item->HasVideoInfoTag())
4770       return StringUtils::Join(item->GetVideoInfoTag()->m_studio, g_advancedSettings.m_videoItemSeparator);
4771     break;
4772   case LISTITEM_COUNTRY:
4773     if (item->HasVideoInfoTag())
4774       return StringUtils::Join(item->GetVideoInfoTag()->m_country, g_advancedSettings.m_videoItemSeparator);
4775     break;
4776   case LISTITEM_MPAA:
4777     if (item->HasVideoInfoTag())
4778       return item->GetVideoInfoTag()->m_strMPAARating;
4779     break;
4780   case LISTITEM_CAST:
4781     if (item->HasVideoInfoTag())
4782       return item->GetVideoInfoTag()->GetCast();
4783     break;
4784   case LISTITEM_CAST_AND_ROLE:
4785     if (item->HasVideoInfoTag())
4786       return item->GetVideoInfoTag()->GetCast(true);
4787     break;
4788   case LISTITEM_WRITER:
4789     if (item->HasVideoInfoTag())
4790       return StringUtils::Join(item->GetVideoInfoTag()->m_writingCredits, g_advancedSettings.m_videoItemSeparator);
4791     break;
4792   case LISTITEM_TAGLINE:
4793     if (item->HasVideoInfoTag())
4794       return item->GetVideoInfoTag()->m_strTagLine;
4795     break;
4796   case LISTITEM_TRAILER:
4797     if (item->HasVideoInfoTag())
4798       return item->GetVideoInfoTag()->m_strTrailer;
4799     break;
4800   case LISTITEM_TOP250:
4801     if (item->HasVideoInfoTag())
4802     {
4803       CStdString strResult;
4804       if (item->GetVideoInfoTag()->m_iTop250 > 0)
4805         strResult = StringUtils::Format("%i",item->GetVideoInfoTag()->m_iTop250);
4806       return strResult;
4807     }
4808     break;
4809   case LISTITEM_SORT_LETTER:
4810     {
4811       CStdString letter;
4812       std::wstring character(1, item->GetSortLabel()[0]);
4813       StringUtils::ToUpper(character);
4814       g_charsetConverter.wToUTF8(character, letter);
4815       return letter;
4816     }
4817     break;
4818   case LISTITEM_VIDEO_CODEC:
4819     if (item->HasVideoInfoTag())
4820       return item->GetVideoInfoTag()->m_streamDetails.GetVideoCodec();
4821     break;
4822   case LISTITEM_VIDEO_RESOLUTION:
4823     if (item->HasVideoInfoTag())
4824       return CStreamDetails::VideoDimsToResolutionDescription(item->GetVideoInfoTag()->m_streamDetails.GetVideoWidth(), item->GetVideoInfoTag()->m_streamDetails.GetVideoHeight());
4825     break;
4826   case LISTITEM_VIDEO_ASPECT:
4827     if (item->HasVideoInfoTag())
4828       return CStreamDetails::VideoAspectToAspectDescription(item->GetVideoInfoTag()->m_streamDetails.GetVideoAspect());
4829     break;
4830   case LISTITEM_AUDIO_CODEC:
4831     if (item->HasVideoInfoTag())
4832     {
4833       return item->GetVideoInfoTag()->m_streamDetails.GetAudioCodec();
4834     }
4835     break;
4836   case LISTITEM_AUDIO_CHANNELS:
4837     if (item->HasVideoInfoTag())
4838     {
4839       CStdString strResult;
4840       int iChannels = item->GetVideoInfoTag()->m_streamDetails.GetAudioChannels();
4841       if (iChannels > -1)
4842         strResult = StringUtils::Format("%i", iChannels);
4843       return strResult;
4844     }
4845     break;
4846   case LISTITEM_AUDIO_LANGUAGE:
4847     if (item->HasVideoInfoTag())
4848       return item->GetVideoInfoTag()->m_streamDetails.GetAudioLanguage();
4849     break;
4850   case LISTITEM_SUBTITLE_LANGUAGE:
4851     if (item->HasVideoInfoTag())
4852       return item->GetVideoInfoTag()->m_streamDetails.GetSubtitleLanguage();
4853     break;
4854   case LISTITEM_STARTTIME:
4855     if (item->HasPVRChannelInfoTag())
4856     {
4857       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4858       CEpgInfoTag tag;
4859       if (channel && channel->GetEPGNow(tag))
4860         return tag.StartAsLocalTime().GetAsLocalizedTime("", false);
4861       return CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
4862     }
4863     if (item->HasEPGInfoTag())
4864       return item->GetEPGInfoTag()->StartAsLocalTime().GetAsLocalizedTime("", false);
4865     if (item->HasPVRTimerInfoTag())
4866       return item->GetPVRTimerInfoTag()->StartAsLocalTime().GetAsLocalizedTime("", false);
4867     if (item->HasPVRRecordingInfoTag())
4868       return item->GetPVRRecordingInfoTag()->RecordingTimeAsLocalTime().GetAsLocalizedTime("", false);
4869     if (item->m_dateTime.IsValid())
4870       return item->m_dateTime.GetAsLocalizedTime("", false);
4871     break;
4872   case LISTITEM_ENDTIME:
4873     if (item->HasPVRChannelInfoTag())
4874     {
4875       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4876       CEpgInfoTag tag;
4877       if (channel && channel->GetEPGNow(tag))
4878         return tag.EndAsLocalTime().GetAsLocalizedTime("", false);
4879       return CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
4880     }
4881     if (item->HasEPGInfoTag())
4882       return item->GetEPGInfoTag()->EndAsLocalTime().GetAsLocalizedTime("", false);
4883     if (item->HasPVRTimerInfoTag())
4884       return item->GetPVRTimerInfoTag()->EndAsLocalTime().GetAsLocalizedTime("", false);
4885     break;
4886   case LISTITEM_STARTDATE:
4887     if (item->HasPVRChannelInfoTag())
4888     {
4889       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4890       CEpgInfoTag tag;
4891       if (channel && channel->GetEPGNow(tag))
4892         return tag.StartAsLocalTime().GetAsLocalizedDate(true);
4893       return CDateTime::GetCurrentDateTime().GetAsLocalizedDate(true);
4894     }
4895     if (item->HasEPGInfoTag())
4896       return item->GetEPGInfoTag()->StartAsLocalTime().GetAsLocalizedDate(true);
4897     if (item->HasPVRTimerInfoTag())
4898       return item->GetPVRTimerInfoTag()->StartAsLocalTime().GetAsLocalizedDate(true);
4899     if (item->HasPVRRecordingInfoTag())
4900       return item->GetPVRRecordingInfoTag()->RecordingTimeAsLocalTime().GetAsLocalizedDate(true);
4901     if (item->m_dateTime.IsValid())
4902       return item->m_dateTime.GetAsLocalizedDate(true);
4903     break;
4904   case LISTITEM_ENDDATE:
4905     if (item->HasPVRChannelInfoTag())
4906     {
4907       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4908       CEpgInfoTag tag;
4909       if (channel && channel->GetEPGNow(tag))
4910         return tag.EndAsLocalTime().GetAsLocalizedDate(true);
4911       return CDateTime::GetCurrentDateTime().GetAsLocalizedDate(true);
4912     }
4913     if (item->HasEPGInfoTag())
4914       return item->GetEPGInfoTag()->EndAsLocalTime().GetAsLocalizedDate(true);
4915     if (item->HasPVRTimerInfoTag())
4916       return item->GetPVRTimerInfoTag()->EndAsLocalTime().GetAsLocalizedDate(true);
4917     break;
4918   case LISTITEM_CHANNEL_NUMBER:
4919     {
4920       CStdString number;
4921       if (item->HasPVRChannelInfoTag())
4922         number = StringUtils::Format("%i", item->GetPVRChannelInfoTag()->ChannelNumber());
4923       if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->HasPVRChannel())
4924         number = StringUtils::Format("%i", item->GetEPGInfoTag()->PVRChannelNumber());
4925       if (item->HasPVRTimerInfoTag())
4926         number = StringUtils::Format("%i", item->GetPVRTimerInfoTag()->ChannelNumber());
4927
4928       return number;
4929     }
4930     break;
4931   case LISTITEM_CHANNEL_NAME:
4932     if (item->HasPVRChannelInfoTag())
4933       return item->GetPVRChannelInfoTag()->ChannelName();
4934     if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->HasPVRChannel())
4935       return item->GetEPGInfoTag()->PVRChannelName();
4936     if (item->HasPVRRecordingInfoTag())
4937       return item->GetPVRRecordingInfoTag()->m_strChannelName;
4938     if (item->HasPVRTimerInfoTag())
4939       return item->GetPVRTimerInfoTag()->ChannelName();
4940     break;
4941   case LISTITEM_NEXT_STARTTIME:
4942     {
4943       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4944       CEpgInfoTag tag;
4945       if (channel && channel->GetEPGNext(tag))
4946         return tag.StartAsLocalTime().GetAsLocalizedTime("", false);
4947     }
4948     return CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
4949   case LISTITEM_NEXT_ENDTIME:
4950     {
4951       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4952       CEpgInfoTag tag;
4953       if (channel && channel->GetEPGNext(tag))
4954         return tag.EndAsLocalTime().GetAsLocalizedTime("", false);
4955     }
4956     return CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
4957   case LISTITEM_NEXT_STARTDATE:
4958     {
4959       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4960       CEpgInfoTag tag;
4961       if (channel && channel->GetEPGNext(tag))
4962         return tag.StartAsLocalTime().GetAsLocalizedDate(true);
4963     }
4964     return CDateTime::GetCurrentDateTime().GetAsLocalizedDate(true);
4965   case LISTITEM_NEXT_ENDDATE:
4966     {
4967       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4968       CEpgInfoTag tag;
4969       if (channel && channel->GetEPGNext(tag))
4970         return tag.EndAsLocalTime().GetAsLocalizedDate(true);
4971     }
4972     return CDateTime::GetCurrentDateTime().GetAsLocalizedDate(true);
4973   case LISTITEM_NEXT_PLOT:
4974     {
4975       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4976       CEpgInfoTag tag;
4977       if (channel && channel->GetEPGNext(tag))
4978         return tag.Plot();
4979     }
4980     return StringUtils::EmptyString;
4981   case LISTITEM_NEXT_PLOT_OUTLINE:
4982     {
4983       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4984       CEpgInfoTag tag;
4985       if (channel && channel->GetEPGNext(tag))
4986         return tag.PlotOutline();
4987     }
4988     return StringUtils::EmptyString;
4989   case LISTITEM_NEXT_DURATION:
4990     {
4991       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4992       CEpgInfoTag tag;
4993       if (channel && channel->GetEPGNext(tag))
4994         return StringUtils::SecondsToTimeString(tag.GetDuration());
4995     }
4996     return StringUtils::EmptyString;
4997   case LISTITEM_NEXT_GENRE:
4998     {
4999       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
5000       CEpgInfoTag tag;
5001       if (channel && channel->GetEPGNext(tag))
5002         return StringUtils::Join(tag.Genre(), g_advancedSettings.m_videoItemSeparator);
5003     }
5004     return StringUtils::EmptyString;
5005   case LISTITEM_NEXT_TITLE:
5006     {
5007       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
5008       CEpgInfoTag tag;
5009       if (channel && channel->GetEPGNext(tag))
5010         return tag.Title();
5011     }
5012     return StringUtils::EmptyString;
5013   case LISTITEM_PARENTALRATING:
5014     {
5015       CStdString rating;
5016       if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->ParentalRating() > 0)
5017         rating = StringUtils::Format("%i", item->GetEPGInfoTag()->ParentalRating());
5018       return rating;
5019     }
5020     break;
5021   case LISTITEM_PERCENT_PLAYED:
5022     {
5023       int val;
5024       if (GetItemInt(val, item, info))
5025       {
5026         return StringUtils::Format("%d", val);;
5027       }
5028       break;
5029     }
5030   case LISTITEM_DATE_ADDED:
5031     if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_dateAdded.IsValid())
5032       return item->GetVideoInfoTag()->m_dateAdded.GetAsLocalizedDate();
5033     break;
5034   case LISTITEM_DBTYPE:
5035     if (item->HasVideoInfoTag())
5036       return item->GetVideoInfoTag()->m_type;
5037     break;
5038   case LISTITEM_DBID:
5039     if (item->HasVideoInfoTag())
5040       {
5041         return StringUtils::Format("%i", item->GetVideoInfoTag()->m_iDbId);;
5042       }
5043     if (item->HasMusicInfoTag())
5044       {
5045         return StringUtils::Format("%i", item->GetMusicInfoTag()->GetDatabaseId());;
5046       }
5047     break;
5048   case LISTITEM_STEREOSCOPIC_MODE:
5049     {
5050       std::string stereoMode = item->GetProperty("stereomode").asString();
5051       if (stereoMode.empty() && item->HasVideoInfoTag())
5052         stereoMode = CStereoscopicsManager::Get().NormalizeStereoMode(item->GetVideoInfoTag()->m_streamDetails.GetStereoMode());
5053       return stereoMode;
5054     }
5055   }
5056   return "";
5057 }
5058
5059 CStdString CGUIInfoManager::GetItemImage(const CFileItem *item, int info, CStdString *fallback)
5060 {
5061   if (info >= CONDITIONAL_LABEL_START && info <= CONDITIONAL_LABEL_END)
5062     return GetSkinVariableString(info, true, item);
5063
5064   switch (info)
5065   {
5066   case LISTITEM_RATING:  // old song rating format
5067     {
5068       if (item->HasMusicInfoTag())
5069       {
5070         return StringUtils::Format("songrating%c.png", item->GetMusicInfoTag()->GetRating());
5071       }
5072     }
5073     break;
5074   case LISTITEM_STAR_RATING:
5075     {
5076       CStdString rating;
5077       if (item->HasVideoInfoTag())
5078       { // rating for videos is assumed 0..10, so convert to 0..5
5079         rating = StringUtils::Format("rating%d.png", (long)((item->GetVideoInfoTag()->m_fRating * 0.5f) + 0.5f));
5080       }
5081       else if (item->HasMusicInfoTag())
5082       { // song rating.
5083         rating = StringUtils::Format("rating%c.png", item->GetMusicInfoTag()->GetRating());
5084       }
5085       return rating;
5086     }
5087     break;
5088   }  /* switch (info) */
5089
5090   return GetItemLabel(item, info, fallback);
5091 }
5092
5093 bool CGUIInfoManager::GetItemBool(const CGUIListItem *item, int condition) const
5094 {
5095   if (!item) return false;
5096   if (condition >= LISTITEM_PROPERTY_START && condition - LISTITEM_PROPERTY_START < (int)m_listitemProperties.size())
5097   { // grab the property
5098     CStdString property = m_listitemProperties[condition - LISTITEM_PROPERTY_START];
5099     return item->GetProperty(property).asBoolean();
5100   }
5101   else if (condition == LISTITEM_ISPLAYING)
5102   {
5103     if (item->HasProperty("playlistposition"))
5104       return (int)item->GetProperty("playlisttype").asInteger() == g_playlistPlayer.GetCurrentPlaylist() && (int)item->GetProperty("playlistposition").asInteger() == g_playlistPlayer.GetCurrentSong();
5105     else if (item->IsFileItem() && !m_currentFile->GetPath().empty())
5106     {
5107       if (!g_application.m_strPlayListFile.empty())
5108       {
5109         //playlist file that is currently playing or the playlistitem that is currently playing.
5110         return g_application.m_strPlayListFile.Equals(((const CFileItem *)item)->GetPath()) || m_currentFile->IsSamePath((const CFileItem *)item);
5111       }
5112       return m_currentFile->IsSamePath((const CFileItem *)item);
5113     }
5114   }
5115   else if (condition == LISTITEM_ISSELECTED)
5116     return item->IsSelected();
5117   else if (condition == LISTITEM_IS_FOLDER)
5118     return item->m_bIsFolder;
5119   else if (condition == LISTITEM_IS_RESUMABLE)
5120   {
5121     if (item->IsFileItem())
5122     {
5123       if (((const CFileItem *)item)->HasVideoInfoTag())
5124         return ((const CFileItem *)item)->GetVideoInfoTag()->m_resumePoint.timeInSeconds > 0;
5125       else if (((const CFileItem *)item)->HasPVRRecordingInfoTag())
5126         return ((const CFileItem *)item)->GetPVRRecordingInfoTag()->m_resumePoint.timeInSeconds > 0;
5127     }
5128   }
5129   else if (item->IsFileItem())
5130   {
5131     const CFileItem *pItem = (const CFileItem *)item;
5132     if (condition == LISTITEM_ISRECORDING)
5133     {
5134       if (!g_PVRManager.IsStarted())
5135         return false;
5136
5137       if (pItem->HasPVRChannelInfoTag())
5138       {
5139         return pItem->GetPVRChannelInfoTag()->IsRecording();
5140       }
5141       else if (pItem->HasPVRTimerInfoTag())
5142       {
5143         const CPVRTimerInfoTag *timer = pItem->GetPVRTimerInfoTag();
5144         if (timer)
5145           return timer->IsRecording();
5146       }
5147       else if (pItem->HasEPGInfoTag())
5148       {
5149         CFileItemPtr timer = g_PVRTimers->GetTimerForEpgTag(pItem);
5150         if (timer && timer->HasPVRTimerInfoTag())
5151           return timer->GetPVRTimerInfoTag()->IsRecording();
5152       }
5153     }
5154     else if (condition == LISTITEM_HASTIMER)
5155     {
5156       if (pItem->HasEPGInfoTag())
5157       {
5158         CFileItemPtr timer = g_PVRTimers->GetTimerForEpgTag(pItem);
5159         if (timer && timer->HasPVRTimerInfoTag())
5160           return timer->GetPVRTimerInfoTag()->IsActive();
5161       }
5162     }
5163     else if (condition == LISTITEM_HAS_EPG)
5164     {
5165       if (pItem->HasPVRChannelInfoTag())
5166       {
5167         CEpgInfoTag epgTag;
5168         return pItem->GetPVRChannelInfoTag()->GetEPGNow(epgTag);
5169       }
5170       else
5171       {
5172         return pItem->HasEPGInfoTag();
5173       }
5174     }
5175     else if (condition == LISTITEM_ISENCRYPTED)
5176     {
5177       if (pItem->HasPVRChannelInfoTag())
5178       {
5179         return pItem->GetPVRChannelInfoTag()->IsEncrypted();
5180       }
5181       else if (pItem->HasEPGInfoTag() && pItem->GetEPGInfoTag()->HasPVRChannel())
5182       {
5183         return pItem->GetEPGInfoTag()->ChannelTag()->IsEncrypted();
5184       }
5185     }
5186     else if (condition == LISTITEM_IS_STEREOSCOPIC)
5187     {
5188       std::string stereoMode = pItem->GetProperty("stereomode").asString();
5189       if (stereoMode.empty() && pItem->HasVideoInfoTag())
5190           stereoMode = CStereoscopicsManager::Get().NormalizeStereoMode(pItem->GetVideoInfoTag()->m_streamDetails.GetStereoMode());
5191       if (!stereoMode.empty() && stereoMode != "mono")
5192         return true;
5193     }
5194   }
5195
5196   return false;
5197 }
5198
5199 void CGUIInfoManager::ResetCache()
5200 {
5201   // reset any animation triggers as well
5202   m_containerMoves.clear();
5203   // mark our infobools as dirty
5204   CSingleLock lock(m_critInfo);
5205   for (vector<InfoPtr>::iterator i = m_bools.begin(); i != m_bools.end(); ++i)
5206     (*i)->SetDirty();
5207 }
5208
5209 // Called from tuxbox service thread to update current status
5210 void CGUIInfoManager::UpdateFromTuxBox()
5211 {
5212   if(g_tuxbox.vVideoSubChannel.mode)
5213     m_currentFile->GetVideoInfoTag()->m_strTitle = g_tuxbox.vVideoSubChannel.current_name;
5214
5215   // Set m_currentMovieDuration
5216   if(!g_tuxbox.sCurSrvData.current_event_duration.empty() &&
5217     !g_tuxbox.sCurSrvData.next_event_description.empty() &&
5218     !g_tuxbox.sCurSrvData.current_event_duration.Equals("-") &&
5219     !g_tuxbox.sCurSrvData.next_event_description.Equals("-"))
5220   {
5221     StringUtils::Replace(g_tuxbox.sCurSrvData.current_event_duration, "(","");
5222     StringUtils::Replace(g_tuxbox.sCurSrvData.current_event_duration, ")","");
5223
5224     m_currentMovieDuration = StringUtils::Format("%s: %s %s (%s - %s)",
5225                                                  g_localizeStrings.Get(180).c_str(),
5226                                                  g_tuxbox.sCurSrvData.current_event_duration.c_str(),
5227                                                  g_localizeStrings.Get(12391).c_str(),
5228                                                  g_tuxbox.sCurSrvData.current_event_time.c_str(),
5229                                                  g_tuxbox.sCurSrvData.next_event_time.c_str());
5230   }
5231
5232   //Set strVideoGenre
5233   if (!g_tuxbox.sCurSrvData.current_event_description.empty() &&
5234     !g_tuxbox.sCurSrvData.next_event_description.empty() &&
5235     !g_tuxbox.sCurSrvData.current_event_description.Equals("-") &&
5236     !g_tuxbox.sCurSrvData.next_event_description.Equals("-"))
5237   {
5238     CStdString genre = StringUtils::Format("%s %s  -  (%s: %s)",
5239                                            g_localizeStrings.Get(143).c_str(),
5240                                            g_tuxbox.sCurSrvData.current_event_description.c_str(),
5241                                            g_localizeStrings.Get(209).c_str(),
5242                                            g_tuxbox.sCurSrvData.next_event_description.c_str());
5243     m_currentFile->GetVideoInfoTag()->m_genre = StringUtils::Split(genre, g_advancedSettings.m_videoItemSeparator);
5244   }
5245
5246   //Set m_currentMovie.m_director
5247   if (!g_tuxbox.sCurSrvData.current_event_details.Equals("-") &&
5248     !g_tuxbox.sCurSrvData.current_event_details.empty())
5249   {
5250     m_currentFile->GetVideoInfoTag()->m_director = StringUtils::Split(g_tuxbox.sCurSrvData.current_event_details, g_advancedSettings.m_videoItemSeparator);
5251   }
5252 }
5253
5254 CStdString CGUIInfoManager::GetPictureLabel(int info)
5255 {
5256   if (info == SLIDE_FILE_NAME)
5257     return GetItemLabel(m_currentSlide, LISTITEM_FILENAME);
5258   else if (info == SLIDE_FILE_PATH)
5259   {
5260     CStdString path = URIUtils::GetDirectory(m_currentSlide->GetPath());
5261     return CURL(path).GetWithoutUserDetails();
5262   }
5263   else if (info == SLIDE_FILE_SIZE)
5264     return GetItemLabel(m_currentSlide, LISTITEM_SIZE);
5265   else if (info == SLIDE_FILE_DATE)
5266     return GetItemLabel(m_currentSlide, LISTITEM_DATE);
5267   else if (info == SLIDE_INDEX)
5268   {
5269     CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
5270     if (slideshow && slideshow->NumSlides())
5271     {
5272       return StringUtils::Format("%d/%d", slideshow->CurrentSlide(), slideshow->NumSlides());
5273     }
5274   }
5275   if (m_currentSlide->HasPictureInfoTag())
5276     return m_currentSlide->GetPictureInfoTag()->GetInfo(info);
5277   return "";
5278 }
5279
5280 void CGUIInfoManager::SetCurrentSlide(CFileItem &item)
5281 {
5282   if (m_currentSlide->GetPath() != item.GetPath())
5283   {
5284     if (!item.GetPictureInfoTag()->Loaded()) // If picture metadata has not been loaded yet, load it now
5285       item.GetPictureInfoTag()->Load(item.GetPath());
5286     *m_currentSlide = item;
5287   }
5288 }
5289
5290 void CGUIInfoManager::ResetCurrentSlide()
5291 {
5292   m_currentSlide->Reset();
5293 }
5294
5295 bool CGUIInfoManager::CheckWindowCondition(CGUIWindow *window, int condition) const
5296 {
5297   // check if it satisfies our condition
5298   if (!window) return false;
5299   if ((condition & WINDOW_CONDITION_HAS_LIST_ITEMS) && !window->HasListItems())
5300     return false;
5301   if ((condition & WINDOW_CONDITION_IS_MEDIA_WINDOW) && !window->IsMediaWindow())
5302     return false;
5303   return true;
5304 }
5305
5306 CGUIWindow *CGUIInfoManager::GetWindowWithCondition(int contextWindow, int condition) const
5307 {
5308   CGUIWindow *window = g_windowManager.GetWindow(contextWindow);
5309   if (CheckWindowCondition(window, condition))
5310     return window;
5311
5312   // try topmost dialog
5313   window = g_windowManager.GetWindow(g_windowManager.GetTopMostModalDialogID());
5314   if (CheckWindowCondition(window, condition))
5315     return window;
5316
5317   // try active window
5318   window = g_windowManager.GetWindow(g_windowManager.GetActiveWindow());
5319   if (CheckWindowCondition(window, condition))
5320     return window;
5321
5322   return NULL;
5323 }
5324
5325 void CGUIInfoManager::SetCurrentVideoTag(const CVideoInfoTag &tag)
5326 {
5327   *m_currentFile->GetVideoInfoTag() = tag;
5328   m_currentFile->m_lStartOffset = 0;
5329 }
5330
5331 void CGUIInfoManager::SetCurrentSongTag(const MUSIC_INFO::CMusicInfoTag &tag)
5332 {
5333   //CLog::Log(LOGDEBUG, "Asked to SetCurrentTag");
5334   *m_currentFile->GetMusicInfoTag() = tag;
5335   m_currentFile->m_lStartOffset = 0;
5336 }
5337
5338 const CFileItem& CGUIInfoManager::GetCurrentSlide() const
5339 {
5340   return *m_currentSlide;
5341 }
5342
5343 const MUSIC_INFO::CMusicInfoTag* CGUIInfoManager::GetCurrentSongTag() const
5344 {
5345   if (m_currentFile->HasMusicInfoTag())
5346     return m_currentFile->GetMusicInfoTag();
5347
5348   return NULL;
5349 }
5350
5351 const CVideoInfoTag* CGUIInfoManager::GetCurrentMovieTag() const
5352 {
5353   if (m_currentFile->HasVideoInfoTag())
5354     return m_currentFile->GetVideoInfoTag();
5355
5356   return NULL;
5357 }
5358
5359 void GUIInfo::SetInfoFlag(uint32_t flag)
5360 {
5361   assert(flag >= (1 << 24));
5362   m_data1 |= flag;
5363 }
5364
5365 uint32_t GUIInfo::GetInfoFlag() const
5366 {
5367   // we strip out the bottom 24 bits, where we keep data
5368   // and return the flag only
5369   return m_data1 & 0xff000000;
5370 }
5371
5372 uint32_t GUIInfo::GetData1() const
5373 {
5374   // we strip out the top 8 bits, where we keep flags
5375   // and return the unflagged data
5376   return m_data1 & ((1 << 24) -1);
5377 }
5378
5379 int GUIInfo::GetData2() const
5380 {
5381   return m_data2;
5382 }
5383
5384 void CGUIInfoManager::SetLibraryBool(int condition, bool value)
5385 {
5386   switch (condition)
5387   {
5388     case LIBRARY_HAS_MUSIC:
5389       m_libraryHasMusic = value ? 1 : 0;
5390       break;
5391     case LIBRARY_HAS_MOVIES:
5392       m_libraryHasMovies = value ? 1 : 0;
5393       break;
5394     case LIBRARY_HAS_MOVIE_SETS:
5395       m_libraryHasMovieSets = value ? 1 : 0;
5396       break;
5397     case LIBRARY_HAS_TVSHOWS:
5398       m_libraryHasTVShows = value ? 1 : 0;
5399       break;
5400     case LIBRARY_HAS_MUSICVIDEOS:
5401       m_libraryHasMusicVideos = value ? 1 : 0;
5402       break;
5403     default:
5404       break;
5405   }
5406 }
5407
5408 void CGUIInfoManager::ResetLibraryBools()
5409 {
5410   m_libraryHasMusic = -1;
5411   m_libraryHasMovies = -1;
5412   m_libraryHasTVShows = -1;
5413   m_libraryHasMusicVideos = -1;
5414   m_libraryHasMovieSets = -1;
5415 }
5416
5417 bool CGUIInfoManager::GetLibraryBool(int condition)
5418 {
5419   if (condition == LIBRARY_HAS_MUSIC)
5420   {
5421     if (m_libraryHasMusic < 0)
5422     { // query
5423       CMusicDatabase db;
5424       if (db.Open())
5425       {
5426         m_libraryHasMusic = (db.GetSongsCount() > 0) ? 1 : 0;
5427         db.Close();
5428       }
5429     }
5430     return m_libraryHasMusic > 0;
5431   }
5432   else if (condition == LIBRARY_HAS_MOVIES)
5433   {
5434     if (m_libraryHasMovies < 0)
5435     {
5436       CVideoDatabase db;
5437       if (db.Open())
5438       {
5439         m_libraryHasMovies = db.HasContent(VIDEODB_CONTENT_MOVIES) ? 1 : 0;
5440         db.Close();
5441       }
5442     }
5443     return m_libraryHasMovies > 0;
5444   }
5445   else if (condition == LIBRARY_HAS_MOVIE_SETS)
5446   {
5447     if (m_libraryHasMovieSets < 0)
5448     {
5449       CVideoDatabase db;
5450       if (db.Open())
5451       {
5452         m_libraryHasMovieSets = db.HasSets() ? 1 : 0;
5453         db.Close();
5454       }
5455     }
5456     return m_libraryHasMovieSets > 0;
5457   }
5458   else if (condition == LIBRARY_HAS_TVSHOWS)
5459   {
5460     if (m_libraryHasTVShows < 0)
5461     {
5462       CVideoDatabase db;
5463       if (db.Open())
5464       {
5465         m_libraryHasTVShows = db.HasContent(VIDEODB_CONTENT_TVSHOWS) ? 1 : 0;
5466         db.Close();
5467       }
5468     }
5469     return m_libraryHasTVShows > 0;
5470   }
5471   else if (condition == LIBRARY_HAS_MUSICVIDEOS)
5472   {
5473     if (m_libraryHasMusicVideos < 0)
5474     {
5475       CVideoDatabase db;
5476       if (db.Open())
5477       {
5478         m_libraryHasMusicVideos = db.HasContent(VIDEODB_CONTENT_MUSICVIDEOS) ? 1 : 0;
5479         db.Close();
5480       }
5481     }
5482     return m_libraryHasMusicVideos > 0;
5483   }
5484   else if (condition == LIBRARY_HAS_VIDEO)
5485   {
5486     return (GetLibraryBool(LIBRARY_HAS_MOVIES) ||
5487             GetLibraryBool(LIBRARY_HAS_TVSHOWS) ||
5488             GetLibraryBool(LIBRARY_HAS_MUSICVIDEOS));
5489   }
5490   return false;
5491 }
5492
5493 int CGUIInfoManager::RegisterSkinVariableString(const CSkinVariableString* info)
5494 {
5495   if (!info)
5496     return 0;
5497
5498   CSingleLock lock(m_critInfo);
5499   m_skinVariableStrings.push_back(*info);
5500   delete info;
5501   return CONDITIONAL_LABEL_START + m_skinVariableStrings.size() - 1;
5502 }
5503
5504 int CGUIInfoManager::TranslateSkinVariableString(const CStdString& name, int context)
5505 {
5506   for (vector<CSkinVariableString>::const_iterator it = m_skinVariableStrings.begin();
5507        it != m_skinVariableStrings.end(); ++it)
5508   {
5509     if (it->GetName().Equals(name) && it->GetContext() == context)
5510       return it - m_skinVariableStrings.begin() + CONDITIONAL_LABEL_START;
5511   }
5512   return 0;
5513 }
5514
5515 CStdString CGUIInfoManager::GetSkinVariableString(int info,
5516                                                   bool preferImage /*= false*/,
5517                                                   const CGUIListItem *item /*= NULL*/)
5518 {
5519   info -= CONDITIONAL_LABEL_START;
5520   if (info >= 0 && info < (int)m_skinVariableStrings.size())
5521     return m_skinVariableStrings[info].GetValue(preferImage, item);
5522
5523   return "";
5524 }
5525
5526 bool CGUIInfoManager::ConditionsChangedValues(const std::map<INFO::InfoPtr, bool>& map)
5527 {
5528   for (std::map<INFO::InfoPtr, bool>::const_iterator it = map.begin() ; it != map.end() ; it++)
5529   {
5530     if (it->first->Get() != it->second)
5531       return true;
5532   }
5533   return false;
5534 }
5535
5536 bool CGUIInfoManager::GetEpgInfoTag(CEpgInfoTag& tag) const
5537 {
5538   if (m_currentFile->HasEPGInfoTag())
5539   {
5540     CEpgInfoTag* currentTag =  m_currentFile->GetEPGInfoTag();
5541     while (currentTag && !currentTag->IsActive())
5542       currentTag = currentTag->GetNextEvent().get();
5543     if (currentTag)
5544     {
5545       tag = *currentTag;
5546       return true;
5547     }
5548   }
5549   return false;
5550 }