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