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