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