[Windows] Fix driver version detection of AMD RDNA+ GPU on Windows 10
[xbmc.git] / xbmc / music / windows / GUIWindowMusicPlaylistEditor.cpp
blob6d3d79089842918a86e207065c50d157f2cb5be0
1 /*
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.
7 */
9 #include "GUIWindowMusicPlaylistEditor.h"
11 #include "Autorun.h"
12 #include "FileItem.h"
13 #include "FileItemList.h"
14 #include "GUIUserMessages.h"
15 #include "ServiceBroker.h"
16 #include "URL.h"
17 #include "Util.h"
18 #include "dialogs/GUIDialogFileBrowser.h"
19 #include "dialogs/GUIDialogKaiToast.h"
20 #include "filesystem/PlaylistFileDirectory.h"
21 #include "guilib/GUIKeyboardFactory.h"
22 #include "guilib/LocalizeStrings.h"
23 #include "input/actions/Action.h"
24 #include "input/actions/ActionIDs.h"
25 #include "music/MusicUtils.h"
26 #include "playlists/PlayListM3U.h"
27 #include "settings/Settings.h"
28 #include "settings/SettingsComponent.h"
29 #include "utils/StringUtils.h"
30 #include "utils/URIUtils.h"
31 #include "utils/Variant.h"
33 #define CONTROL_LABELFILES 12
35 #define CONTROL_LOAD_PLAYLIST 6
36 #define CONTROL_SAVE_PLAYLIST 7
37 #define CONTROL_CLEAR_PLAYLIST 8
39 #define CONTROL_LIST 50
40 #define CONTROL_PLAYLIST 100
41 #define CONTROL_LABEL_PLAYLIST 101
43 using namespace KODI;
45 CGUIWindowMusicPlaylistEditor::CGUIWindowMusicPlaylistEditor(void)
46 : CGUIWindowMusicBase(WINDOW_MUSIC_PLAYLIST_EDITOR, "MyMusicPlaylistEditor.xml")
48 m_playlistThumbLoader.SetObserver(this);
49 m_playlist = new CFileItemList;
52 CGUIWindowMusicPlaylistEditor::~CGUIWindowMusicPlaylistEditor(void)
54 delete m_playlist;
57 bool CGUIWindowMusicPlaylistEditor::OnBack(int actionID)
59 if (actionID == ACTION_NAV_BACK && !m_viewControl.HasControl(GetFocusedControlID()))
60 return CGUIWindow::OnBack(actionID); // base class goes up a folder, but none to go up
61 return CGUIWindowMusicBase::OnBack(actionID);
64 bool CGUIWindowMusicPlaylistEditor::OnAction(const CAction &action)
66 if (action.GetID() == ACTION_CONTEXT_MENU)
68 int iControl = GetFocusedControlID();
69 if (iControl == CONTROL_PLAYLIST)
71 OnPlaylistContext();
72 return true;
74 else if (iControl == CONTROL_LIST)
76 OnSourcesContext();
77 return true;
80 return CGUIWindow::OnAction(action);
83 bool CGUIWindowMusicPlaylistEditor::OnClick(int iItem, const std::string& player /* = "" */)
85 if (iItem < 0 || iItem >= m_vecItems->Size()) return false;
86 CFileItemPtr item = m_vecItems->Get(iItem);
88 // Expand .m3u files in sources list when clicked on regardless of <playlistasfolders>
89 if (item->IsFileFolder(EFILEFOLDER_MASK_ONBROWSE))
90 return Update(item->GetPath());
91 // Avoid playback (default click behaviour) of media files
92 if (!item->m_bIsFolder)
93 return false;
95 return CGUIWindowMusicBase::OnClick(iItem, player);
98 bool CGUIWindowMusicPlaylistEditor::OnMessage(CGUIMessage& message)
100 switch ( message.GetMessage() )
102 case GUI_MSG_WINDOW_DEINIT:
103 if (m_thumbLoader.IsLoading())
104 m_thumbLoader.StopThread();
105 if (m_playlistThumbLoader.IsLoading())
106 m_playlistThumbLoader.StopThread();
107 CGUIWindowMusicBase::OnMessage(message);
108 return true;
110 case GUI_MSG_WINDOW_INIT:
112 if (m_vecItems->GetPath() == "?")
113 m_vecItems->SetPath("");
114 CGUIWindowMusicBase::OnMessage(message);
116 if (message.GetNumStringParams())
117 LoadPlaylist(message.GetStringParam());
119 return true;
121 break;
123 case GUI_MSG_NOTIFY_ALL:
125 if (message.GetParam1()==GUI_MSG_REMOVED_MEDIA)
126 DeleteRemoveableMediaDirectoryCache();
128 break;
130 case GUI_MSG_CLICKED:
132 int control = message.GetSenderId();
133 if (control == CONTROL_PLAYLIST)
135 int item = GetCurrentPlaylistItem();
136 int action = message.GetParam1();
137 if (action == ACTION_CONTEXT_MENU || action == ACTION_MOUSE_RIGHT_CLICK)
138 OnPlaylistContext();
139 else if (action == ACTION_QUEUE_ITEM || action == ACTION_DELETE_ITEM ||
140 action == ACTION_MOUSE_MIDDLE_CLICK)
141 OnDeletePlaylistItem(item);
142 else if (action == ACTION_MOVE_ITEM_UP)
143 OnMovePlaylistItem(item, -1);
144 else if (action == ACTION_MOVE_ITEM_DOWN)
145 OnMovePlaylistItem(item, 1);
146 return true;
148 else if (control == CONTROL_LIST)
150 int action = message.GetParam1();
151 if (action == ACTION_CONTEXT_MENU || action == ACTION_MOUSE_RIGHT_CLICK)
153 OnSourcesContext();
154 return true;
157 else if (control == CONTROL_LOAD_PLAYLIST)
158 { // load a playlist
159 OnLoadPlaylist();
160 return true;
162 else if (control == CONTROL_SAVE_PLAYLIST)
163 { // save the playlist
164 OnSavePlaylist();
165 return true;
167 else if (control == CONTROL_CLEAR_PLAYLIST)
168 { // clear the playlist
169 ClearPlaylist();
170 return true;
173 break;
176 return CGUIWindowMusicBase::OnMessage(message);
179 bool CGUIWindowMusicPlaylistEditor::GetDirectory(const std::string &strDirectory, CFileItemList &items)
181 items.Clear();
182 if (strDirectory.empty())
183 { // root listing - list files:// and musicdb://
184 CFileItemPtr files(new CFileItem("sources://music/", true));
185 files->SetLabel(g_localizeStrings.Get(744));
186 files->SetLabelPreformatted(true);
187 files->m_bIsShareOrDrive = true;
188 items.Add(files);
190 CFileItemPtr mdb(new CFileItem("library://music/", true));
191 mdb->SetLabel(g_localizeStrings.Get(14022));
192 mdb->SetLabelPreformatted(true);
193 mdb->m_bIsShareOrDrive = true;
194 items.SetPath("");
195 items.Add(mdb);
197 CFileItemPtr vdb(new CFileItem("videodb://musicvideos/", true));
198 vdb->SetLabel(g_localizeStrings.Get(20389));
199 vdb->SetLabelPreformatted(true);
200 vdb->m_bIsShareOrDrive = true;
201 items.SetPath("");
202 items.Add(vdb);
204 return true;
207 if (!CGUIWindowMusicBase::GetDirectory(strDirectory, items))
208 return false;
210 // check for .CUE files here.
211 items.FilterCueItems();
213 return true;
216 void CGUIWindowMusicPlaylistEditor::OnPrepareFileItems(CFileItemList &items)
218 CGUIWindowMusicBase::OnPrepareFileItems(items);
220 RetrieveMusicInfo();
223 void CGUIWindowMusicPlaylistEditor::UpdateButtons()
225 CGUIWindowMusicBase::UpdateButtons();
227 // Update object count label
228 std::string items = StringUtils::Format("{} {}", m_vecItems->GetObjectCount(),
229 g_localizeStrings.Get(127)); // " 14 Objects"
230 SET_CONTROL_LABEL(CONTROL_LABELFILES, items);
233 void CGUIWindowMusicPlaylistEditor::DeleteRemoveableMediaDirectoryCache()
235 CUtil::DeleteDirectoryCache("r-");
238 void CGUIWindowMusicPlaylistEditor::PlayItem(int iItem)
240 // unlike additemtoplaylist, we need to check the items here
241 // before calling it since the current playlist will be stopped
242 // and cleared!
244 // we're at the root source listing
245 if (m_vecItems->IsVirtualDirectoryRoot() && !m_vecItems->Get(iItem)->IsDVD())
246 return;
248 #ifdef HAS_OPTICAL_DRIVE
249 if (m_vecItems->Get(iItem)->IsDVD())
250 MEDIA_DETECT::CAutorun::PlayDiscAskResume(m_vecItems->Get(iItem)->GetPath());
251 else
252 #endif
253 CGUIWindowMusicBase::PlayItem(iItem);
256 void CGUIWindowMusicPlaylistEditor::OnQueueItem(int iItem, bool)
258 if (iItem < 0 || iItem >= m_vecItems->Size())
259 return;
261 // add this item to our playlist. We make a new copy here as we may be rendering them side by side,
262 // and thus want a different layout for each item
263 CFileItemPtr item(new CFileItem(*m_vecItems->Get(iItem)));
264 CFileItemList newItems;
265 MUSIC_UTILS::GetItemsForPlayList(item, newItems);
266 AppendToPlaylist(newItems);
269 bool CGUIWindowMusicPlaylistEditor::Update(const std::string &strDirectory, bool updateFilterPath /* = true */)
271 if (m_thumbLoader.IsLoading())
272 m_thumbLoader.StopThread();
274 if (!CGUIMediaWindow::Update(strDirectory, updateFilterPath))
275 return false;
277 m_vecItems->SetContent("files");
278 m_thumbLoader.Load(*m_vecItems);
280 // update our playlist control
281 UpdatePlaylist();
282 return true;
285 void CGUIWindowMusicPlaylistEditor::ClearPlaylist()
287 CGUIMessage msg(GUI_MSG_LABEL_RESET, GetID(), CONTROL_PLAYLIST);
288 OnMessage(msg);
290 m_playlist->Clear();
293 void CGUIWindowMusicPlaylistEditor::UpdatePlaylist()
295 if (m_playlistThumbLoader.IsLoading())
296 m_playlistThumbLoader.StopThread();
298 // deselect all items
299 for (int i = 0; i < m_playlist->Size(); i++)
300 m_playlist->Get(i)->Select(false);
302 // bind them to the list
303 CGUIMessage msg(GUI_MSG_LABEL_BIND, GetID(), CONTROL_PLAYLIST, 0, 0, m_playlist);
304 OnMessage(msg);
306 // indicate how many songs we have
307 std::string items = StringUtils::Format("{} {}", m_playlist->Size(),
308 g_localizeStrings.Get(134)); // "123 Songs"
309 SET_CONTROL_LABEL(CONTROL_LABEL_PLAYLIST, items);
311 m_playlistThumbLoader.Load(*m_playlist);
314 int CGUIWindowMusicPlaylistEditor::GetCurrentPlaylistItem()
316 CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), CONTROL_PLAYLIST);
317 OnMessage(msg);
318 int item = msg.GetParam1();
319 if (item > m_playlist->Size())
320 return -1;
321 return item;
324 void CGUIWindowMusicPlaylistEditor::OnDeletePlaylistItem(int item)
326 if (item < 0) return;
327 m_playlist->Remove(item);
328 UpdatePlaylist();
329 // select the next item
330 CGUIMessage msg(GUI_MSG_ITEM_SELECT, GetID(), CONTROL_PLAYLIST, item);
331 OnMessage(msg);
334 void CGUIWindowMusicPlaylistEditor::OnMovePlaylistItem(int item, int direction)
336 if (item < 0) return;
337 if (item + direction >= m_playlist->Size() || item + direction < 0)
338 return;
339 m_playlist->Swap(item, item + direction);
340 UpdatePlaylist();
341 CGUIMessage msg(GUI_MSG_ITEM_SELECT, GetID(), CONTROL_PLAYLIST, item + direction);
342 OnMessage(msg);
345 void CGUIWindowMusicPlaylistEditor::OnLoadPlaylist()
347 // Prompt user for file to load from music playlists folder
348 std::string playlist;
349 if (CGUIDialogFileBrowser::ShowAndGetFile("special://musicplaylists/",
350 ".m3u|.m3u8|.pls|.b4s|.wpl|.xspf", g_localizeStrings.Get(656),
351 playlist))
352 LoadPlaylist(playlist);
355 void CGUIWindowMusicPlaylistEditor::LoadPlaylist(const std::string &playlist)
357 const CURL pathToUrl(playlist);
358 if (pathToUrl.IsProtocol("newplaylist"))
360 ClearPlaylist();
361 m_strLoadedPlaylist.clear();
362 return;
365 XFILE::CPlaylistFileDirectory dir;
366 CFileItemList items;
367 if (dir.GetDirectory(pathToUrl, items))
369 ClearPlaylist();
370 AppendToPlaylist(items);
371 m_strLoadedPlaylist = playlist;
375 void CGUIWindowMusicPlaylistEditor::OnSavePlaylist()
377 // saves playlist to the playlist folder
378 std::string name = URIUtils::GetFileName(m_strLoadedPlaylist);
379 std::string extension = URIUtils::GetExtension(m_strLoadedPlaylist);
380 if (extension.empty())
381 extension = ".m3u8";
382 else
383 URIUtils::RemoveExtension(name);
385 if (CGUIKeyboardFactory::ShowAndGetInput(name, CVariant{g_localizeStrings.Get(16012)}, false))
387 PLAYLIST::CPlayListM3U playlist;
388 playlist.Add(*m_playlist);
389 std::string path = URIUtils::AddFileToFolder(
390 CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_SYSTEM_PLAYLISTSPATH),
391 "music",
392 name + extension);
394 playlist.Save(path);
395 m_strLoadedPlaylist = name;
396 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info,
397 g_localizeStrings.Get(559), // "Playlist"
398 g_localizeStrings.Get(35259)); // "Saved"
402 void CGUIWindowMusicPlaylistEditor::AppendToPlaylist(CFileItemList &newItems)
404 OnRetrieveMusicInfo(newItems);
405 FormatItemLabels(newItems, LABEL_MASKS(CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_MUSICFILES_TRACKFORMAT), "%D", "%L", ""));
406 m_playlist->Append(newItems);
407 UpdatePlaylist();
410 void CGUIWindowMusicPlaylistEditor::OnSourcesContext()
412 static constexpr int CONTEXT_BUTTON_QUEUE_ITEM = 0;
413 static constexpr int CONTEXT_BUTTON_BROWSE_INTO = 1;
415 CFileItemPtr item = GetCurrentListItem();
416 CContextButtons buttons;
417 if (item->IsFileFolder(EFILEFOLDER_MASK_ONBROWSE))
418 buttons.Add(CONTEXT_BUTTON_BROWSE_INTO, 37015); //Browse into
419 if (item && !item->IsParentFolder() && !m_vecItems->IsVirtualDirectoryRoot())
420 buttons.Add(CONTEXT_BUTTON_QUEUE_ITEM, 15019); // Add (to playlist)
422 int btnid = CGUIDialogContextMenu::ShowAndGetChoice(buttons);
423 if (btnid == CONTEXT_BUTTON_QUEUE_ITEM)
424 OnQueueItem(m_viewControl.GetSelectedItem(), false);
425 else if (btnid == CONTEXT_BUTTON_BROWSE_INTO)
426 Update(item->GetPath());
429 void CGUIWindowMusicPlaylistEditor::OnPlaylistContext()
431 int item = GetCurrentPlaylistItem();
432 CContextButtons buttons;
433 if (item > 0)
434 buttons.Add(CONTEXT_BUTTON_MOVE_ITEM_UP, 13332);
435 if (item >= 0 && item < m_playlist->Size() - 1)
436 buttons.Add(CONTEXT_BUTTON_MOVE_ITEM_DOWN, 13333);
437 if (item >= 0)
438 buttons.Add(CONTEXT_BUTTON_DELETE, 1210);
440 int btnid = CGUIDialogContextMenu::ShowAndGetChoice(buttons);
441 if (btnid == CONTEXT_BUTTON_MOVE_ITEM_UP)
442 OnMovePlaylistItem(item, -1);
443 else if (btnid == CONTEXT_BUTTON_MOVE_ITEM_DOWN)
444 OnMovePlaylistItem(item, 1);
445 else if (btnid == CONTEXT_BUTTON_DELETE)
446 OnDeletePlaylistItem(item);