2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
9 #include "GUIWindowMusicPlaylist.h"
12 #include "FileItemList.h"
13 #include "GUIUserMessages.h"
14 #include "PartyModeManager.h"
15 #include "PlayListPlayer.h"
16 #include "ServiceBroker.h"
18 #include "application/Application.h"
19 #include "application/ApplicationComponents.h"
20 #include "application/ApplicationPlayer.h"
21 #include "dialogs/GUIDialogSmartPlaylistEditor.h"
22 #include "guilib/GUIComponent.h"
23 #include "guilib/GUIKeyboardFactory.h"
24 #include "guilib/GUIWindowManager.h"
25 #include "guilib/LocalizeStrings.h"
26 #include "input/actions/Action.h"
27 #include "input/actions/ActionIDs.h"
28 #include "music/MusicFileItemClassify.h"
29 #include "music/tags/MusicInfoTag.h"
30 #include "playlists/PlayListM3U.h"
31 #include "profiles/ProfileManager.h"
32 #include "settings/MediaSettings.h"
33 #include "settings/Settings.h"
34 #include "settings/SettingsComponent.h"
35 #include "utils/LabelFormatter.h"
36 #include "utils/StringUtils.h"
37 #include "utils/URIUtils.h"
38 #include "utils/Variant.h"
39 #include "utils/log.h"
40 #include "view/GUIViewState.h"
44 #define CONTROL_BTNVIEWASICONS 2
45 #define CONTROL_BTNSORTBY 3
46 #define CONTROL_BTNSORTASC 4
47 #define CONTROL_LABELFILES 12
49 #define CONTROL_BTNSHUFFLE 20
50 #define CONTROL_BTNSAVE 21
51 #define CONTROL_BTNCLEAR 22
53 #define CONTROL_BTNPLAY 23
54 #define CONTROL_BTNNEXT 24
55 #define CONTROL_BTNPREVIOUS 25
56 #define CONTROL_BTNREPEAT 26
58 CGUIWindowMusicPlayList::CGUIWindowMusicPlayList(void)
59 : CGUIWindowMusicBase(WINDOW_MUSIC_PLAYLIST
, "MyPlaylist.xml")
61 m_musicInfoLoader
.SetObserver(this);
65 CGUIWindowMusicPlayList::~CGUIWindowMusicPlayList(void) = default;
67 bool CGUIWindowMusicPlayList::OnMessage(CGUIMessage
& message
)
69 switch (message
.GetMessage())
71 case GUI_MSG_PLAYLISTPLAYER_REPEAT
:
77 case GUI_MSG_PLAYLISTPLAYER_RANDOM
:
78 case GUI_MSG_PLAYLIST_CHANGED
:
80 // global playlist changed outside playlist window
83 if (m_vecItemsUpdating
)
85 CLog::Log(LOGWARNING
, "CGUIWindowMusicPlayList::OnMessage - updating in progress");
88 CUpdateGuard
ug(m_vecItemsUpdating
);
92 if (m_viewControl
.HasControl(m_iLastControl
) && m_vecItems
->Size() <= 0)
94 m_iLastControl
= CONTROL_BTNVIEWASICONS
;
95 SET_CONTROL_FOCUS(m_iLastControl
, 0);
100 case GUI_MSG_WINDOW_DEINIT
:
102 if (m_musicInfoLoader
.IsLoading())
103 m_musicInfoLoader
.StopThread();
109 case GUI_MSG_WINDOW_INIT
:
111 // Setup item cache for tagloader
112 m_musicInfoLoader
.UseCacheOnHD("special://temp/archive_cache/MusicPlaylist.fi");
114 m_vecItems
->SetPath("playlistmusic://");
116 // updatebuttons is called in here
117 if (!CGUIWindowMusicBase::OnMessage(message
))
120 if (m_vecItems
->Size() <= 0)
122 m_iLastControl
= CONTROL_BTNVIEWASICONS
;
123 SET_CONTROL_FOCUS(m_iLastControl
, 0);
126 const auto& components
= CServiceBroker::GetAppComponents();
127 const auto appPlayer
= components
.GetComponent
<CApplicationPlayer
>();
128 if (appPlayer
->IsPlayingAudio() &&
129 CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist() == PLAYLIST::Id::TYPE_MUSIC
)
131 int iSong
= CServiceBroker::GetPlaylistPlayer().GetCurrentItemIdx();
132 if (iSong
>= 0 && iSong
<= m_vecItems
->Size())
133 m_viewControl
.SetSelectedItem(iSong
);
140 case GUI_MSG_CLICKED
:
142 int iControl
= message
.GetSenderId();
143 if (iControl
== CONTROL_BTNSHUFFLE
)
145 if (!g_partyModeManager
.IsEnabled())
147 CServiceBroker::GetPlaylistPlayer().SetShuffle(
148 PLAYLIST::Id::TYPE_MUSIC
,
149 !(CServiceBroker::GetPlaylistPlayer().IsShuffled(PLAYLIST::Id::TYPE_MUSIC
)));
150 CMediaSettings::GetInstance().SetMusicPlaylistShuffled(
151 CServiceBroker::GetPlaylistPlayer().IsShuffled(PLAYLIST::Id::TYPE_MUSIC
));
152 CServiceBroker::GetSettingsComponent()->GetSettings()->Save();
157 else if (iControl
== CONTROL_BTNSAVE
)
159 if (m_musicInfoLoader
.IsLoading()) // needed since we destroy m_vecitems to save memory
160 m_musicInfoLoader
.StopThread();
164 else if (iControl
== CONTROL_BTNCLEAR
)
166 if (m_musicInfoLoader
.IsLoading())
167 m_musicInfoLoader
.StopThread();
171 else if (iControl
== CONTROL_BTNPLAY
)
173 m_guiState
->SetPlaylistDirectory("playlistmusic://");
174 CServiceBroker::GetPlaylistPlayer().SetCurrentPlaylist(PLAYLIST::Id::TYPE_MUSIC
);
175 CServiceBroker::GetPlaylistPlayer().Reset();
176 CServiceBroker::GetPlaylistPlayer().Play(m_viewControl
.GetSelectedItem(), "");
179 else if (iControl
== CONTROL_BTNNEXT
)
181 CServiceBroker::GetPlaylistPlayer().SetCurrentPlaylist(PLAYLIST::Id::TYPE_MUSIC
);
182 CServiceBroker::GetPlaylistPlayer().PlayNext();
184 else if (iControl
== CONTROL_BTNPREVIOUS
)
186 CServiceBroker::GetPlaylistPlayer().SetCurrentPlaylist(PLAYLIST::Id::TYPE_MUSIC
);
187 CServiceBroker::GetPlaylistPlayer().PlayPrevious();
189 else if (iControl
== CONTROL_BTNREPEAT
)
191 // increment repeat state
192 PLAYLIST::RepeatState state
=
193 CServiceBroker::GetPlaylistPlayer().GetRepeat(PLAYLIST::Id::TYPE_MUSIC
);
194 if (state
== PLAYLIST::RepeatState::NONE
)
195 CServiceBroker::GetPlaylistPlayer().SetRepeat(PLAYLIST::Id::TYPE_MUSIC
,
196 PLAYLIST::RepeatState::ALL
);
197 else if (state
== PLAYLIST::RepeatState::ALL
)
198 CServiceBroker::GetPlaylistPlayer().SetRepeat(PLAYLIST::Id::TYPE_MUSIC
,
199 PLAYLIST::RepeatState::ONE
);
201 CServiceBroker::GetPlaylistPlayer().SetRepeat(PLAYLIST::Id::TYPE_MUSIC
,
202 PLAYLIST::RepeatState::NONE
);
205 CMediaSettings::GetInstance().SetMusicPlaylistRepeat(
206 CServiceBroker::GetPlaylistPlayer().GetRepeat(PLAYLIST::Id::TYPE_MUSIC
) ==
207 PLAYLIST::RepeatState::ALL
);
208 CServiceBroker::GetSettingsComponent()->GetSettings()->Save();
212 else if (m_viewControl
.HasControl(iControl
))
214 int iAction
= message
.GetParam1();
215 int iItem
= m_viewControl
.GetSelectedItem();
216 if (iAction
== ACTION_DELETE_ITEM
|| iAction
== ACTION_MOUSE_MIDDLE_CLICK
)
218 RemovePlayListItem(iItem
);
225 return CGUIWindowMusicBase::OnMessage(message
);
228 bool CGUIWindowMusicPlayList::OnAction(const CAction
& action
)
230 if (action
.GetID() == ACTION_PARENT_DIR
)
232 // Playlist has no parent dirs
235 if (action
.GetID() == ACTION_SHOW_PLAYLIST
)
237 CServiceBroker::GetGUI()->GetWindowManager().PreviousWindow();
240 if ((action
.GetID() == ACTION_MOVE_ITEM_UP
) || (action
.GetID() == ACTION_MOVE_ITEM_DOWN
))
243 int iFocusedControl
= GetFocusedControlID();
244 if (m_viewControl
.HasControl(iFocusedControl
))
245 iItem
= m_viewControl
.GetSelectedItem();
246 OnMove(iItem
, action
.GetID());
249 return CGUIWindowMusicBase::OnAction(action
);
252 bool CGUIWindowMusicPlayList::OnBack(int actionID
)
256 if (actionID
== ACTION_NAV_BACK
)
257 return CGUIWindow::OnBack(actionID
); // base class goes up a folder, but none to go up
258 return CGUIWindowMusicBase::OnBack(actionID
);
261 bool CGUIWindowMusicPlayList::MoveCurrentPlayListItem(int iItem
,
263 bool bUpdate
/* = true */)
265 int iSelected
= iItem
;
266 int iNew
= iSelected
;
267 if (iAction
== ACTION_MOVE_ITEM_UP
)
272 const auto& components
= CServiceBroker::GetAppComponents();
273 const auto appPlayer
= components
.GetComponent
<CApplicationPlayer
>();
275 // is the currently playing item affected?
276 bool bFixCurrentSong
= false;
277 if ((CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist() == PLAYLIST::Id::TYPE_MUSIC
) &&
278 appPlayer
->IsPlayingAudio() &&
279 ((CServiceBroker::GetPlaylistPlayer().GetCurrentItemIdx() == iSelected
) ||
280 (CServiceBroker::GetPlaylistPlayer().GetCurrentItemIdx() == iNew
)))
281 bFixCurrentSong
= true;
283 PLAYLIST::CPlayList
& playlist
=
284 CServiceBroker::GetPlaylistPlayer().GetPlaylist(PLAYLIST::Id::TYPE_MUSIC
);
285 if (playlist
.Swap(iSelected
, iNew
))
287 // Correct the current playing song in playlistplayer
290 int iCurrentSong
= CServiceBroker::GetPlaylistPlayer().GetCurrentItemIdx();
291 if (iSelected
== iCurrentSong
)
293 else if (iNew
== iCurrentSong
)
294 iCurrentSong
= iSelected
;
295 CServiceBroker::GetPlaylistPlayer().SetCurrentItemIdx(iCurrentSong
);
306 void CGUIWindowMusicPlayList::SavePlayList()
308 std::string strNewFileName
;
309 if (CGUIKeyboardFactory::ShowAndGetInput(strNewFileName
, CVariant
{g_localizeStrings
.Get(16012)},
313 strNewFileName
= CUtil::MakeLegalFileName(std::move(strNewFileName
));
314 strNewFileName
+= ".m3u8";
315 std::string strPath
=
316 URIUtils::AddFileToFolder(CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(
317 CSettings::SETTING_SYSTEM_PLAYLISTSPATH
),
318 "music", strNewFileName
);
321 int iItem
= m_viewControl
.GetSelectedItem();
322 std::string strSelectedItem
= "";
323 if (iItem
>= 0 && iItem
< m_vecItems
->Size())
325 CFileItemPtr pItem
= m_vecItems
->Get(iItem
);
326 if (!pItem
->IsParentFolder())
328 GetDirectoryHistoryString(pItem
.get(), strSelectedItem
);
332 std::string strOldDirectory
= m_vecItems
->GetPath();
333 m_history
.SetSelectedItem(strSelectedItem
, strOldDirectory
, iItem
);
335 PLAYLIST::CPlayListM3U playlist
;
336 for (int i
= 0; i
< m_vecItems
->Size(); ++i
)
338 CFileItemPtr pItem
= m_vecItems
->Get(i
);
340 // Musicdatabase items should contain the real path instead of a musicdb url
341 // otherwise the user can't save and reuse the playlist when the musicdb gets deleted
342 if (MUSIC::IsMusicDb(*pItem
))
343 pItem
->SetPath(pItem
->GetMusicInfoTag()->GetURL());
347 CLog::Log(LOGDEBUG
, "Saving music playlist: [{}]", strPath
);
348 playlist
.Save(strPath
);
349 Refresh(); // need to update
353 void CGUIWindowMusicPlayList::ClearPlayList()
356 CServiceBroker::GetPlaylistPlayer().ClearPlaylist(PLAYLIST::Id::TYPE_MUSIC
);
357 if (CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist() == PLAYLIST::Id::TYPE_MUSIC
)
359 CServiceBroker::GetPlaylistPlayer().Reset();
360 CServiceBroker::GetPlaylistPlayer().SetCurrentPlaylist(PLAYLIST::Id::TYPE_NONE
);
363 SET_CONTROL_FOCUS(CONTROL_BTNVIEWASICONS
, 0);
366 void CGUIWindowMusicPlayList::RemovePlayListItem(int iItem
)
368 if (iItem
< 0 || iItem
> m_vecItems
->Size())
371 const auto& components
= CServiceBroker::GetAppComponents();
372 const auto appPlayer
= components
.GetComponent
<CApplicationPlayer
>();
373 // The current playing song can't be removed
374 if (CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist() == PLAYLIST::Id::TYPE_MUSIC
&&
375 appPlayer
->IsPlayingAudio() &&
376 CServiceBroker::GetPlaylistPlayer().GetCurrentItemIdx() == iItem
)
379 CServiceBroker::GetPlaylistPlayer().Remove(PLAYLIST::Id::TYPE_MUSIC
, iItem
);
383 if (m_vecItems
->Size() <= 0)
385 SET_CONTROL_FOCUS(CONTROL_BTNVIEWASICONS
, 0);
389 m_viewControl
.SetSelectedItem(iItem
);
392 g_partyModeManager
.OnSongChange();
395 void CGUIWindowMusicPlayList::UpdateButtons()
397 CGUIWindowMusicBase::UpdateButtons();
399 // Update playlist buttons
400 if (m_vecItems
->Size() && !g_partyModeManager
.IsEnabled())
402 CONTROL_ENABLE(CONTROL_BTNSHUFFLE
);
403 CONTROL_ENABLE(CONTROL_BTNSAVE
);
404 CONTROL_ENABLE(CONTROL_BTNCLEAR
);
405 CONTROL_ENABLE(CONTROL_BTNREPEAT
);
406 CONTROL_ENABLE(CONTROL_BTNPLAY
);
408 const auto& components
= CServiceBroker::GetAppComponents();
409 const auto appPlayer
= components
.GetComponent
<CApplicationPlayer
>();
410 if (appPlayer
->IsPlayingAudio() &&
411 CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist() == PLAYLIST::Id::TYPE_MUSIC
)
413 CONTROL_ENABLE(CONTROL_BTNNEXT
);
414 CONTROL_ENABLE(CONTROL_BTNPREVIOUS
);
418 CONTROL_DISABLE(CONTROL_BTNNEXT
);
419 CONTROL_DISABLE(CONTROL_BTNPREVIOUS
);
424 // disable buttons if party mode is enabled too
425 CONTROL_DISABLE(CONTROL_BTNSHUFFLE
);
426 CONTROL_DISABLE(CONTROL_BTNSAVE
);
427 CONTROL_DISABLE(CONTROL_BTNCLEAR
);
428 CONTROL_DISABLE(CONTROL_BTNREPEAT
);
429 CONTROL_DISABLE(CONTROL_BTNPLAY
);
430 CONTROL_DISABLE(CONTROL_BTNNEXT
);
431 CONTROL_DISABLE(CONTROL_BTNPREVIOUS
);
435 CONTROL_DESELECT(CONTROL_BTNSHUFFLE
);
436 if (CServiceBroker::GetPlaylistPlayer().IsShuffled(PLAYLIST::Id::TYPE_MUSIC
))
437 CONTROL_SELECT(CONTROL_BTNSHUFFLE
);
439 // update repeat button
440 int iLocalizedString
;
441 PLAYLIST::RepeatState repState
=
442 CServiceBroker::GetPlaylistPlayer().GetRepeat(PLAYLIST::Id::TYPE_MUSIC
);
443 if (repState
== PLAYLIST::RepeatState::NONE
)
444 iLocalizedString
= 595; // Repeat: Off
445 else if (repState
== PLAYLIST::RepeatState::ONE
)
446 iLocalizedString
= 596; // Repeat: One
448 iLocalizedString
= 597; // Repeat: All
450 SET_CONTROL_LABEL(CONTROL_BTNREPEAT
, g_localizeStrings
.Get(iLocalizedString
));
452 // Update object count label
454 StringUtils::Format("{} {}", m_vecItems
->GetObjectCount(), g_localizeStrings
.Get(127));
455 SET_CONTROL_LABEL(CONTROL_LABELFILES
, items
);
460 bool CGUIWindowMusicPlayList::OnPlayMedia(int iItem
, const std::string
& player
)
462 if (g_partyModeManager
.IsEnabled())
463 g_partyModeManager
.Play(iItem
);
466 PLAYLIST::Id playlistId
= m_guiState
->GetPlaylist();
467 if (playlistId
!= PLAYLIST::Id::TYPE_NONE
)
470 m_guiState
->SetPlaylistDirectory(m_vecItems
->GetPath());
472 CServiceBroker::GetPlaylistPlayer().SetCurrentPlaylist(playlistId
);
473 CServiceBroker::GetPlaylistPlayer().Play(iItem
, player
);
477 // Reset Playlistplayer, playback started now does
478 // not use the playlistplayer.
479 CFileItemPtr pItem
= m_vecItems
->Get(iItem
);
480 CServiceBroker::GetPlaylistPlayer().Reset();
481 CServiceBroker::GetPlaylistPlayer().SetCurrentPlaylist(PLAYLIST::Id::TYPE_NONE
);
482 g_application
.PlayFile(*pItem
, player
);
489 void CGUIWindowMusicPlayList::OnItemLoaded(CFileItem
* pItem
)
491 if (pItem
->HasMusicInfoTag() && pItem
->GetMusicInfoTag()->Loaded())
492 { // set label 1+2 from tags
493 const std::shared_ptr
<CSettings
> settings
=
494 CServiceBroker::GetSettingsComponent()->GetSettings();
495 std::string strTrack
= settings
->GetString(CSettings::SETTING_MUSICFILES_NOWPLAYINGTRACKFORMAT
);
496 if (strTrack
.empty())
497 strTrack
= settings
->GetString(CSettings::SETTING_MUSICFILES_TRACKFORMAT
);
498 CLabelFormatter
formatter(strTrack
, "%D");
499 formatter
.FormatLabels(pItem
);
500 } // if (pItem->m_musicInfoTag.Loaded())
503 // Our tag may have a duration even if its not loaded
504 if (pItem
->HasMusicInfoTag() && pItem
->GetMusicInfoTag()->GetDuration())
506 int nDuration
= pItem
->GetMusicInfoTag()->GetDuration();
508 pItem
->SetLabel2(StringUtils::SecondsToTimeString(nDuration
));
510 else if (pItem
->GetLabel() == "") // pls labels come in preformatted
512 // FIXME: get the position of the item in the playlist
513 // currently it is hacked into m_iprogramCount
515 // No music info and it's not CDDA so we'll just show the filename
517 str
= CUtil::GetTitleFromPath(pItem
->GetPath());
518 str
= StringUtils::Format("{:02}. {} ", pItem
->m_iprogramCount
, str
);
519 pItem
->SetLabel(str
);
524 bool CGUIWindowMusicPlayList::Update(const std::string
& strDirectory
,
525 bool updateFilterPath
/* = true */)
527 if (m_musicInfoLoader
.IsLoading())
528 m_musicInfoLoader
.StopThread();
530 if (!CGUIWindowMusicBase::Update(strDirectory
, updateFilterPath
))
533 if (m_vecItems
->GetContent().empty())
534 m_vecItems
->SetContent("songs");
536 m_musicInfoLoader
.Load(*m_vecItems
);
540 void CGUIWindowMusicPlayList::GetContextButtons(int itemNumber
, CContextButtons
& buttons
)
542 // is this playlist playing?
543 int itemPlaying
= CServiceBroker::GetPlaylistPlayer().GetCurrentItemIdx();
545 if (itemNumber
>= 0 && itemNumber
< m_vecItems
->Size())
548 item
= m_vecItems
->Get(itemNumber
);
550 if (m_movingFrom
>= 0)
552 // we can move the item to any position not where we are, and any position not above currently
553 // playing item in party mode
554 if (itemNumber
!= m_movingFrom
&&
555 (!g_partyModeManager
.IsEnabled() || itemNumber
> itemPlaying
))
556 buttons
.Add(CONTEXT_BUTTON_MOVE_HERE
, 13252); // move item here
557 buttons
.Add(CONTEXT_BUTTON_CANCEL_MOVE
, 13253);
561 if (itemNumber
> (g_partyModeManager
.IsEnabled() ? 1 : 0))
562 buttons
.Add(CONTEXT_BUTTON_MOVE_ITEM_UP
, 13332);
563 if (itemNumber
+ 1 < m_vecItems
->Size())
564 buttons
.Add(CONTEXT_BUTTON_MOVE_ITEM_DOWN
, 13333);
565 if (!g_partyModeManager
.IsEnabled() || itemNumber
!= itemPlaying
)
566 buttons
.Add(CONTEXT_BUTTON_MOVE_ITEM
, 13251);
567 if (itemNumber
!= itemPlaying
)
568 buttons
.Add(CONTEXT_BUTTON_DELETE
, 1210); // Remove
572 if (g_partyModeManager
.IsEnabled())
574 buttons
.Add(CONTEXT_BUTTON_EDIT_PARTYMODE
, 21439);
575 buttons
.Add(CONTEXT_BUTTON_CANCEL_PARTYMODE
, 588); // cancel party mode
579 bool CGUIWindowMusicPlayList::OnContextButton(int itemNumber
, CONTEXT_BUTTON button
)
583 case CONTEXT_BUTTON_MOVE_ITEM
:
584 m_movingFrom
= itemNumber
;
587 case CONTEXT_BUTTON_MOVE_HERE
:
588 MoveItem(m_movingFrom
, itemNumber
);
592 case CONTEXT_BUTTON_CANCEL_MOVE
:
596 case CONTEXT_BUTTON_MOVE_ITEM_UP
:
597 OnMove(itemNumber
, ACTION_MOVE_ITEM_UP
);
600 case CONTEXT_BUTTON_MOVE_ITEM_DOWN
:
601 OnMove(itemNumber
, ACTION_MOVE_ITEM_DOWN
);
604 case CONTEXT_BUTTON_DELETE
:
605 RemovePlayListItem(itemNumber
);
608 case CONTEXT_BUTTON_CANCEL_PARTYMODE
:
609 g_partyModeManager
.Disable();
612 case CONTEXT_BUTTON_EDIT_PARTYMODE
:
614 const std::shared_ptr
<CProfileManager
> profileManager
=
615 CServiceBroker::GetSettingsComponent()->GetProfileManager();
617 std::string playlist
= profileManager
->GetUserDataItem("PartyMode.xsp");
618 if (CGUIDialogSmartPlaylistEditor::EditPlaylist(playlist
))
621 g_partyModeManager
.Disable();
622 g_partyModeManager
.Enable();
630 return CGUIWindowMusicBase::OnContextButton(itemNumber
, button
);
633 void CGUIWindowMusicPlayList::OnMove(int iItem
, int iAction
)
635 if (iItem
< 0 || iItem
>= m_vecItems
->Size())
638 bool bRestart
= m_musicInfoLoader
.IsLoading();
640 m_musicInfoLoader
.StopThread();
642 MoveCurrentPlayListItem(iItem
, iAction
);
645 m_musicInfoLoader
.Load(*m_vecItems
);
648 void CGUIWindowMusicPlayList::MoveItem(int iStart
, int iDest
)
650 if (iStart
< 0 || iStart
>= m_vecItems
->Size())
652 if (iDest
< 0 || iDest
>= m_vecItems
->Size())
655 // default to move up
656 int iAction
= ACTION_MOVE_ITEM_UP
;
658 // are we moving down?
661 iAction
= ACTION_MOVE_ITEM_DOWN
;
665 bool bRestart
= m_musicInfoLoader
.IsLoading();
667 m_musicInfoLoader
.StopThread();
669 // keep swapping until you get to the destination or you
670 // hit the currently playing song
674 // try to swap adjacent items
675 if (MoveCurrentPlayListItem(i
, iAction
, false))
676 i
= i
+ (1 * iDirection
);
677 // we hit currently playing song, so abort
684 m_musicInfoLoader
.Load(*m_vecItems
);
687 void CGUIWindowMusicPlayList::MarkPlaying()
690 for (int i = 0; i < m_vecItems->Size(); i++)
691 m_vecItems->Get(i)->Select(false);
693 // mark the currently playing item
694 if ((CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist() == TYPE_MUSIC) && (g_application.GetAppPlayer().IsPlayingAudio()))
696 int iSong = CServiceBroker::GetPlaylistPlayer().GetCurrentItemIdx();
697 if (iSong >= 0 && iSong <= m_vecItems->Size())
698 m_vecItems->Get(iSong)->Select(true);