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