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