Merge pull request #4085 from Black09/textbox-auto-height
[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="movies";
2975           if (!m_currentFile->HasVideoInfoTag() || m_currentFile->GetVideoInfoTag()->IsEmpty())
2976             strContent = "files";
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
4470       return track;
4471     }
4472   case LISTITEM_DISC_NUMBER:
4473     {
4474       CStdString disc;
4475       if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetDiscNumber() > 0)
4476         disc = StringUtils::Format("%i", item->GetMusicInfoTag()->GetDiscNumber());
4477       return disc;
4478     }
4479   case LISTITEM_ARTIST:
4480     if (item->HasVideoInfoTag())
4481       return StringUtils::Join(item->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator);
4482     if (item->HasMusicInfoTag())
4483       return StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator);
4484     break;
4485   case LISTITEM_ALBUM_ARTIST:
4486     if (item->HasMusicInfoTag())
4487       return StringUtils::Join(item->GetMusicInfoTag()->GetAlbumArtist(), g_advancedSettings.m_musicItemSeparator);
4488     break;
4489   case LISTITEM_DIRECTOR:
4490     if (item->HasVideoInfoTag())
4491       return StringUtils::Join(item->GetVideoInfoTag()->m_director, g_advancedSettings.m_videoItemSeparator);
4492     break;
4493   case LISTITEM_ALBUM:
4494     if (item->HasVideoInfoTag())
4495       return item->GetVideoInfoTag()->m_strAlbum;
4496     if (item->HasMusicInfoTag())
4497       return item->GetMusicInfoTag()->GetAlbum();
4498     break;
4499   case LISTITEM_YEAR:
4500     if (item->HasVideoInfoTag())
4501     {
4502       CStdString strResult;
4503       if (item->GetVideoInfoTag()->m_iYear > 0)
4504         strResult = StringUtils::Format("%i",item->GetVideoInfoTag()->m_iYear);
4505       return strResult;
4506     }
4507     if (item->HasMusicInfoTag())
4508       return item->GetMusicInfoTag()->GetYearString();
4509     break;
4510   case LISTITEM_PREMIERED:
4511     if (item->HasVideoInfoTag())
4512     {
4513       CDateTime dateTime;
4514       if (item->GetVideoInfoTag()->m_firstAired.IsValid())
4515         dateTime = item->GetVideoInfoTag()->m_firstAired;
4516       else if (item->GetVideoInfoTag()->m_premiered.IsValid())
4517         dateTime = item->GetVideoInfoTag()->m_premiered;
4518
4519       if (dateTime.IsValid())
4520         return dateTime.GetAsLocalizedDate();
4521       break;
4522     }
4523     break;
4524   case LISTITEM_GENRE:
4525     if (item->HasVideoInfoTag())
4526       return StringUtils::Join(item->GetVideoInfoTag()->m_genre, g_advancedSettings.m_videoItemSeparator);
4527     if (item->HasMusicInfoTag())
4528       return StringUtils::Join(item->GetMusicInfoTag()->GetGenre(), g_advancedSettings.m_musicItemSeparator);
4529     if (item->HasPVRChannelInfoTag())
4530     {
4531       CEpgInfoTag epgTag;
4532       return item->GetPVRChannelInfoTag()->GetEPGNow(epgTag) ? StringUtils::Join(epgTag.Genre(), g_advancedSettings.m_videoItemSeparator) : StringUtils::EmptyString;
4533     }
4534     if (item->HasPVRRecordingInfoTag())
4535       return StringUtils::Join(item->GetPVRRecordingInfoTag()->m_genre, g_advancedSettings.m_videoItemSeparator);
4536     if (item->HasEPGInfoTag())
4537       return StringUtils::Join(item->GetEPGInfoTag()->Genre(), g_advancedSettings.m_videoItemSeparator);
4538     break;
4539   case LISTITEM_FILENAME:
4540   case LISTITEM_FILE_EXTENSION:
4541     {
4542       CStdString strFile;
4543       if (item->IsMusicDb() && item->HasMusicInfoTag())
4544         strFile = URIUtils::GetFileName(item->GetMusicInfoTag()->GetURL());
4545       else if (item->IsVideoDb() && item->HasVideoInfoTag())
4546         strFile = URIUtils::GetFileName(item->GetVideoInfoTag()->m_strFileNameAndPath);
4547       else
4548         strFile = URIUtils::GetFileName(item->GetPath());
4549
4550       if (info==LISTITEM_FILE_EXTENSION)
4551       {
4552         CStdString strExtension = URIUtils::GetExtension(strFile);
4553         return StringUtils::TrimLeft(strExtension, ".");
4554       }
4555       return strFile;
4556     }
4557     break;
4558   case LISTITEM_DATE:
4559     if (item->HasEPGInfoTag())
4560       return item->GetEPGInfoTag()->StartAsLocalTime().GetAsLocalizedDateTime(false, false);
4561     if (item->HasPVRChannelInfoTag())
4562     {
4563       CEpgInfoTag epgTag;
4564       return item->GetPVRChannelInfoTag()->GetEPGNow(epgTag) ? epgTag.StartAsLocalTime().GetAsLocalizedDateTime(false, false) : CDateTime::GetCurrentDateTime().GetAsLocalizedDateTime(false, false);
4565     }
4566     if (item->HasPVRRecordingInfoTag())
4567       return item->GetPVRRecordingInfoTag()->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(false, false);
4568     if (item->HasPVRTimerInfoTag())
4569       return item->GetPVRTimerInfoTag()->Summary();
4570     if (item->m_dateTime.IsValid())
4571       return item->m_dateTime.GetAsLocalizedDate();
4572     break;
4573   case LISTITEM_SIZE:
4574     if (!item->m_bIsFolder || item->m_dwSize)
4575       return StringUtils::SizeToString(item->m_dwSize);
4576     break;
4577   case LISTITEM_RATING:
4578     {
4579       CStdString rating;
4580       if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_fRating > 0.f) // movie rating
4581         rating = StringUtils::Format("%.1f", item->GetVideoInfoTag()->m_fRating);
4582       else if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetRating() > '0')
4583       { // song rating.  Images will probably be better than numbers for this in the long run
4584         rating = item->GetMusicInfoTag()->GetRating();
4585       }
4586       return rating;
4587     }
4588   case LISTITEM_RATING_AND_VOTES:
4589     {
4590       if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_fRating > 0.f) // movie rating
4591       {
4592         CStdString strRatingAndVotes;
4593         if (item->GetVideoInfoTag()->m_strVotes.empty())
4594           strRatingAndVotes = StringUtils::Format("%.1f",
4595                                                   item->GetVideoInfoTag()->m_fRating);
4596         else
4597           strRatingAndVotes = StringUtils::Format("%.1f (%s %s)",
4598                                                   item->GetVideoInfoTag()->m_fRating,
4599                                                   item->GetVideoInfoTag()->m_strVotes.c_str(),
4600                                                   g_localizeStrings.Get(20350).c_str());
4601         return strRatingAndVotes;
4602       }
4603     }
4604     break;
4605   case LISTITEM_VOTES:
4606     if (item->HasVideoInfoTag())
4607       return item->GetVideoInfoTag()->m_strVotes;
4608     break;
4609   case LISTITEM_PROGRAM_COUNT:
4610     {
4611       return StringUtils::Format("%i", item->m_iprogramCount);;
4612     }
4613   case LISTITEM_DURATION:
4614     {
4615       CStdString duration;
4616       if (item->HasPVRChannelInfoTag())
4617       {
4618         const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4619         CEpgInfoTag tag;
4620         if (channel && channel->GetEPGNow(tag))
4621           return StringUtils::SecondsToTimeString(tag.GetDuration());
4622         return StringUtils::EmptyString;
4623       }
4624       else if (item->HasPVRRecordingInfoTag())
4625       {
4626         if (item->GetPVRRecordingInfoTag()->GetDuration() > 0)
4627           duration = StringUtils::SecondsToTimeString(item->GetPVRRecordingInfoTag()->GetDuration());
4628       }
4629       else if (item->HasEPGInfoTag())
4630       {
4631         if (item->GetEPGInfoTag()->GetDuration() > 0)
4632           duration = StringUtils::SecondsToTimeString(item->GetEPGInfoTag()->GetDuration());
4633       }
4634       else if (item->HasVideoInfoTag())
4635       {
4636         if (item->GetVideoInfoTag()->GetDuration() > 0)
4637           duration = StringUtils::Format("%d", item->GetVideoInfoTag()->GetDuration() / 60);
4638       }
4639       else if (item->HasMusicInfoTag())
4640       {
4641         if (item->GetMusicInfoTag()->GetDuration() > 0)
4642           duration = StringUtils::SecondsToTimeString(item->GetMusicInfoTag()->GetDuration());
4643       }
4644       return duration;
4645     }
4646   case LISTITEM_PLOT:
4647     if (item->HasPVRChannelInfoTag())
4648     {
4649       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4650       CEpgInfoTag tag;
4651       if (channel && channel->GetEPGNow(tag))
4652         return tag.Plot();
4653       return StringUtils::EmptyString;
4654     }
4655     if (item->HasEPGInfoTag())
4656       return item->GetEPGInfoTag()->Plot();
4657     if (item->HasPVRRecordingInfoTag())
4658       return item->GetPVRRecordingInfoTag()->m_strPlot;
4659     if (item->HasVideoInfoTag())
4660     {
4661       if (!(!item->GetVideoInfoTag()->m_strShowTitle.empty() && item->GetVideoInfoTag()->m_iSeason == -1)) // dont apply to tvshows
4662         if (item->GetVideoInfoTag()->m_playCount == 0 && !CSettings::Get().GetBool("videolibrary.showunwatchedplots"))
4663           return g_localizeStrings.Get(20370);
4664
4665       return item->GetVideoInfoTag()->m_strPlot;
4666     }
4667     break;
4668   case LISTITEM_PLOT_OUTLINE:
4669     if (item->HasPVRChannelInfoTag())
4670     {
4671       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4672       CEpgInfoTag tag;
4673       if (channel && channel->GetEPGNow(tag))
4674         return tag.PlotOutline();
4675       return StringUtils::EmptyString;
4676     }
4677     if (item->HasEPGInfoTag())
4678       return item->GetEPGInfoTag()->PlotOutline();
4679     if (item->HasPVRRecordingInfoTag())
4680       return item->GetPVRRecordingInfoTag()->m_strPlotOutline;
4681     if (item->HasVideoInfoTag())
4682       return item->GetVideoInfoTag()->m_strPlotOutline;
4683     break;
4684   case LISTITEM_EPISODE:
4685     if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iEpisode > 0)
4686     {
4687       CStdString strResult;
4688       if (item->GetVideoInfoTag()->m_iSeason == 0) // prefix episode with 'S'
4689         strResult = StringUtils::Format("S%d",item->GetVideoInfoTag()->m_iEpisode);
4690       else
4691         strResult = StringUtils::Format("%d",item->GetVideoInfoTag()->m_iEpisode);
4692       return strResult;
4693     }
4694     break;
4695   case LISTITEM_SEASON:
4696     if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iSeason > 0)
4697     {
4698       return StringUtils::Format("%d",item->GetVideoInfoTag()->m_iSeason);;
4699     }
4700     break;
4701   case LISTITEM_TVSHOW:
4702     if (item->HasVideoInfoTag())
4703       return item->GetVideoInfoTag()->m_strShowTitle;
4704     break;
4705   case LISTITEM_COMMENT:
4706     if (item->HasPVRTimerInfoTag())
4707       return item->GetPVRTimerInfoTag()->GetStatus();
4708     if (item->HasMusicInfoTag())
4709       return item->GetMusicInfoTag()->GetComment();
4710     break;
4711   case LISTITEM_ACTUAL_ICON:
4712     return item->GetIconImage();
4713   case LISTITEM_ICON:
4714     {
4715       CStdString strThumb = item->GetArt("thumb");
4716       if (strThumb.empty())
4717         strThumb = item->GetIconImage();
4718       if (fallback)
4719         *fallback = item->GetIconImage();
4720       return strThumb;
4721     }
4722   case LISTITEM_OVERLAY:
4723     return item->GetOverlayImage();
4724   case LISTITEM_THUMB:
4725     return item->GetArt("thumb");
4726   case LISTITEM_FOLDERPATH:
4727     return CURL(item->GetPath()).GetWithoutUserDetails();
4728   case LISTITEM_FOLDERNAME:
4729   case LISTITEM_PATH:
4730     {
4731       CStdString path;
4732       if (item->IsMusicDb() && item->HasMusicInfoTag())
4733         path = URIUtils::GetDirectory(item->GetMusicInfoTag()->GetURL());
4734       else if (item->IsVideoDb() && item->HasVideoInfoTag())
4735       {
4736         if( item->m_bIsFolder )
4737           path = item->GetVideoInfoTag()->m_strPath;
4738         else
4739           URIUtils::GetParentPath(item->GetVideoInfoTag()->m_strFileNameAndPath, path);
4740       }
4741       else
4742         URIUtils::GetParentPath(item->GetPath(), path);
4743       path = CURL(path).GetWithoutUserDetails();
4744       if (info==LISTITEM_FOLDERNAME)
4745       {
4746         URIUtils::RemoveSlashAtEnd(path);
4747         path=URIUtils::GetFileName(path);
4748       }
4749       return path;
4750     }
4751   case LISTITEM_FILENAME_AND_PATH:
4752     {
4753       CStdString path;
4754       if (item->IsMusicDb() && item->HasMusicInfoTag())
4755         path = item->GetMusicInfoTag()->GetURL();
4756       else if (item->IsVideoDb() && item->HasVideoInfoTag())
4757         path = item->GetVideoInfoTag()->m_strFileNameAndPath;
4758       else
4759         path = item->GetPath();
4760       path = CURL(path).GetWithoutUserDetails();
4761       return path;
4762     }
4763   case LISTITEM_PICTURE_PATH:
4764     if (item->IsPicture() && (!item->IsZIP() || item->IsRAR() || item->IsCBZ() || item->IsCBR()))
4765       return item->GetPath();
4766     break;
4767   case LISTITEM_STUDIO:
4768     if (item->HasVideoInfoTag())
4769       return StringUtils::Join(item->GetVideoInfoTag()->m_studio, g_advancedSettings.m_videoItemSeparator);
4770     break;
4771   case LISTITEM_COUNTRY:
4772     if (item->HasVideoInfoTag())
4773       return StringUtils::Join(item->GetVideoInfoTag()->m_country, g_advancedSettings.m_videoItemSeparator);
4774     break;
4775   case LISTITEM_MPAA:
4776     if (item->HasVideoInfoTag())
4777       return item->GetVideoInfoTag()->m_strMPAARating;
4778     break;
4779   case LISTITEM_CAST:
4780     if (item->HasVideoInfoTag())
4781       return item->GetVideoInfoTag()->GetCast();
4782     break;
4783   case LISTITEM_CAST_AND_ROLE:
4784     if (item->HasVideoInfoTag())
4785       return item->GetVideoInfoTag()->GetCast(true);
4786     break;
4787   case LISTITEM_WRITER:
4788     if (item->HasVideoInfoTag())
4789       return StringUtils::Join(item->GetVideoInfoTag()->m_writingCredits, g_advancedSettings.m_videoItemSeparator);
4790     break;
4791   case LISTITEM_TAGLINE:
4792     if (item->HasVideoInfoTag())
4793       return item->GetVideoInfoTag()->m_strTagLine;
4794     break;
4795   case LISTITEM_TRAILER:
4796     if (item->HasVideoInfoTag())
4797       return item->GetVideoInfoTag()->m_strTrailer;
4798     break;
4799   case LISTITEM_TOP250:
4800     if (item->HasVideoInfoTag())
4801     {
4802       CStdString strResult;
4803       if (item->GetVideoInfoTag()->m_iTop250 > 0)
4804         strResult = StringUtils::Format("%i",item->GetVideoInfoTag()->m_iTop250);
4805       return strResult;
4806     }
4807     break;
4808   case LISTITEM_SORT_LETTER:
4809     {
4810       CStdString letter;
4811       std::wstring character(1, item->GetSortLabel()[0]);
4812       StringUtils::ToUpper(character);
4813       g_charsetConverter.wToUTF8(character, letter);
4814       return letter;
4815     }
4816     break;
4817   case LISTITEM_VIDEO_CODEC:
4818     if (item->HasVideoInfoTag())
4819       return item->GetVideoInfoTag()->m_streamDetails.GetVideoCodec();
4820     break;
4821   case LISTITEM_VIDEO_RESOLUTION:
4822     if (item->HasVideoInfoTag())
4823       return CStreamDetails::VideoDimsToResolutionDescription(item->GetVideoInfoTag()->m_streamDetails.GetVideoWidth(), item->GetVideoInfoTag()->m_streamDetails.GetVideoHeight());
4824     break;
4825   case LISTITEM_VIDEO_ASPECT:
4826     if (item->HasVideoInfoTag())
4827       return CStreamDetails::VideoAspectToAspectDescription(item->GetVideoInfoTag()->m_streamDetails.GetVideoAspect());
4828     break;
4829   case LISTITEM_AUDIO_CODEC:
4830     if (item->HasVideoInfoTag())
4831     {
4832       return item->GetVideoInfoTag()->m_streamDetails.GetAudioCodec();
4833     }
4834     break;
4835   case LISTITEM_AUDIO_CHANNELS:
4836     if (item->HasVideoInfoTag())
4837     {
4838       CStdString strResult;
4839       int iChannels = item->GetVideoInfoTag()->m_streamDetails.GetAudioChannels();
4840       if (iChannels > -1)
4841         strResult = StringUtils::Format("%i", iChannels);
4842       return strResult;
4843     }
4844     break;
4845   case LISTITEM_AUDIO_LANGUAGE:
4846     if (item->HasVideoInfoTag())
4847       return item->GetVideoInfoTag()->m_streamDetails.GetAudioLanguage();
4848     break;
4849   case LISTITEM_SUBTITLE_LANGUAGE:
4850     if (item->HasVideoInfoTag())
4851       return item->GetVideoInfoTag()->m_streamDetails.GetSubtitleLanguage();
4852     break;
4853   case LISTITEM_STARTTIME:
4854     if (item->HasPVRChannelInfoTag())
4855     {
4856       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4857       CEpgInfoTag tag;
4858       if (channel && channel->GetEPGNow(tag))
4859         return tag.StartAsLocalTime().GetAsLocalizedTime("", false);
4860       return CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
4861     }
4862     if (item->HasEPGInfoTag())
4863       return item->GetEPGInfoTag()->StartAsLocalTime().GetAsLocalizedTime("", false);
4864     if (item->HasPVRTimerInfoTag())
4865       return item->GetPVRTimerInfoTag()->StartAsLocalTime().GetAsLocalizedTime("", false);
4866     if (item->HasPVRRecordingInfoTag())
4867       return item->GetPVRRecordingInfoTag()->RecordingTimeAsLocalTime().GetAsLocalizedTime("", false);
4868     if (item->m_dateTime.IsValid())
4869       return item->m_dateTime.GetAsLocalizedTime("", false);
4870     break;
4871   case LISTITEM_ENDTIME:
4872     if (item->HasPVRChannelInfoTag())
4873     {
4874       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4875       CEpgInfoTag tag;
4876       if (channel && channel->GetEPGNow(tag))
4877         return tag.EndAsLocalTime().GetAsLocalizedTime("", false);
4878       return CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
4879     }
4880     if (item->HasEPGInfoTag())
4881       return item->GetEPGInfoTag()->EndAsLocalTime().GetAsLocalizedTime("", false);
4882     if (item->HasPVRTimerInfoTag())
4883       return item->GetPVRTimerInfoTag()->EndAsLocalTime().GetAsLocalizedTime("", false);
4884     break;
4885   case LISTITEM_STARTDATE:
4886     if (item->HasPVRChannelInfoTag())
4887     {
4888       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4889       CEpgInfoTag tag;
4890       if (channel && channel->GetEPGNow(tag))
4891         return tag.StartAsLocalTime().GetAsLocalizedDate(true);
4892       return CDateTime::GetCurrentDateTime().GetAsLocalizedDate(true);
4893     }
4894     if (item->HasEPGInfoTag())
4895       return item->GetEPGInfoTag()->StartAsLocalTime().GetAsLocalizedDate(true);
4896     if (item->HasPVRTimerInfoTag())
4897       return item->GetPVRTimerInfoTag()->StartAsLocalTime().GetAsLocalizedDate(true);
4898     if (item->HasPVRRecordingInfoTag())
4899       return item->GetPVRRecordingInfoTag()->RecordingTimeAsLocalTime().GetAsLocalizedDate(true);
4900     if (item->m_dateTime.IsValid())
4901       return item->m_dateTime.GetAsLocalizedDate(true);
4902     break;
4903   case LISTITEM_ENDDATE:
4904     if (item->HasPVRChannelInfoTag())
4905     {
4906       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4907       CEpgInfoTag tag;
4908       if (channel && channel->GetEPGNow(tag))
4909         return tag.EndAsLocalTime().GetAsLocalizedDate(true);
4910       return CDateTime::GetCurrentDateTime().GetAsLocalizedDate(true);
4911     }
4912     if (item->HasEPGInfoTag())
4913       return item->GetEPGInfoTag()->EndAsLocalTime().GetAsLocalizedDate(true);
4914     if (item->HasPVRTimerInfoTag())
4915       return item->GetPVRTimerInfoTag()->EndAsLocalTime().GetAsLocalizedDate(true);
4916     break;
4917   case LISTITEM_CHANNEL_NUMBER:
4918     {
4919       CStdString number;
4920       if (item->HasPVRChannelInfoTag())
4921         number = StringUtils::Format("%i", item->GetPVRChannelInfoTag()->ChannelNumber());
4922       if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->HasPVRChannel())
4923         number = StringUtils::Format("%i", item->GetEPGInfoTag()->PVRChannelNumber());
4924       if (item->HasPVRTimerInfoTag())
4925         number = StringUtils::Format("%i", item->GetPVRTimerInfoTag()->ChannelNumber());
4926
4927       return number;
4928     }
4929     break;
4930   case LISTITEM_CHANNEL_NAME:
4931     if (item->HasPVRChannelInfoTag())
4932       return item->GetPVRChannelInfoTag()->ChannelName();
4933     if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->HasPVRChannel())
4934       return item->GetEPGInfoTag()->PVRChannelName();
4935     if (item->HasPVRRecordingInfoTag())
4936       return item->GetPVRRecordingInfoTag()->m_strChannelName;
4937     if (item->HasPVRTimerInfoTag())
4938       return item->GetPVRTimerInfoTag()->ChannelName();
4939     break;
4940   case LISTITEM_NEXT_STARTTIME:
4941     {
4942       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4943       CEpgInfoTag tag;
4944       if (channel && channel->GetEPGNext(tag))
4945         return tag.StartAsLocalTime().GetAsLocalizedTime("", false);
4946     }
4947     return CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
4948   case LISTITEM_NEXT_ENDTIME:
4949     {
4950       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4951       CEpgInfoTag tag;
4952       if (channel && channel->GetEPGNext(tag))
4953         return tag.EndAsLocalTime().GetAsLocalizedTime("", false);
4954     }
4955     return CDateTime::GetCurrentDateTime().GetAsLocalizedTime("", false);
4956   case LISTITEM_NEXT_STARTDATE:
4957     {
4958       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4959       CEpgInfoTag tag;
4960       if (channel && channel->GetEPGNext(tag))
4961         return tag.StartAsLocalTime().GetAsLocalizedDate(true);
4962     }
4963     return CDateTime::GetCurrentDateTime().GetAsLocalizedDate(true);
4964   case LISTITEM_NEXT_ENDDATE:
4965     {
4966       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4967       CEpgInfoTag tag;
4968       if (channel && channel->GetEPGNext(tag))
4969         return tag.EndAsLocalTime().GetAsLocalizedDate(true);
4970     }
4971     return CDateTime::GetCurrentDateTime().GetAsLocalizedDate(true);
4972   case LISTITEM_NEXT_PLOT:
4973     {
4974       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4975       CEpgInfoTag tag;
4976       if (channel && channel->GetEPGNext(tag))
4977         return tag.Plot();
4978     }
4979     return StringUtils::EmptyString;
4980   case LISTITEM_NEXT_PLOT_OUTLINE:
4981     {
4982       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4983       CEpgInfoTag tag;
4984       if (channel && channel->GetEPGNext(tag))
4985         return tag.PlotOutline();
4986     }
4987     return StringUtils::EmptyString;
4988   case LISTITEM_NEXT_DURATION:
4989     {
4990       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4991       CEpgInfoTag tag;
4992       if (channel && channel->GetEPGNext(tag))
4993         return StringUtils::SecondsToTimeString(tag.GetDuration());
4994     }
4995     return StringUtils::EmptyString;
4996   case LISTITEM_NEXT_GENRE:
4997     {
4998       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
4999       CEpgInfoTag tag;
5000       if (channel && channel->GetEPGNext(tag))
5001         return StringUtils::Join(tag.Genre(), g_advancedSettings.m_videoItemSeparator);
5002     }
5003     return StringUtils::EmptyString;
5004   case LISTITEM_NEXT_TITLE:
5005     {
5006       const CPVRChannel *channel = item->HasPVRChannelInfoTag() ? item->GetPVRChannelInfoTag() : NULL;
5007       CEpgInfoTag tag;
5008       if (channel && channel->GetEPGNext(tag))
5009         return tag.Title();
5010     }
5011     return StringUtils::EmptyString;
5012   case LISTITEM_PARENTALRATING:
5013     {
5014       CStdString rating;
5015       if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->ParentalRating() > 0)
5016         rating = StringUtils::Format("%i", item->GetEPGInfoTag()->ParentalRating());
5017       return rating;
5018     }
5019     break;
5020   case LISTITEM_PERCENT_PLAYED:
5021     {
5022       int val;
5023       if (GetItemInt(val, item, info))
5024       {
5025         return StringUtils::Format("%d", val);;
5026       }
5027       break;
5028     }
5029   case LISTITEM_DATE_ADDED:
5030     if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_dateAdded.IsValid())
5031       return item->GetVideoInfoTag()->m_dateAdded.GetAsLocalizedDate();
5032     break;
5033   case LISTITEM_DBTYPE:
5034     if (item->HasVideoInfoTag())
5035       return item->GetVideoInfoTag()->m_type;
5036     break;
5037   case LISTITEM_DBID:
5038     if (item->HasVideoInfoTag())
5039       {
5040         return StringUtils::Format("%i", item->GetVideoInfoTag()->m_iDbId);;
5041       }
5042     if (item->HasMusicInfoTag())
5043       {
5044         return StringUtils::Format("%i", item->GetMusicInfoTag()->GetDatabaseId());;
5045       }
5046     break;
5047   case LISTITEM_STEREOSCOPIC_MODE:
5048     {
5049       std::string stereoMode = item->GetProperty("stereomode").asString();
5050       if (stereoMode.empty() && item->HasVideoInfoTag())
5051         stereoMode = CStereoscopicsManager::Get().NormalizeStereoMode(item->GetVideoInfoTag()->m_streamDetails.GetStereoMode());
5052       return stereoMode;
5053     }
5054   }
5055   return "";
5056 }
5057
5058 CStdString CGUIInfoManager::GetItemImage(const CFileItem *item, int info, CStdString *fallback)
5059 {
5060   if (info >= CONDITIONAL_LABEL_START && info <= CONDITIONAL_LABEL_END)
5061     return GetSkinVariableString(info, true, item);
5062
5063   switch (info)
5064   {
5065   case LISTITEM_RATING:  // old song rating format
5066     {
5067       if (item->HasMusicInfoTag())
5068       {
5069         return StringUtils::Format("songrating%c.png", item->GetMusicInfoTag()->GetRating());
5070       }
5071     }
5072     break;
5073   case LISTITEM_STAR_RATING:
5074     {
5075       CStdString rating;
5076       if (item->HasVideoInfoTag())
5077       { // rating for videos is assumed 0..10, so convert to 0..5
5078         rating = StringUtils::Format("rating%d.png", (long)((item->GetVideoInfoTag()->m_fRating * 0.5f) + 0.5f));
5079       }
5080       else if (item->HasMusicInfoTag())
5081       { // song rating.
5082         rating = StringUtils::Format("rating%c.png", item->GetMusicInfoTag()->GetRating());
5083       }
5084       return rating;
5085     }
5086     break;
5087   }  /* switch (info) */
5088
5089   return GetItemLabel(item, info, fallback);
5090 }
5091
5092 bool CGUIInfoManager::GetItemBool(const CGUIListItem *item, int condition) const
5093 {
5094   if (!item) return false;
5095   if (condition >= LISTITEM_PROPERTY_START && condition - LISTITEM_PROPERTY_START < (int)m_listitemProperties.size())
5096   { // grab the property
5097     CStdString property = m_listitemProperties[condition - LISTITEM_PROPERTY_START];
5098     return item->GetProperty(property).asBoolean();
5099   }
5100   else if (condition == LISTITEM_ISPLAYING)
5101   {
5102     if (item->HasProperty("playlistposition"))
5103       return (int)item->GetProperty("playlisttype").asInteger() == g_playlistPlayer.GetCurrentPlaylist() && (int)item->GetProperty("playlistposition").asInteger() == g_playlistPlayer.GetCurrentSong();
5104     else if (item->IsFileItem() && !m_currentFile->GetPath().empty())
5105     {
5106       if (!g_application.m_strPlayListFile.empty())
5107       {
5108         //playlist file that is currently playing or the playlistitem that is currently playing.
5109         return g_application.m_strPlayListFile.Equals(((const CFileItem *)item)->GetPath()) || m_currentFile->IsSamePath((const CFileItem *)item);
5110       }
5111       return m_currentFile->IsSamePath((const CFileItem *)item);
5112     }
5113   }
5114   else if (condition == LISTITEM_ISSELECTED)
5115     return item->IsSelected();
5116   else if (condition == LISTITEM_IS_FOLDER)
5117     return item->m_bIsFolder;
5118   else if (condition == LISTITEM_IS_RESUMABLE)
5119   {
5120     if (item->IsFileItem())
5121     {
5122       if (((const CFileItem *)item)->HasVideoInfoTag())
5123         return ((const CFileItem *)item)->GetVideoInfoTag()->m_resumePoint.timeInSeconds > 0;
5124       else if (((const CFileItem *)item)->HasPVRRecordingInfoTag())
5125         return ((const CFileItem *)item)->GetPVRRecordingInfoTag()->m_resumePoint.timeInSeconds > 0;
5126     }
5127   }
5128   else if (item->IsFileItem())
5129   {
5130     const CFileItem *pItem = (const CFileItem *)item;
5131     if (condition == LISTITEM_ISRECORDING)
5132     {
5133       if (!g_PVRManager.IsStarted())
5134         return false;
5135
5136       if (pItem->HasPVRChannelInfoTag())
5137       {
5138         return pItem->GetPVRChannelInfoTag()->IsRecording();
5139       }
5140       else if (pItem->HasPVRTimerInfoTag())
5141       {
5142         const CPVRTimerInfoTag *timer = pItem->GetPVRTimerInfoTag();
5143         if (timer)
5144           return timer->IsRecording();
5145       }
5146       else if (pItem->HasEPGInfoTag())
5147       {
5148         CFileItemPtr timer = g_PVRTimers->GetTimerForEpgTag(pItem);
5149         if (timer && timer->HasPVRTimerInfoTag())
5150           return timer->GetPVRTimerInfoTag()->IsRecording();
5151       }
5152     }
5153     else if (condition == LISTITEM_HASTIMER)
5154     {
5155       if (pItem->HasEPGInfoTag())
5156       {
5157         CFileItemPtr timer = g_PVRTimers->GetTimerForEpgTag(pItem);
5158         if (timer && timer->HasPVRTimerInfoTag())
5159           return timer->GetPVRTimerInfoTag()->IsActive();
5160       }
5161     }
5162     else if (condition == LISTITEM_HAS_EPG)
5163     {
5164       if (pItem->HasPVRChannelInfoTag())
5165       {
5166         CEpgInfoTag epgTag;
5167         return pItem->GetPVRChannelInfoTag()->GetEPGNow(epgTag);
5168       }
5169       else
5170       {
5171         return pItem->HasEPGInfoTag();
5172       }
5173     }
5174     else if (condition == LISTITEM_ISENCRYPTED)
5175     {
5176       if (pItem->HasPVRChannelInfoTag())
5177       {
5178         return pItem->GetPVRChannelInfoTag()->IsEncrypted();
5179       }
5180       else if (pItem->HasEPGInfoTag() && pItem->GetEPGInfoTag()->HasPVRChannel())
5181       {
5182         return pItem->GetEPGInfoTag()->ChannelTag()->IsEncrypted();
5183       }
5184     }
5185     else if (condition == LISTITEM_IS_STEREOSCOPIC)
5186     {
5187       std::string stereoMode = pItem->GetProperty("stereomode").asString();
5188       if (stereoMode.empty() && pItem->HasVideoInfoTag())
5189           stereoMode = CStereoscopicsManager::Get().NormalizeStereoMode(pItem->GetVideoInfoTag()->m_streamDetails.GetStereoMode());
5190       if (!stereoMode.empty() && stereoMode != "mono")
5191         return true;
5192     }
5193   }
5194
5195   return false;
5196 }
5197
5198 void CGUIInfoManager::ResetCache()
5199 {
5200   // reset any animation triggers as well
5201   m_containerMoves.clear();
5202   // mark our infobools as dirty
5203   CSingleLock lock(m_critInfo);
5204   for (vector<InfoPtr>::iterator i = m_bools.begin(); i != m_bools.end(); ++i)
5205     (*i)->SetDirty();
5206 }
5207
5208 // Called from tuxbox service thread to update current status
5209 void CGUIInfoManager::UpdateFromTuxBox()
5210 {
5211   if(g_tuxbox.vVideoSubChannel.mode)
5212     m_currentFile->GetVideoInfoTag()->m_strTitle = g_tuxbox.vVideoSubChannel.current_name;
5213
5214   // Set m_currentMovieDuration
5215   if(!g_tuxbox.sCurSrvData.current_event_duration.empty() &&
5216     !g_tuxbox.sCurSrvData.next_event_description.empty() &&
5217     !g_tuxbox.sCurSrvData.current_event_duration.Equals("-") &&
5218     !g_tuxbox.sCurSrvData.next_event_description.Equals("-"))
5219   {
5220     StringUtils::Replace(g_tuxbox.sCurSrvData.current_event_duration, "(","");
5221     StringUtils::Replace(g_tuxbox.sCurSrvData.current_event_duration, ")","");
5222
5223     m_currentMovieDuration = StringUtils::Format("%s: %s %s (%s - %s)",
5224                                                  g_localizeStrings.Get(180).c_str(),
5225                                                  g_tuxbox.sCurSrvData.current_event_duration.c_str(),
5226                                                  g_localizeStrings.Get(12391).c_str(),
5227                                                  g_tuxbox.sCurSrvData.current_event_time.c_str(),
5228                                                  g_tuxbox.sCurSrvData.next_event_time.c_str());
5229   }
5230
5231   //Set strVideoGenre
5232   if (!g_tuxbox.sCurSrvData.current_event_description.empty() &&
5233     !g_tuxbox.sCurSrvData.next_event_description.empty() &&
5234     !g_tuxbox.sCurSrvData.current_event_description.Equals("-") &&
5235     !g_tuxbox.sCurSrvData.next_event_description.Equals("-"))
5236   {
5237     CStdString genre = StringUtils::Format("%s %s  -  (%s: %s)",
5238                                            g_localizeStrings.Get(143).c_str(),
5239                                            g_tuxbox.sCurSrvData.current_event_description.c_str(),
5240                                            g_localizeStrings.Get(209).c_str(),
5241                                            g_tuxbox.sCurSrvData.next_event_description.c_str());
5242     m_currentFile->GetVideoInfoTag()->m_genre = StringUtils::Split(genre, g_advancedSettings.m_videoItemSeparator);
5243   }
5244
5245   //Set m_currentMovie.m_director
5246   if (!g_tuxbox.sCurSrvData.current_event_details.Equals("-") &&
5247     !g_tuxbox.sCurSrvData.current_event_details.empty())
5248   {
5249     m_currentFile->GetVideoInfoTag()->m_director = StringUtils::Split(g_tuxbox.sCurSrvData.current_event_details, g_advancedSettings.m_videoItemSeparator);
5250   }
5251 }
5252
5253 CStdString CGUIInfoManager::GetPictureLabel(int info)
5254 {
5255   if (info == SLIDE_FILE_NAME)
5256     return GetItemLabel(m_currentSlide, LISTITEM_FILENAME);
5257   else if (info == SLIDE_FILE_PATH)
5258   {
5259     CStdString path = URIUtils::GetDirectory(m_currentSlide->GetPath());
5260     return CURL(path).GetWithoutUserDetails();
5261   }
5262   else if (info == SLIDE_FILE_SIZE)
5263     return GetItemLabel(m_currentSlide, LISTITEM_SIZE);
5264   else if (info == SLIDE_FILE_DATE)
5265     return GetItemLabel(m_currentSlide, LISTITEM_DATE);
5266   else if (info == SLIDE_INDEX)
5267   {
5268     CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
5269     if (slideshow && slideshow->NumSlides())
5270     {
5271       return StringUtils::Format("%d/%d", slideshow->CurrentSlide(), slideshow->NumSlides());
5272     }
5273   }
5274   if (m_currentSlide->HasPictureInfoTag())
5275     return m_currentSlide->GetPictureInfoTag()->GetInfo(info);
5276   return "";
5277 }
5278
5279 void CGUIInfoManager::SetCurrentSlide(CFileItem &item)
5280 {
5281   if (m_currentSlide->GetPath() != item.GetPath())
5282   {
5283     if (!item.GetPictureInfoTag()->Loaded()) // If picture metadata has not been loaded yet, load it now
5284       item.GetPictureInfoTag()->Load(item.GetPath());
5285     *m_currentSlide = item;
5286   }
5287 }
5288
5289 void CGUIInfoManager::ResetCurrentSlide()
5290 {
5291   m_currentSlide->Reset();
5292 }
5293
5294 bool CGUIInfoManager::CheckWindowCondition(CGUIWindow *window, int condition) const
5295 {
5296   // check if it satisfies our condition
5297   if (!window) return false;
5298   if ((condition & WINDOW_CONDITION_HAS_LIST_ITEMS) && !window->HasListItems())
5299     return false;
5300   if ((condition & WINDOW_CONDITION_IS_MEDIA_WINDOW) && !window->IsMediaWindow())
5301     return false;
5302   return true;
5303 }
5304
5305 CGUIWindow *CGUIInfoManager::GetWindowWithCondition(int contextWindow, int condition) const
5306 {
5307   CGUIWindow *window = g_windowManager.GetWindow(contextWindow);
5308   if (CheckWindowCondition(window, condition))
5309     return window;
5310
5311   // try topmost dialog
5312   window = g_windowManager.GetWindow(g_windowManager.GetTopMostModalDialogID());
5313   if (CheckWindowCondition(window, condition))
5314     return window;
5315
5316   // try active window
5317   window = g_windowManager.GetWindow(g_windowManager.GetActiveWindow());
5318   if (CheckWindowCondition(window, condition))
5319     return window;
5320
5321   return NULL;
5322 }
5323
5324 void CGUIInfoManager::SetCurrentVideoTag(const CVideoInfoTag &tag)
5325 {
5326   *m_currentFile->GetVideoInfoTag() = tag;
5327   m_currentFile->m_lStartOffset = 0;
5328 }
5329
5330 void CGUIInfoManager::SetCurrentSongTag(const MUSIC_INFO::CMusicInfoTag &tag)
5331 {
5332   //CLog::Log(LOGDEBUG, "Asked to SetCurrentTag");
5333   *m_currentFile->GetMusicInfoTag() = tag;
5334   m_currentFile->m_lStartOffset = 0;
5335 }
5336
5337 const CFileItem& CGUIInfoManager::GetCurrentSlide() const
5338 {
5339   return *m_currentSlide;
5340 }
5341
5342 const MUSIC_INFO::CMusicInfoTag* CGUIInfoManager::GetCurrentSongTag() const
5343 {
5344   if (m_currentFile->HasMusicInfoTag())
5345     return m_currentFile->GetMusicInfoTag();
5346
5347   return NULL;
5348 }
5349
5350 const CVideoInfoTag* CGUIInfoManager::GetCurrentMovieTag() const
5351 {
5352   if (m_currentFile->HasVideoInfoTag())
5353     return m_currentFile->GetVideoInfoTag();
5354
5355   return NULL;
5356 }
5357
5358 void GUIInfo::SetInfoFlag(uint32_t flag)
5359 {
5360   assert(flag >= (1 << 24));
5361   m_data1 |= flag;
5362 }
5363
5364 uint32_t GUIInfo::GetInfoFlag() const
5365 {
5366   // we strip out the bottom 24 bits, where we keep data
5367   // and return the flag only
5368   return m_data1 & 0xff000000;
5369 }
5370
5371 uint32_t GUIInfo::GetData1() const
5372 {
5373   // we strip out the top 8 bits, where we keep flags
5374   // and return the unflagged data
5375   return m_data1 & ((1 << 24) -1);
5376 }
5377
5378 int GUIInfo::GetData2() const
5379 {
5380   return m_data2;
5381 }
5382
5383 void CGUIInfoManager::SetLibraryBool(int condition, bool value)
5384 {
5385   switch (condition)
5386   {
5387     case LIBRARY_HAS_MUSIC:
5388       m_libraryHasMusic = value ? 1 : 0;
5389       break;
5390     case LIBRARY_HAS_MOVIES:
5391       m_libraryHasMovies = value ? 1 : 0;
5392       break;
5393     case LIBRARY_HAS_MOVIE_SETS:
5394       m_libraryHasMovieSets = value ? 1 : 0;
5395       break;
5396     case LIBRARY_HAS_TVSHOWS:
5397       m_libraryHasTVShows = value ? 1 : 0;
5398       break;
5399     case LIBRARY_HAS_MUSICVIDEOS:
5400       m_libraryHasMusicVideos = value ? 1 : 0;
5401       break;
5402     default:
5403       break;
5404   }
5405 }
5406
5407 void CGUIInfoManager::ResetLibraryBools()
5408 {
5409   m_libraryHasMusic = -1;
5410   m_libraryHasMovies = -1;
5411   m_libraryHasTVShows = -1;
5412   m_libraryHasMusicVideos = -1;
5413   m_libraryHasMovieSets = -1;
5414 }
5415
5416 bool CGUIInfoManager::GetLibraryBool(int condition)
5417 {
5418   if (condition == LIBRARY_HAS_MUSIC)
5419   {
5420     if (m_libraryHasMusic < 0)
5421     { // query
5422       CMusicDatabase db;
5423       if (db.Open())
5424       {
5425         m_libraryHasMusic = (db.GetSongsCount() > 0) ? 1 : 0;
5426         db.Close();
5427       }
5428     }
5429     return m_libraryHasMusic > 0;
5430   }
5431   else if (condition == LIBRARY_HAS_MOVIES)
5432   {
5433     if (m_libraryHasMovies < 0)
5434     {
5435       CVideoDatabase db;
5436       if (db.Open())
5437       {
5438         m_libraryHasMovies = db.HasContent(VIDEODB_CONTENT_MOVIES) ? 1 : 0;
5439         db.Close();
5440       }
5441     }
5442     return m_libraryHasMovies > 0;
5443   }
5444   else if (condition == LIBRARY_HAS_MOVIE_SETS)
5445   {
5446     if (m_libraryHasMovieSets < 0)
5447     {
5448       CVideoDatabase db;
5449       if (db.Open())
5450       {
5451         m_libraryHasMovieSets = db.HasSets() ? 1 : 0;
5452         db.Close();
5453       }
5454     }
5455     return m_libraryHasMovieSets > 0;
5456   }
5457   else if (condition == LIBRARY_HAS_TVSHOWS)
5458   {
5459     if (m_libraryHasTVShows < 0)
5460     {
5461       CVideoDatabase db;
5462       if (db.Open())
5463       {
5464         m_libraryHasTVShows = db.HasContent(VIDEODB_CONTENT_TVSHOWS) ? 1 : 0;
5465         db.Close();
5466       }
5467     }
5468     return m_libraryHasTVShows > 0;
5469   }
5470   else if (condition == LIBRARY_HAS_MUSICVIDEOS)
5471   {
5472     if (m_libraryHasMusicVideos < 0)
5473     {
5474       CVideoDatabase db;
5475       if (db.Open())
5476       {
5477         m_libraryHasMusicVideos = db.HasContent(VIDEODB_CONTENT_MUSICVIDEOS) ? 1 : 0;
5478         db.Close();
5479       }
5480     }
5481     return m_libraryHasMusicVideos > 0;
5482   }
5483   else if (condition == LIBRARY_HAS_VIDEO)
5484   {
5485     return (GetLibraryBool(LIBRARY_HAS_MOVIES) ||
5486             GetLibraryBool(LIBRARY_HAS_TVSHOWS) ||
5487             GetLibraryBool(LIBRARY_HAS_MUSICVIDEOS));
5488   }
5489   return false;
5490 }
5491
5492 int CGUIInfoManager::RegisterSkinVariableString(const CSkinVariableString* info)
5493 {
5494   if (!info)
5495     return 0;
5496
5497   CSingleLock lock(m_critInfo);
5498   m_skinVariableStrings.push_back(*info);
5499   delete info;
5500   return CONDITIONAL_LABEL_START + m_skinVariableStrings.size() - 1;
5501 }
5502
5503 int CGUIInfoManager::TranslateSkinVariableString(const CStdString& name, int context)
5504 {
5505   for (vector<CSkinVariableString>::const_iterator it = m_skinVariableStrings.begin();
5506        it != m_skinVariableStrings.end(); ++it)
5507   {
5508     if (it->GetName().Equals(name) && it->GetContext() == context)
5509       return it - m_skinVariableStrings.begin() + CONDITIONAL_LABEL_START;
5510   }
5511   return 0;
5512 }
5513
5514 CStdString CGUIInfoManager::GetSkinVariableString(int info,
5515                                                   bool preferImage /*= false*/,
5516                                                   const CGUIListItem *item /*= NULL*/)
5517 {
5518   info -= CONDITIONAL_LABEL_START;
5519   if (info >= 0 && info < (int)m_skinVariableStrings.size())
5520     return m_skinVariableStrings[info].GetValue(preferImage, item);
5521
5522   return "";
5523 }
5524
5525 bool CGUIInfoManager::ConditionsChangedValues(const std::map<INFO::InfoPtr, bool>& map)
5526 {
5527   for (std::map<INFO::InfoPtr, bool>::const_iterator it = map.begin() ; it != map.end() ; it++)
5528   {
5529     if (it->first->Get() != it->second)
5530       return true;
5531   }
5532   return false;
5533 }
5534
5535 bool CGUIInfoManager::GetEpgInfoTag(CEpgInfoTag& tag) const
5536 {
5537   if (m_currentFile->HasEPGInfoTag())
5538   {
5539     CEpgInfoTag* currentTag =  m_currentFile->GetEPGInfoTag();
5540     while (currentTag && !currentTag->IsActive())
5541       currentTag = currentTag->GetNextEvent().get();
5542     if (currentTag)
5543     {
5544       tag = *currentTag;
5545       return true;
5546     }
5547   }
5548   return false;
5549 }