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