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