1 /*
2 * Copyright (C) 2012-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9 #include "guilib/guiinfo/MusicGUIInfo.h"
10
11 #include "Application.h"
12 #include "FileItem.h"
13 #include "PartyModeManager.h"
14 #include "PlayListPlayer.h"
15 #include "ServiceBroker.h"
16 #include "URL.h"
17 #include "Util.h"
18 #include "guilib/LocalizeStrings.h"
19 #include "guilib/guiinfo/GUIInfo.h"
20 #include "guilib/guiinfo/GUIInfoHelper.h"
21 #include "guilib/guiinfo/GUIInfoLabels.h"
22 #include "music/MusicInfoLoader.h"
23 #include "music/MusicThumbLoader.h"
24 #include "music/tags/MusicInfoTag.h"
25 #include "playlists/PlayList.h"
26 #include "settings/AdvancedSettings.h"
27 #include "settings/SettingsComponent.h"
28 #include "utils/URIUtils.h"
29 #include "utils/log.h"
30
31 using namespace KODI::GUILIB;
32 using namespace KODI::GUILIB::GUIINFO;
33 using namespace MUSIC_INFO;
34
InitCurrentItem(CFileItem * item)35 bool CMusicGUIInfo::InitCurrentItem(CFileItem *item)
36 {
37 if (item && (item->IsAudio() || (item->IsInternetStream() && g_application.GetAppPlayer().IsPlayingAudio())))
38 {
39 CLog::Log(LOGDEBUG,"CMusicGUIInfo::InitCurrentItem(%s)", item->GetPath().c_str());
40
41 item->LoadMusicTag();
42
43 CMusicInfoTag* tag = item->GetMusicInfoTag(); // creates item if not yet set, so no nullptr checks needed
44 tag->SetLoaded(true);
45
46 // find a thumb for this file.
47 if (item->IsInternetStream() && !item->IsMusicDb())
48 {
49 if (!g_application.m_strPlayListFile.empty())
50 {
51 CLog::Log(LOGDEBUG,"Streaming media detected... using %s to find a thumb", g_application.m_strPlayListFile.c_str());
52 CFileItem streamingItem(g_application.m_strPlayListFile,false);
53
54 CMusicThumbLoader loader;
55 loader.FillThumb(streamingItem);
56 if (streamingItem.HasArt("thumb"))
57 item->SetArt("thumb", streamingItem.GetArt("thumb"));
58 }
59 }
60 else
61 {
62 CMusicThumbLoader loader;
63 loader.LoadItem(item);
64 }
65
66 CMusicInfoLoader::LoadAdditionalTagInfo(item);
67 return true;
68 }
69 return false;
70 }
71
GetLabel(std::string & value,const CFileItem * item,int contextWindow,const CGUIInfo & info,std::string * fallback) const72 bool CMusicGUIInfo::GetLabel(std::string& value, const CFileItem *item, int contextWindow, const CGUIInfo &info, std::string *fallback) const
73 {
74 // For musicplayer "offset" and "position" info labels check playlist
75 if (info.GetData1() && ((info.m_info >= MUSICPLAYER_OFFSET_POSITION_FIRST &&
76 info.m_info <= MUSICPLAYER_OFFSET_POSITION_LAST) ||
77 (info.m_info >= PLAYER_OFFSET_POSITION_FIRST && info.m_info <= PLAYER_OFFSET_POSITION_LAST)))
78 return GetPlaylistInfo(value, info);
79
80 const CMusicInfoTag* tag = item->GetMusicInfoTag();
81 if (tag)
82 {
83 switch (info.m_info)
84 {
85 /////////////////////////////////////////////////////////////////////////////////////////////
86 // PLAYER_* / MUSICPLAYER_* / LISTITEM_*
87 /////////////////////////////////////////////////////////////////////////////////////////////
88 case PLAYER_PATH:
89 case PLAYER_FILENAME:
90 case PLAYER_FILEPATH:
91 value = tag->GetURL();
92 if (value.empty())
93 value = item->GetPath();
94 value = GUIINFO::GetFileInfoLabelValueFromPath(info.m_info, value);
95 return true;
96 case PLAYER_TITLE:
97 value = tag->GetTitle();
98 return !value.empty();
99 case MUSICPLAYER_TITLE:
100 value = tag->GetTitle();
101 return !value.empty();
102 case LISTITEM_TITLE:
103 value = tag->GetTitle();
104 return true;
105 case MUSICPLAYER_PLAYCOUNT:
106 case LISTITEM_PLAYCOUNT:
107 if (tag->GetPlayCount() > 0)
108 {
109 value = StringUtils::Format("%i", tag->GetPlayCount());
110 return true;
111 }
112 break;
113 case MUSICPLAYER_LASTPLAYED:
114 case LISTITEM_LASTPLAYED:
115 {
116 const CDateTime& dateTime = tag->GetLastPlayed();
117 if (dateTime.IsValid())
118 {
119 value = dateTime.GetAsLocalizedDate();
120 return true;
121 }
122 break;
123 }
124 case MUSICPLAYER_TRACK_NUMBER:
125 case LISTITEM_TRACKNUMBER:
126 if (tag->Loaded() && tag->GetTrackNumber() > 0)
127 {
128 value = StringUtils::Format("%02i", tag->GetTrackNumber());
129 return true;
130 }
131 break;
132 case MUSICPLAYER_DISC_NUMBER:
133 case LISTITEM_DISC_NUMBER:
134 if (tag->GetDiscNumber() > 0)
135 {
136 value = StringUtils::Format("%i", tag->GetDiscNumber());
137 return true;
138 }
139 break;
140 case MUSICPLAYER_TOTALDISCS:
141 case LISTITEM_TOTALDISCS:
142 value = StringUtils::Format("%i", tag->GetTotalDiscs());
143 return true;
144 case MUSICPLAYER_DISC_TITLE:
145 case LISTITEM_DISC_TITLE:
146 value = tag->GetDiscSubtitle();
147 return true;
148 case MUSICPLAYER_ARTIST:
149 case LISTITEM_ARTIST:
150 value = tag->GetArtistString();
151 return true;
152 case MUSICPLAYER_ALBUM_ARTIST:
153 case LISTITEM_ALBUM_ARTIST:
154 value = tag->GetAlbumArtistString();
155 return true;
156 case MUSICPLAYER_CONTRIBUTORS:
157 case LISTITEM_CONTRIBUTORS:
158 if (tag->HasContributors())
159 {
160 value = tag->GetContributorsText();
161 return true;
162 }
163 break;
164 case MUSICPLAYER_CONTRIBUTOR_AND_ROLE:
165 case LISTITEM_CONTRIBUTOR_AND_ROLE:
166 if (tag->HasContributors())
167 {
168 value = tag->GetContributorsAndRolesText();
169 return true;
170 }
171 break;
172 case MUSICPLAYER_ALBUM:
173 case LISTITEM_ALBUM:
174 value = tag->GetAlbum();
175 return true;
176 case MUSICPLAYER_YEAR:
177 case LISTITEM_YEAR:
178 value = tag->GetYearString();
179 return true;
180 case MUSICPLAYER_GENRE:
181 case LISTITEM_GENRE:
182 value = StringUtils::Join(tag->GetGenre(), CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_musicItemSeparator);
183 return true;
184 case MUSICPLAYER_LYRICS:
185 value = tag->GetLyrics();
186 return true;
187 case MUSICPLAYER_RATING:
188 case LISTITEM_RATING:
189 {
190 float rating = tag->GetRating();
191 if (rating > 0.f)
192 {
193 value = StringUtils::FormatNumber(rating);
194 return true;
195 }
196 break;
197 }
198 case MUSICPLAYER_RATING_AND_VOTES:
199 case LISTITEM_RATING_AND_VOTES:
200 {
201 float rating = tag->GetRating();
202 if (rating > 0.f)
203 {
204 int votes = tag->GetVotes();
205 if (votes <= 0)
206 value = StringUtils::FormatNumber(rating);
207 else
208 value = StringUtils::Format(g_localizeStrings.Get(20350).c_str(),
209 StringUtils::FormatNumber(rating).c_str(),
210 StringUtils::FormatNumber(votes).c_str());
211 return true;
212 }
213 break;
214 }
215 case MUSICPLAYER_USER_RATING:
216 case LISTITEM_USER_RATING:
217 if (tag->GetUserrating() > 0)
218 {
219 value = StringUtils::Format("%i", tag->GetUserrating());
220 return true;
221 }
222 break;
223 case MUSICPLAYER_COMMENT:
224 case LISTITEM_COMMENT:
225 value = tag->GetComment();
226 return true;
227 case MUSICPLAYER_MOOD:
228 case LISTITEM_MOOD:
229 value = tag->GetMood();
230 return true;
231 case LISTITEM_DBTYPE:
232 value = tag->GetType();
233 return true;
234 case MUSICPLAYER_DBID:
235 case LISTITEM_DBID:
236 {
237 int dbId = tag->GetDatabaseId();
238 if (dbId > -1)
239 {
240 value = StringUtils::Format("%i", dbId);
241 return true;
242 }
243 break;
244 }
245 case PLAYER_DURATION:
246 if (!g_application.GetAppPlayer().IsPlayingAudio())
247 break;
248 // fall-thru is intended.
249 case MUSICPLAYER_DURATION:
250 case LISTITEM_DURATION:
251 {
252 int iDuration = tag->GetDuration();
253 if (iDuration > 0)
254 {
255 value = StringUtils::SecondsToTimeString(iDuration,
256 static_cast<TIME_FORMAT>(info.m_info == LISTITEM_DURATION
257 ? info.GetData4()
258 : info.GetData1()));
259 return true;
260 }
261 break;
262 }
263 case MUSICPLAYER_BPM:
264 case LISTITEM_BPM:
265 if (tag->GetBPM() > 0)
266 {
267 value = StringUtils::Format("%i", tag->GetBPM());
268 return true;
269 }
270 break;
271 case MUSICPLAYER_STATIONNAME:
272 // This property can be used for example by addons to enforce/override the station name.
273 value = item->GetProperty("StationName").asString();
274 if (value.empty())
275 value = tag->GetStationName();
276 return true;
277
278 /////////////////////////////////////////////////////////////////////////////////////////////
279 // LISTITEM_*
280 /////////////////////////////////////////////////////////////////////////////////////////////
281 case LISTITEM_PROPERTY:
282 if (StringUtils::StartsWithNoCase(info.GetData3(), "Role."))
283 {
284 // "Role.xxxx" properties are held in music tag
285 std::string property = info.GetData3();
286 property.erase(0, 5); //Remove Role.
287 value = tag->GetArtistStringForRole(property);
288 return true;
289 }
290 break;
291 case LISTITEM_VOTES:
292 value = StringUtils::FormatNumber(tag->GetVotes());
293 return true;
294 case MUSICPLAYER_ORIGINALDATE:
295 case LISTITEM_ORIGINALDATE:
296 {
297 value = tag->GetOriginalDate();
298 if (!CServiceBroker::GetSettingsComponent()
299 ->GetAdvancedSettings()
300 ->m_bMusicLibraryUseISODates)
301 value = StringUtils::ISODateToLocalizedDate(value);
302 return true;
303 }
304 case MUSICPLAYER_RELEASEDATE:
305 case LISTITEM_RELEASEDATE:
306 {
307 value = tag->GetReleaseDate();
308 if (!CServiceBroker::GetSettingsComponent()
309 ->GetAdvancedSettings()
310 ->m_bMusicLibraryUseISODates)
311 value = StringUtils::ISODateToLocalizedDate(value);
312 return true;
313 }
314 break;
315 case LISTITEM_BITRATE:
316 {
317 int BitRate = tag->GetBitRate();
318 if (BitRate > 0)
319 {
320 value = StringUtils::Format("%i", BitRate);
321 return true;
322 }
323 break;
324 }
325 case LISTITEM_SAMPLERATE:
326 {
327 int sampleRate = tag->GetSampleRate();
328 if (sampleRate > 0)
329 {
330 value = StringUtils::Format("%.5g", static_cast<double>(sampleRate) / 1000.0);
331 return true;
332 }
333 break;
334 }
335 case LISTITEM_MUSICCHANNELS:
336 {
337 int channels = tag->GetNoOfChannels();
338 if (channels > 0)
339 {
340 value = StringUtils::Format("%i", channels);
341 return true;
342 }
343 break;
344 }
345 case LISTITEM_ALBUMSTATUS:
346 value = tag->GetAlbumReleaseStatus();
347 return true;
348 case LISTITEM_FILENAME:
349 case LISTITEM_FILE_EXTENSION:
350 if (item->IsMusicDb())
351 value = URIUtils::GetFileName(tag->GetURL());
352 else if (item->HasVideoInfoTag()) // special handling for music videos, which have both a videotag and a musictag
353 break;
354 else
355 value = URIUtils::GetFileName(item->GetPath());
356
357 if (info.m_info == LISTITEM_FILE_EXTENSION)
358 {
359 std::string strExtension = URIUtils::GetExtension(value);
360 value = StringUtils::TrimLeft(strExtension, ".");
361 }
362 return true;
363 case LISTITEM_FOLDERNAME:
364 case LISTITEM_PATH:
365 if (item->IsMusicDb())
366 value = URIUtils::GetDirectory(tag->GetURL());
367 else if (item->HasVideoInfoTag()) // special handling for music videos, which have both a videotag and a musictag
368 break;
369 else
370 URIUtils::GetParentPath(item->GetPath(), value);
371
372 value = CURL(value).GetWithoutUserDetails();
373
374 if (info.m_info == LISTITEM_FOLDERNAME)
375 {
376 URIUtils::RemoveSlashAtEnd(value);
377 value = URIUtils::GetFileName(value);
378 }
379 return true;
380 case LISTITEM_FILENAME_AND_PATH:
381 if (item->IsMusicDb())
382 value = tag->GetURL();
383 else if (item->HasVideoInfoTag()) // special handling for music videos, which have both a videotag and a musictag
384 break;
385 else
386 value = item->GetPath();
387
388 value = CURL(value).GetWithoutUserDetails();
389 return true;
390 case LISTITEM_DATE_ADDED:
391 if (tag->GetDateAdded().IsValid())
392 {
393 value = tag->GetDateAdded().GetAsLocalizedDate();
394 return true;
395 }
396 break;
397 }
398 }
399
400 switch (info.m_info)
401 {
402 ///////////////////////////////////////////////////////////////////////////////////////////////
403 // MUSICPLAYER_*
404 ///////////////////////////////////////////////////////////////////////////////////////////////
405 case MUSICPLAYER_PROPERTY:
406 if (StringUtils::StartsWithNoCase(info.GetData3(), "Role.") && item->HasMusicInfoTag())
407 {
408 // "Role.xxxx" properties are held in music tag
409 std::string property = info.GetData3();
410 property.erase(0, 5); //Remove Role.
411 value = item->GetMusicInfoTag()->GetArtistStringForRole(property);
412 return true;
413 }
414 value = item->GetProperty(info.GetData3()).asString();
415 return true;
416 case MUSICPLAYER_PLAYLISTLEN:
417 if (CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist() == PLAYLIST_MUSIC)
418 {
419 value = GUIINFO::GetPlaylistLabel(PLAYLIST_LENGTH);
420 return true;
421 }
422 break;
423 case MUSICPLAYER_PLAYLISTPOS:
424 if (CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist() == PLAYLIST_MUSIC)
425 {
426 value = GUIINFO::GetPlaylistLabel(PLAYLIST_POSITION);
427 return true;
428 }
429 break;
430 case MUSICPLAYER_COVER:
431 if (g_application.GetAppPlayer().IsPlayingAudio())
432 {
433 if (fallback)
434 *fallback = "DefaultAlbumCover.png";
435 value = item->HasArt("thumb") ? item->GetArt("thumb") : "DefaultAlbumCover.png";
436 return true;
437 }
438 break;
439 case MUSICPLAYER_BITRATE:
440 {
441 int iBitrate = m_audioInfo.bitrate;
442 if (iBitrate > 0)
443 {
444 value = StringUtils::Format("%li", std::lrint(static_cast<double>(iBitrate) / 1000.0));
445 return true;
446 }
447 break;
448 }
449 case MUSICPLAYER_CHANNELS:
450 {
451 int iChannels = m_audioInfo.channels;
452 if (iChannels > 0)
453 {
454 value = StringUtils::Format("%i", iChannels);
455 return true;
456 }
457 break;
458 }
459 case MUSICPLAYER_BITSPERSAMPLE:
460 {
461 int iBPS = m_audioInfo.bitspersample;
462 if (iBPS > 0)
463 {
464 value = StringUtils::Format("%i", iBPS);
465 return true;
466 }
467 break;
468 }
469 case MUSICPLAYER_SAMPLERATE:
470 {
471 int iSamplerate = m_audioInfo.samplerate;
472 if (iSamplerate > 0)
473 {
474 value = StringUtils::Format("%.5g", static_cast<double>(iSamplerate) / 1000.0);
475 return true;
476 }
477 break;
478 }
479 case MUSICPLAYER_CODEC:
480 value = StringUtils::Format("%s", m_audioInfo.codecName.c_str());
481 return true;
482 }
483
484 ///////////////////////////////////////////////////////////////////////////////////////////////
485 // MUSICPM_*
486 ///////////////////////////////////////////////////////////////////////////////////////////////
487 if (GetPartyModeLabel(value, info))
488 return true;
489
490 return false;
491 }
492
GetPartyModeLabel(std::string & value,const CGUIInfo & info) const493 bool CMusicGUIInfo::GetPartyModeLabel(std::string& value, const CGUIInfo &info) const
494 {
495 int iSongs = -1;
496
497 switch (info.m_info)
498 {
499 case MUSICPM_SONGSPLAYED:
500 iSongs = g_partyModeManager.GetSongsPlayed();
501 break;
502 case MUSICPM_MATCHINGSONGS:
503 iSongs = g_partyModeManager.GetMatchingSongs();
504 break;
505 case MUSICPM_MATCHINGSONGSPICKED:
506 iSongs = g_partyModeManager.GetMatchingSongsPicked();
507 break;
508 case MUSICPM_MATCHINGSONGSLEFT:
509 iSongs = g_partyModeManager.GetMatchingSongsLeft();
510 break;
511 case MUSICPM_RELAXEDSONGSPICKED:
512 iSongs = g_partyModeManager.GetRelaxedSongs();
513 break;
514 case MUSICPM_RANDOMSONGSPICKED:
515 iSongs = g_partyModeManager.GetRandomSongs();
516 break;
517 }
518
519 if (iSongs >= 0)
520 {
521 value = StringUtils::Format("%i", iSongs);
522 return true;
523 }
524
525 return false;
526 }
527
GetPlaylistInfo(std::string & value,const CGUIInfo & info) const528 bool CMusicGUIInfo::GetPlaylistInfo(std::string& value, const CGUIInfo &info) const
529 {
530 PLAYLIST::CPlayList& playlist = CServiceBroker::GetPlaylistPlayer().GetPlaylist(PLAYLIST_MUSIC);
531 if (playlist.size() < 1)
532 return false;
533
534 int index = info.GetData2();
535 if (info.GetData1() == 1)
536 { // relative index (requires current playlist is PLAYLIST_MUSIC)
537 if (CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist() != PLAYLIST_MUSIC)
538 return false;
539
540 index = CServiceBroker::GetPlaylistPlayer().GetNextSong(index);
541 }
542
543 if (index < 0 || index >= playlist.size())
544 return false;
545
546 const CFileItemPtr playlistItem = playlist[index];
547 if (playlistItem->HasMusicInfoTag() && !playlistItem->GetMusicInfoTag()->Loaded())
548 {
549 playlistItem->LoadMusicTag();
550 playlistItem->GetMusicInfoTag()->SetLoaded();
551 }
552 // try to set a thumbnail
553 if (!playlistItem->HasArt("thumb"))
554 {
555 CMusicThumbLoader loader;
556 loader.LoadItem(playlistItem.get());
557 // still no thumb? then just the set the default cover
558 if (!playlistItem->HasArt("thumb"))
559 playlistItem->SetArt("thumb", "DefaultAlbumCover.png");
560 }
561 if (info.m_info == MUSICPLAYER_PLAYLISTPOS)
562 {
563 value = StringUtils::Format("%i", index + 1);
564 return true;
565 }
566 else if (info.m_info == MUSICPLAYER_COVER)
567 {
568 value = playlistItem->GetArt("thumb");
569 return true;
570 }
571
572 return GetLabel(value, playlistItem.get(), 0, CGUIInfo(info.m_info), nullptr);
573 }
574
GetFallbackLabel(std::string & value,const CFileItem * item,int contextWindow,const CGUIInfo & info,std::string * fallback)575 bool CMusicGUIInfo::GetFallbackLabel(std::string& value,
576 const CFileItem* item,
577 int contextWindow,
578 const CGUIInfo& info,
579 std::string* fallback)
580 {
581 // No fallback for musicplayer "offset" and "position" info labels
582 if (info.GetData1() && ((info.m_info >= MUSICPLAYER_OFFSET_POSITION_FIRST &&
583 info.m_info <= MUSICPLAYER_OFFSET_POSITION_LAST) ||
584 (info.m_info >= PLAYER_OFFSET_POSITION_FIRST && info.m_info <= PLAYER_OFFSET_POSITION_LAST)))
585 return false;
586
587 const CMusicInfoTag* tag = item->GetMusicInfoTag();
588 if (tag)
589 {
590 switch (info.m_info)
591 {
592 /////////////////////////////////////////////////////////////////////////////////////////////
593 // MUSICPLAYER_*
594 /////////////////////////////////////////////////////////////////////////////////////////////
595 case MUSICPLAYER_TITLE:
596 value = item->GetLabel();
597 if (value.empty())
598 value = CUtil::GetTitleFromPath(item->GetPath());
599 return true;
600 default:
601 break;
602 }
603 }
604 return false;
605 }
606
GetInt(int & value,const CGUIListItem * gitem,int contextWindow,const CGUIInfo & info) const607 bool CMusicGUIInfo::GetInt(int& value, const CGUIListItem *gitem, int contextWindow, const CGUIInfo &info) const
608 {
609 return false;
610 }
611
GetBool(bool & value,const CGUIListItem * gitem,int contextWindow,const CGUIInfo & info) const612 bool CMusicGUIInfo::GetBool(bool& value, const CGUIListItem *gitem, int contextWindow, const CGUIInfo &info) const
613 {
614 const CFileItem* item = static_cast<const CFileItem*>(gitem);
615 const CMusicInfoTag* tag = item->GetMusicInfoTag();
616
617 switch (info.m_info)
618 {
619 ///////////////////////////////////////////////////////////////////////////////////////////////
620 // MUSICPLAYER_*
621 ///////////////////////////////////////////////////////////////////////////////////////////////
622 case MUSICPLAYER_CONTENT:
623 value = StringUtils::EqualsNoCase(info.GetData3(), "files");
624 return value; // if no match for this provider, other providers shall be asked.
625 case MUSICPLAYER_HASPREVIOUS:
626 // requires current playlist be PLAYLIST_MUSIC
627 if (CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist() == PLAYLIST_MUSIC)
628 {
629 value = (CServiceBroker::GetPlaylistPlayer().GetCurrentSong() > 0); // not first song
630 return true;
631 }
632 break;
633 case MUSICPLAYER_HASNEXT:
634 // requires current playlist be PLAYLIST_MUSIC
635 if (CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist() == PLAYLIST_MUSIC)
636 {
637 value = (CServiceBroker::GetPlaylistPlayer().GetCurrentSong() < (CServiceBroker::GetPlaylistPlayer().GetPlaylist(PLAYLIST_MUSIC).size() - 1)); // not last song
638 return true;
639 }
640 break;
641 case MUSICPLAYER_PLAYLISTPLAYING:
642 if (g_application.GetAppPlayer().IsPlayingAudio() && CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist() == PLAYLIST_MUSIC)
643 {
644 value = true;
645 return true;
646 }
647 break;
648 case MUSICPLAYER_EXISTS:
649 {
650 int index = info.GetData2();
651 if (info.GetData1() == 1)
652 { // relative index
653 if (CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist() != PLAYLIST_MUSIC)
654 {
655 value = false;
656 return true;
657 }
658 index += CServiceBroker::GetPlaylistPlayer().GetCurrentSong();
659 }
660 value = (index >= 0 && index < CServiceBroker::GetPlaylistPlayer().GetPlaylist(PLAYLIST_MUSIC).size());
661 return true;
662 }
663 case MUSICPLAYER_ISMULTIDISC:
664 if (tag)
665 {
666 value = (item->GetMusicInfoTag()->GetTotalDiscs() > 1);
667 return true;
668 }
669 break;
670 ///////////////////////////////////////////////////////////////////////////////////////////////
671 // MUSICPM_*
672 ///////////////////////////////////////////////////////////////////////////////////////////////
673 case MUSICPM_ENABLED:
674 value = g_partyModeManager.IsEnabled();
675 return true;
676
677 ///////////////////////////////////////////////////////////////////////////////////////////////
678 // LISTITEM_*
679 ///////////////////////////////////////////////////////////////////////////////////////////////
680 case LISTITEM_IS_BOXSET:
681 if (tag)
682 {
683 value = tag->GetBoxset() == true;
684 return true;
685 }
686 break;
687 }
688
689 return false;
690 }
691