2 * Copyright (C) 2005-2013 Team XBMC
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)
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.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "GUIWindowMusicNav.h"
22 #include "utils/FileUtils.h"
23 #include "utils/URIUtils.h"
24 #include "PlayListPlayer.h"
25 #include "GUIPassword.h"
26 #include "settings/dialogs/GUIDialogContentSettings.h"
27 #include "filesystem/MusicDatabaseDirectory.h"
28 #include "filesystem/VideoDatabaseDirectory.h"
29 #include "PartyModeManager.h"
30 #include "playlists/PlayList.h"
31 #include "playlists/PlayListFactory.h"
32 #include "profiles/ProfilesManager.h"
33 #include "video/VideoDatabase.h"
34 #include "video/windows/GUIWindowVideoNav.h"
35 #include "music/tags/MusicInfoTag.h"
36 #include "guilib/GUIWindowManager.h"
37 #include "dialogs/GUIDialogOK.h"
38 #include "guilib/GUIKeyboardFactory.h"
39 #include "guilib/Key.h"
40 #include "dialogs/GUIDialogYesNo.h"
41 #include "guilib/GUIEditControl.h"
42 #include "GUIUserMessages.h"
43 #include "filesystem/File.h"
45 #include "Application.h"
46 #include "ApplicationMessenger.h"
47 #include "settings/Settings.h"
48 #include "settings/AdvancedSettings.h"
49 #include "guilib/LocalizeStrings.h"
50 #include "utils/LegacyPathTranslation.h"
51 #include "utils/log.h"
52 #include "utils/StringUtils.h"
53 #include "TextureCache.h"
58 using namespace XFILE;
59 using namespace PLAYLIST;
60 using namespace MUSICDATABASEDIRECTORY;
62 #define CONTROL_BTNVIEWASICONS 2
63 #define CONTROL_BTNSORTBY 3
64 #define CONTROL_BTNSORTASC 4
65 #define CONTROL_BTNTYPE 5
66 #define CONTROL_LABELFILES 12
68 #define CONTROL_SEARCH 8
69 #define CONTROL_FILTER 15
70 #define CONTROL_BTNPARTYMODE 16
71 #define CONTROL_BTNMANUALINFO 17
72 #define CONTROL_BTN_FILTER 19
73 #define CONTROL_LABELEMPTY 18
75 CGUIWindowMusicNav::CGUIWindowMusicNav(void)
76 : CGUIWindowMusicBase(WINDOW_MUSIC_NAV, "MyMusicNav.xml")
78 m_vecItems->SetPath("?");
79 m_bDisplayEmptyDatabaseMessage = false;
80 m_thumbLoader.SetObserver(this);
81 m_searchWithEdit = false;
84 CGUIWindowMusicNav::~CGUIWindowMusicNav(void)
88 bool CGUIWindowMusicNav::OnMessage(CGUIMessage& message)
90 switch (message.GetMessage())
92 case GUI_MSG_WINDOW_RESET:
93 m_vecItems->SetPath("?");
95 case GUI_MSG_WINDOW_DEINIT:
96 if (m_thumbLoader.IsLoading())
97 m_thumbLoader.StopThread();
99 case GUI_MSG_WINDOW_INIT:
101 /* We don't want to show Autosourced items (ie removable pendrives, memorycards) in Library mode */
102 m_rootDir.AllowNonLocalSources(false);
104 // is this the first time the window is opened?
105 if (m_vecItems->GetPath() == "?" && message.GetStringParam().IsEmpty())
106 message.SetStringParam(CSettings::Get().GetString("mymusic.defaultlibview"));
108 DisplayEmptyDatabaseMessage(false); // reset message state
110 if (!CGUIWindowMusicBase::OnMessage(message))
113 // base class has opened the database, do our check
114 DisplayEmptyDatabaseMessage(m_musicdatabase.GetSongsCount() <= 0);
116 if (m_bDisplayEmptyDatabaseMessage)
118 // no library - make sure we focus on a known control, and default to the root.
119 SET_CONTROL_FOCUS(CONTROL_BTNTYPE, 0);
120 m_vecItems->SetPath("");
121 SetHistoryForPath("");
129 case GUI_MSG_CLICKED:
131 int iControl = message.GetSenderId();
132 if (iControl == CONTROL_BTNPARTYMODE)
134 if (g_partyModeManager.IsEnabled())
135 g_partyModeManager.Disable();
138 if (!g_partyModeManager.Enable())
140 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNPARTYMODE,false);
144 // Playlist directory is the root of the playlist window
145 if (m_guiState.get()) m_guiState->SetPlaylistDirectory("playlistmusic://");
151 else if (iControl == CONTROL_SEARCH)
153 if (m_searchWithEdit)
155 // search updated - reset timer
156 m_searchTimer.StartZero();
157 // grab our search string
158 CGUIMessage selected(GUI_MSG_ITEM_SELECTED, GetID(), CONTROL_SEARCH);
160 SetProperty("search", selected.GetLabel());
163 CStdString search(GetProperty("search").asString());
164 CGUIKeyboardFactory::ShowAndGetFilter(search, true);
165 SetProperty("search", search);
170 case GUI_MSG_PLAYBACK_STOPPED:
171 case GUI_MSG_PLAYBACK_ENDED:
172 case GUI_MSG_PLAYLISTPLAYER_STOPPED:
173 case GUI_MSG_PLAYBACK_STARTED:
175 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNPARTYMODE, g_partyModeManager.IsEnabled());
178 case GUI_MSG_NOTIFY_ALL:
180 if (message.GetParam1() == GUI_MSG_SEARCH_UPDATE && IsActive())
182 // search updated - reset timer
183 m_searchTimer.StartZero();
184 SetProperty("search", message.GetStringParam());
188 return CGUIWindowMusicBase::OnMessage(message);
191 bool CGUIWindowMusicNav::OnAction(const CAction& action)
193 if (action.GetID() == ACTION_SCAN_ITEM)
195 int item = m_viewControl.GetSelectedItem();
196 CMusicDatabaseDirectory dir;
197 if (item > -1 && m_vecItems->Get(item)->m_bIsFolder
198 && (dir.HasAlbumInfo(m_vecItems->Get(item)->GetPath())||
199 dir.IsArtistDir(m_vecItems->Get(item)->GetPath())))
200 OnContextButton(item,CONTEXT_BUTTON_INFO);
205 return CGUIWindowMusicBase::OnAction(action);
208 CStdString CGUIWindowMusicNav::GetQuickpathName(const CStdString& strPath) const
210 CStdString path = CLegacyPathTranslation::TranslateMusicDbPath(strPath);
211 if (path.Equals("musicdb://genres/"))
213 else if (path.Equals("musicdb://artists/"))
215 else if (path.Equals("musicdb://albums/"))
217 else if (path.Equals("musicdb://songs/"))
219 else if (path.Equals("musicdb://top100/"))
221 else if (path.Equals("musicdb://top100/songs/"))
222 return "Top100Songs";
223 else if (path.Equals("musicdb://top100/albums/"))
224 return "Top100Albums";
225 else if (path.Equals("musicdb://recentlyaddedalbums/"))
226 return "RecentlyAddedAlbums";
227 else if (path.Equals("musicdb://recentlyplayedalbums/"))
228 return "RecentlyPlayedAlbums";
229 else if (path.Equals("musicdb://compilations/"))
230 return "Compilations";
231 else if (path.Equals("musicdb://years/"))
233 else if (path.Equals("musicdb://singles/"))
235 else if (path.Equals("special://musicplaylists/"))
239 CLog::Log(LOGERROR, " CGUIWindowMusicNav::GetQuickpathName: Unknown parameter (%s)", strPath.c_str());
244 bool CGUIWindowMusicNav::OnClick(int iItem)
246 if (iItem < 0 || iItem >= m_vecItems->Size()) return false;
248 CFileItemPtr item = m_vecItems->Get(iItem);
249 if (item->GetPath().Left(14) == "musicsearch://")
251 if (m_searchWithEdit)
255 CStdString search(GetProperty("search").asString());
256 CGUIKeyboardFactory::ShowAndGetFilter(search, true);
257 SetProperty("search", search);
261 if (item->IsMusicDb() && !item->m_bIsFolder)
262 m_musicdatabase.SetPropertiesForFileItem(*item);
264 return CGUIWindowMusicBase::OnClick(iItem);
267 bool CGUIWindowMusicNav::Update(const CStdString &strDirectory, bool updateFilterPath /* = true */)
269 if (m_thumbLoader.IsLoading())
270 m_thumbLoader.StopThread();
272 if (CGUIWindowMusicBase::Update(strDirectory, updateFilterPath))
274 m_thumbLoader.Load(*m_unfilteredItems);
281 bool CGUIWindowMusicNav::GetDirectory(const CStdString &strDirectory, CFileItemList &items)
283 if (m_bDisplayEmptyDatabaseMessage)
286 if (strDirectory.IsEmpty())
289 bool bResult = CGUIWindowMusicBase::GetDirectory(strDirectory, items);
292 if (items.IsPlayList())
293 OnRetrieveMusicInfo(items);
296 // update our content in the info manager
297 if (strDirectory.Left(10).Equals("videodb://"))
299 CVideoDatabaseDirectory dir;
300 VIDEODATABASEDIRECTORY::NODE_TYPE node = dir.GetDirectoryChildType(strDirectory);
301 if (node == VIDEODATABASEDIRECTORY::NODE_TYPE_TITLE_MUSICVIDEOS)
302 items.SetContent("musicvideos");
304 else if (strDirectory.Left(10).Equals("musicdb://"))
306 CMusicDatabaseDirectory dir;
307 NODE_TYPE node = dir.GetDirectoryChildType(strDirectory);
308 if (node == NODE_TYPE_ALBUM ||
309 node == NODE_TYPE_ALBUM_RECENTLY_ADDED ||
310 node == NODE_TYPE_ALBUM_RECENTLY_PLAYED ||
311 node == NODE_TYPE_ALBUM_TOP100 ||
312 node == NODE_TYPE_ALBUM_COMPILATIONS ||
313 node == NODE_TYPE_YEAR_ALBUM)
314 items.SetContent("albums");
315 else if (node == NODE_TYPE_ARTIST)
316 items.SetContent("artists");
317 else if (node == NODE_TYPE_SONG ||
318 node == NODE_TYPE_SONG_TOP100 ||
319 node == NODE_TYPE_SINGLES)
320 items.SetContent("songs");
321 else if (node == NODE_TYPE_GENRE)
322 items.SetContent("genres");
323 else if (node == NODE_TYPE_YEAR)
324 items.SetContent("years");
326 else if (strDirectory.Equals("special://musicplaylists/"))
327 items.SetContent("playlists");
328 else if (strDirectory.Equals("plugin://music/"))
329 items.SetContent("plugins");
330 else if (items.IsPlayList())
331 items.SetContent("songs");
336 void CGUIWindowMusicNav::UpdateButtons()
338 CGUIWindowMusicBase::UpdateButtons();
340 // Update object count
341 int iItems = m_vecItems->Size();
344 // check for parent dir and "all" items
345 // should always be the first two items
346 for (int i = 0; i <= (iItems>=2 ? 1 : 0); i++)
348 CFileItemPtr pItem = m_vecItems->Get(i);
349 if (pItem->IsParentFolder()) iItems--;
350 if (pItem->GetPath().Left(4).Equals("/-1/")) iItems--;
353 if (m_vecItems->Size() > 2 &&
354 m_vecItems->Get(m_vecItems->Size()-1)->GetPath().Left(4).Equals("/-1/"))
358 items.Format("%i %s", iItems, g_localizeStrings.Get(127).c_str());
359 SET_CONTROL_LABEL(CONTROL_LABELFILES, items);
361 // set the filter label
365 if (m_vecItems->GetPath().Equals("special://musicplaylists/"))
366 strLabel = g_localizeStrings.Get(136);
368 else if (m_vecItems->IsPlayList())
370 // get playlist name from path
372 URIUtils::Split(m_vecItems->GetPath(), strDummy, strLabel);
374 // everything else is from a musicdb:// path
377 CMusicDatabaseDirectory dir;
378 dir.GetLabel(m_vecItems->GetPath(), strLabel);
381 SET_CONTROL_LABEL(CONTROL_FILTER, strLabel);
383 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNPARTYMODE, g_partyModeManager.IsEnabled());
386 void CGUIWindowMusicNav::PlayItem(int iItem)
388 // unlike additemtoplaylist, we need to check the items here
389 // before calling it since the current playlist will be stopped
392 // root is not allowed
393 if (m_vecItems->IsVirtualDirectoryRoot())
396 CGUIWindowMusicBase::PlayItem(iItem);
399 void CGUIWindowMusicNav::OnWindowLoaded()
401 const CGUIControl *control = GetControl(CONTROL_SEARCH);
402 m_searchWithEdit = (control && control->GetControlType() == CGUIControl::GUICONTROL_EDIT);
404 CGUIWindowMusicBase::OnWindowLoaded();
406 if (m_searchWithEdit)
408 SendMessage(GUI_MSG_SET_TYPE, CONTROL_SEARCH, CGUIEditControl::INPUT_TYPE_SEARCH);
409 SET_CONTROL_LABEL2(CONTROL_SEARCH, GetProperty("search").asString());
413 void CGUIWindowMusicNav::GetContextButtons(int itemNumber, CContextButtons &buttons)
415 CGUIWindowMusicBase::GetContextButtons(itemNumber, buttons);
418 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
419 item = m_vecItems->Get(itemNumber);
420 if (item && !item->GetPath().Left(14).Equals("addons://more/"))
422 // are we in the playlists location?
423 bool inPlaylists = m_vecItems->GetPath().Equals(CUtil::MusicPlaylistsLocation()) ||
424 m_vecItems->GetPath().Equals("special://musicplaylists/");
426 CMusicDatabaseDirectory dir;
427 // enable music info button on an album or on a song.
428 if (item->IsAudio() && !item->IsPlayList() && !item->IsSmartPlayList() &&
431 buttons.Add(CONTEXT_BUTTON_SONG_INFO, 658);
433 else if (item->IsVideoDb())
435 if (!item->m_bIsFolder) // music video
436 buttons.Add(CONTEXT_BUTTON_INFO, 20393);
437 if (StringUtils::StartsWith(item->GetPath(), "videodb://musicvideos/artist/") && item->m_bIsFolder)
439 long idArtist = m_musicdatabase.GetArtistByName(m_vecItems->Get(itemNumber)->GetLabel());
441 buttons.Add(CONTEXT_BUTTON_INFO,21891);
444 else if (!inPlaylists && (dir.HasAlbumInfo(item->GetPath())||
445 dir.IsArtistDir(item->GetPath()) ) &&
446 !dir.IsAllItem(item->GetPath()) && !item->IsParentFolder() &&
447 !item->IsPlugin() && !item->IsScript() &&
448 !item->GetPath().Left(14).Equals("musicsearch://"))
450 if (dir.IsArtistDir(item->GetPath()))
451 buttons.Add(CONTEXT_BUTTON_INFO, 21891);
453 buttons.Add(CONTEXT_BUTTON_INFO, 13351);
456 // enable query all albums button only in album view
457 if (dir.HasAlbumInfo(item->GetPath()) && !dir.IsAllItem(item->GetPath()) &&
458 item->m_bIsFolder && !item->IsVideoDb() && !item->IsParentFolder() &&
459 !item->IsPlugin() && !item->GetPath().Left(14).Equals("musicsearch://"))
461 buttons.Add(CONTEXT_BUTTON_INFO_ALL, 20059);
464 // enable query all artist button only in album view
465 if (dir.IsArtistDir(item->GetPath()) && !dir.IsAllItem(item->GetPath()) &&
466 item->m_bIsFolder && !item->IsVideoDb())
468 ADDON::ScraperPtr info;
469 m_musicdatabase.GetScraperForPath(item->GetPath(), info, ADDON::ADDON_SCRAPER_ARTISTS);
470 if (info && info->Supports(CONTENT_ARTISTS))
471 buttons.Add(CONTEXT_BUTTON_INFO_ALL, 21884);
474 //Set default or clear default
475 NODE_TYPE nodetype = dir.GetDirectoryType(item->GetPath());
476 if (!item->IsParentFolder() && !inPlaylists &&
477 (nodetype == NODE_TYPE_ROOT ||
478 nodetype == NODE_TYPE_OVERVIEW ||
479 nodetype == NODE_TYPE_TOP100))
481 if (!item->GetPath().Equals(CSettings::Get().GetString("mymusic.defaultlibview").c_str()))
482 buttons.Add(CONTEXT_BUTTON_SET_DEFAULT, 13335); // set default
483 if (strcmp(CSettings::Get().GetString("mymusic.defaultlibview").c_str(), ""))
484 buttons.Add(CONTEXT_BUTTON_CLEAR_DEFAULT, 13403); // clear default
486 NODE_TYPE childtype = dir.GetDirectoryChildType(item->GetPath());
487 if (childtype == NODE_TYPE_ALBUM ||
488 childtype == NODE_TYPE_ARTIST ||
489 nodetype == NODE_TYPE_GENRE ||
490 nodetype == NODE_TYPE_ALBUM ||
491 nodetype == NODE_TYPE_ALBUM_RECENTLY_ADDED ||
492 nodetype == NODE_TYPE_ALBUM_COMPILATIONS)
494 // we allow the user to set content for
495 // 1. general artist and album nodes
496 // 2. specific per genre
497 // 3. specific per artist
498 // 4. specific per album
499 buttons.Add(CONTEXT_BUTTON_SET_CONTENT,20195);
501 if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetArtist().size() > 0)
503 CVideoDatabase database;
505 if (database.GetMatchingMusicVideo(StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator)) > -1)
506 buttons.Add(CONTEXT_BUTTON_GO_TO_ARTIST, 20400);
508 if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetArtist().size() > 0 &&
509 item->GetMusicInfoTag()->GetAlbum().size() > 0 &&
510 item->GetMusicInfoTag()->GetTitle().size() > 0)
512 CVideoDatabase database;
514 if (database.GetMatchingMusicVideo(StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator),item->GetMusicInfoTag()->GetAlbum(),item->GetMusicInfoTag()->GetTitle()) > -1)
515 buttons.Add(CONTEXT_BUTTON_PLAY_OTHER, 20401);
517 if (item->HasVideoInfoTag() && !item->m_bIsFolder)
519 if (item->GetVideoInfoTag()->m_playCount > 0)
520 buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
522 buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched
523 if ((CProfilesManager::Get().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !item->IsPlugin())
525 buttons.Add(CONTEXT_BUTTON_RENAME, 16105);
526 buttons.Add(CONTEXT_BUTTON_DELETE, 646);
529 if (inPlaylists && !URIUtils::GetFileName(item->GetPath()).Equals("PartyMode.xsp")
530 && (item->IsPlayList() || item->IsSmartPlayList()))
531 buttons.Add(CONTEXT_BUTTON_DELETE, 117);
533 if (item->IsPlugin() || item->IsScript() || m_vecItems->IsPlugin())
534 buttons.Add(CONTEXT_BUTTON_PLUGIN_SETTINGS, 1045);
536 // noncontextual buttons
538 if (g_application.IsMusicScanning())
539 buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353); // Stop Scanning
542 if (!m_vecItems->IsPlugin())
543 buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653);
546 CGUIWindowMusicBase::GetNonContextButtons(buttons);
549 bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
552 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
553 item = m_vecItems->Get(itemNumber);
557 case CONTEXT_BUTTON_INFO:
559 if (!item->IsVideoDb())
560 return CGUIWindowMusicBase::OnContextButton(itemNumber,button);
562 // music videos - artists
563 if (StringUtils::StartsWith(item->GetPath(), "videodb://musicvideos/artists/"))
565 long idArtist = m_musicdatabase.GetArtistByName(item->GetLabel());
568 CStdString path; path.Format("musicdb://artists/%ld/", idArtist);
570 m_musicdatabase.GetArtistInfo(idArtist,artist,false);
571 *item = CFileItem(artist);
573 CGUIWindowMusicBase::OnContextButton(itemNumber,button);
575 m_viewControl.SetSelectedItem(itemNumber);
579 // music videos - albums
580 if (StringUtils::StartsWith(item->GetPath(), "videodb://musicvideos/albums/"))
582 long idAlbum = m_musicdatabase.GetAlbumByName(item->GetLabel());
585 CStdString path; path.Format("musicdb://albums/%ld/", idAlbum);
587 m_musicdatabase.GetAlbumInfo(idAlbum,album,NULL);
588 *item = CFileItem(path,album);
590 CGUIWindowMusicBase::OnContextButton(itemNumber,button);
592 m_viewControl.SetSelectedItem(itemNumber);
596 if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_strTitle.IsEmpty())
598 CGUIWindowVideoNav* pWindow = (CGUIWindowVideoNav*)g_windowManager.GetWindow(WINDOW_VIDEO_NAV);
601 ADDON::ScraperPtr info;
602 pWindow->OnInfo(item.get(),info);
609 case CONTEXT_BUTTON_INFO_ALL:
610 OnInfoAll(itemNumber);
613 case CONTEXT_BUTTON_UPDATE_LIBRARY:
615 g_application.StartMusicScan("");
619 case CONTEXT_BUTTON_SET_DEFAULT:
620 CSettings::Get().SetString("mymusic.defaultlibview", GetQuickpathName(item->GetPath()));
621 CSettings::Get().Save();
624 case CONTEXT_BUTTON_CLEAR_DEFAULT:
625 CSettings::Get().SetString("mymusic.defaultlibview", "");
626 CSettings::Get().Save();
629 case CONTEXT_BUTTON_GO_TO_ARTIST:
632 CVideoDatabase database;
634 strPath.Format("videodb://musicvideos/artist/%ld/",database.GetMatchingMusicVideo(StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator)));
635 g_windowManager.ActivateWindow(WINDOW_VIDEO_NAV,strPath);
639 case CONTEXT_BUTTON_PLAY_OTHER:
641 CVideoDatabase database;
643 CVideoInfoTag details;
644 database.GetMusicVideoInfo("",details,database.GetMatchingMusicVideo(StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator),item->GetMusicInfoTag()->GetAlbum(),item->GetMusicInfoTag()->GetTitle()));
645 CApplicationMessenger::Get().PlayFile(CFileItem(details));
649 case CONTEXT_BUTTON_MARK_WATCHED:
650 CGUIWindowVideoBase::MarkWatched(item,true);
651 CUtil::DeleteVideoDatabaseDirectoryCache();
655 case CONTEXT_BUTTON_MARK_UNWATCHED:
656 CGUIWindowVideoBase::MarkWatched(item,false);
657 CUtil::DeleteVideoDatabaseDirectoryCache();
661 case CONTEXT_BUTTON_RENAME:
662 CGUIWindowVideoBase::UpdateVideoTitle(item.get());
663 CUtil::DeleteVideoDatabaseDirectoryCache();
667 case CONTEXT_BUTTON_DELETE:
668 if (item->IsPlayList() || item->IsSmartPlayList())
670 item->m_bIsFolder = false;
671 CFileUtils::DeleteItem(item);
675 CGUIWindowVideoNav::DeleteItem(item.get());
676 CUtil::DeleteVideoDatabaseDirectoryCache();
681 case CONTEXT_BUTTON_SET_CONTENT:
683 ADDON::ScraperPtr scraper;
684 CStdString path(item->GetPath());
686 CDirectoryNode::GetDatabaseInfo(item->GetPath(), params);
687 CONTENT_TYPE content = CONTENT_ALBUMS;
688 if (params.GetAlbumId() != -1)
689 path.Format("musicdb://albums/%i/",params.GetAlbumId());
690 else if (params.GetArtistId() != -1)
692 path.Format("musicdb://artists/%i/",params.GetArtistId());
693 content = CONTENT_ARTISTS;
696 if (m_vecItems->GetPath().Equals("musicdb://genres/") || item->GetPath().Equals("musicdb://artists/"))
698 content = CONTENT_ARTISTS;
701 if (!m_musicdatabase.GetScraperForPath(path, scraper, ADDON::ScraperTypeFromContent(content)))
703 ADDON::AddonPtr defaultScraper;
704 if (ADDON::CAddonMgr::Get().GetDefault(ADDON::ScraperTypeFromContent(content), defaultScraper))
706 scraper = boost::dynamic_pointer_cast<ADDON::CScraper>(defaultScraper->Clone(defaultScraper));
710 if (CGUIDialogContentSettings::Show(scraper, content))
712 m_musicdatabase.SetScraperForPath(path,scraper);
713 if (CGUIDialogYesNo::ShowAndGetInput(20442,20443,20444,20022))
715 OnInfoAll(itemNumber,true,true);
726 return CGUIWindowMusicBase::OnContextButton(itemNumber, button);
729 bool CGUIWindowMusicNav::GetSongsFromPlayList(const CStdString& strPlayList, CFileItemList &items)
731 CStdString strParentPath=m_history.GetParentPath();
733 if (m_guiState.get() && !m_guiState->HideParentDirItems())
735 CFileItemPtr pItem(new CFileItem(".."));
736 pItem->SetPath(strParentPath);
740 items.SetPath(strPlayList);
741 CLog::Log(LOGDEBUG,"CGUIWindowMusicNav, opening playlist [%s]", strPlayList.c_str());
743 auto_ptr<CPlayList> pPlayList (CPlayListFactory::Create(strPlayList));
744 if ( NULL != pPlayList.get())
747 if (!pPlayList->Load(strPlayList))
749 CGUIDialogOK::ShowAndGetInput(6, 0, 477, 0);
750 return false; //hmmm unable to load playlist?
752 CPlayList playlist = *pPlayList;
753 // convert playlist items to songs
754 for (int i = 0; i < (int)playlist.size(); ++i)
756 items.Add(playlist[i]);
763 void CGUIWindowMusicNav::DisplayEmptyDatabaseMessage(bool bDisplay)
765 m_bDisplayEmptyDatabaseMessage = bDisplay;
768 void CGUIWindowMusicNav::OnSearchUpdate()
770 CStdString search(GetProperty("search").asString());
771 CURL::Encode(search);
772 if (!search.IsEmpty())
774 CStdString path = "musicsearch://" + search + "/";
775 m_history.ClearSearchHistory();
778 else if (m_vecItems->IsVirtualDirectoryRoot())
784 void CGUIWindowMusicNav::FrameMove()
786 static const int search_timeout = 2000;
787 // update our searching
788 if (m_searchTimer.IsRunning() && m_searchTimer.GetElapsedMilliseconds() > search_timeout)
790 m_searchTimer.Stop();
793 if (m_bDisplayEmptyDatabaseMessage)
794 SET_CONTROL_LABEL(CONTROL_LABELEMPTY,g_localizeStrings.Get(745)+'\n'+g_localizeStrings.Get(746));
796 SET_CONTROL_LABEL(CONTROL_LABELEMPTY,"");
797 CGUIWindowMusicBase::FrameMove();
800 void CGUIWindowMusicNav::OnPrepareFileItems(CFileItemList &items)
802 CGUIWindowMusicBase::OnPrepareFileItems(items);
805 void CGUIWindowMusicNav::AddSearchFolder()
807 // we use a general viewstate (and not our member) here as our
808 // current viewstate may be specific to some other folder, and
809 // we know we're in the root here
811 CGUIViewState* viewState = CGUIViewState::GetViewState(GetID(), items);
814 // add our remove the musicsearch source
815 VECSOURCES &sources = viewState->GetSources();
816 bool haveSearchSource = false;
817 bool needSearchSource = !GetProperty("search").empty() || !m_searchWithEdit; // we always need it if we don't have the edit control
818 for (IVECSOURCES it = sources.begin(); it != sources.end(); ++it)
820 CMediaSource& share = *it;
821 if (share.strPath == "musicsearch://")
823 haveSearchSource = true;
824 if (!needSearchSource)
831 if (!haveSearchSource && needSearchSource)
835 share.strName=g_localizeStrings.Get(137); // Search
836 share.strPath = "musicsearch://";
837 share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
838 sources.push_back(share);
840 m_rootDir.SetSources(sources);
845 CStdString CGUIWindowMusicNav::GetStartFolder(const CStdString &dir)
847 if (dir.Equals("Genres"))
848 return "musicdb://genres/";
849 else if (dir.Equals("Artists"))
850 return "musicdb://artists/";
851 else if (dir.Equals("Albums"))
852 return "musicdb://albums/";
853 else if (dir.Equals("Singles"))
854 return "musicdb://singles/";
855 else if (dir.Equals("Songs"))
856 return "musicdb://songs/";
857 else if (dir.Equals("Top100"))
858 return "musicdb://top100/";
859 else if (dir.Equals("Top100Songs"))
860 return "musicdb://top100/songs/";
861 else if (dir.Equals("Top100Albums"))
862 return "musicdb://top100/albums/";
863 else if (dir.Equals("RecentlyAddedAlbums"))
864 return "musicdb://recentlyaddedalbums/";
865 else if (dir.Equals("RecentlyPlayedAlbums"))
866 return "musicdb://recentlyplayedalbums/";
867 else if (dir.Equals("Compilations"))
868 return "musicdb://compilations/";
869 else if (dir.Equals("Years"))
870 return "musicdb://years/";
871 return CGUIWindowMusicBase::GetStartFolder(dir);