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/dialogs/GUIDialogVideoInfo.h"
35 #include "video/windows/GUIWindowVideoNav.h"
36 #include "music/tags/MusicInfoTag.h"
37 #include "guilib/GUIWindowManager.h"
38 #include "dialogs/GUIDialogOK.h"
39 #include "guilib/GUIKeyboardFactory.h"
40 #include "guilib/Key.h"
41 #include "dialogs/GUIDialogYesNo.h"
42 #include "guilib/GUIEditControl.h"
43 #include "GUIUserMessages.h"
44 #include "filesystem/File.h"
46 #include "Application.h"
47 #include "ApplicationMessenger.h"
48 #include "settings/Settings.h"
49 #include "settings/AdvancedSettings.h"
50 #include "guilib/LocalizeStrings.h"
51 #include "utils/LegacyPathTranslation.h"
52 #include "utils/log.h"
53 #include "utils/StringUtils.h"
54 #include "TextureCache.h"
59 using namespace XFILE;
60 using namespace PLAYLIST;
61 using namespace MUSICDATABASEDIRECTORY;
63 #define CONTROL_BTNVIEWASICONS 2
64 #define CONTROL_BTNSORTBY 3
65 #define CONTROL_BTNSORTASC 4
66 #define CONTROL_BTNTYPE 5
67 #define CONTROL_LABELFILES 12
69 #define CONTROL_SEARCH 8
70 #define CONTROL_FILTER 15
71 #define CONTROL_BTNPARTYMODE 16
72 #define CONTROL_BTNMANUALINFO 17
73 #define CONTROL_BTN_FILTER 19
74 #define CONTROL_LABELEMPTY 18
76 #define CONTROL_UPDATE_LIBRARY 20
78 CGUIWindowMusicNav::CGUIWindowMusicNav(void)
79 : CGUIWindowMusicBase(WINDOW_MUSIC_NAV, "MyMusicNav.xml")
81 m_vecItems->SetPath("?");
82 m_bDisplayEmptyDatabaseMessage = false;
83 m_thumbLoader.SetObserver(this);
84 m_searchWithEdit = false;
87 CGUIWindowMusicNav::~CGUIWindowMusicNav(void)
91 bool CGUIWindowMusicNav::OnMessage(CGUIMessage& message)
93 switch (message.GetMessage())
95 case GUI_MSG_WINDOW_RESET:
96 m_vecItems->SetPath("?");
98 case GUI_MSG_WINDOW_DEINIT:
99 if (m_thumbLoader.IsLoading())
100 m_thumbLoader.StopThread();
102 case GUI_MSG_WINDOW_INIT:
104 /* We don't want to show Autosourced items (ie removable pendrives, memorycards) in Library mode */
105 m_rootDir.AllowNonLocalSources(false);
107 // is this the first time the window is opened?
108 if (m_vecItems->GetPath() == "?" && message.GetStringParam().IsEmpty())
109 message.SetStringParam(CSettings::Get().GetString("mymusic.defaultlibview"));
111 DisplayEmptyDatabaseMessage(false); // reset message state
113 if (!CGUIWindowMusicBase::OnMessage(message))
116 // base class has opened the database, do our check
117 DisplayEmptyDatabaseMessage(m_musicdatabase.GetSongsCount() <= 0);
119 if (m_bDisplayEmptyDatabaseMessage)
121 // no library - make sure we focus on a known control, and default to the root.
122 SET_CONTROL_FOCUS(CONTROL_BTNTYPE, 0);
123 m_vecItems->SetPath("");
124 SetHistoryForPath("");
132 case GUI_MSG_CLICKED:
134 int iControl = message.GetSenderId();
135 if (iControl == CONTROL_BTNPARTYMODE)
137 if (g_partyModeManager.IsEnabled())
138 g_partyModeManager.Disable();
141 if (!g_partyModeManager.Enable())
143 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNPARTYMODE,false);
147 // Playlist directory is the root of the playlist window
148 if (m_guiState.get()) m_guiState->SetPlaylistDirectory("playlistmusic://");
154 else if (iControl == CONTROL_SEARCH)
156 if (m_searchWithEdit)
158 // search updated - reset timer
159 m_searchTimer.StartZero();
160 // grab our search string
161 CGUIMessage selected(GUI_MSG_ITEM_SELECTED, GetID(), CONTROL_SEARCH);
163 SetProperty("search", selected.GetLabel());
166 CStdString search(GetProperty("search").asString());
167 CGUIKeyboardFactory::ShowAndGetFilter(search, true);
168 SetProperty("search", search);
171 else if (iControl == CONTROL_UPDATE_LIBRARY)
173 if (!g_application.IsMusicScanning())
174 g_application.StartMusicScan("");
176 g_application.StopMusicScan();
181 case GUI_MSG_PLAYBACK_STOPPED:
182 case GUI_MSG_PLAYBACK_ENDED:
183 case GUI_MSG_PLAYLISTPLAYER_STOPPED:
184 case GUI_MSG_PLAYBACK_STARTED:
186 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNPARTYMODE, g_partyModeManager.IsEnabled());
189 case GUI_MSG_NOTIFY_ALL:
191 if (message.GetParam1() == GUI_MSG_SEARCH_UPDATE && IsActive())
193 // search updated - reset timer
194 m_searchTimer.StartZero();
195 SetProperty("search", message.GetStringParam());
199 return CGUIWindowMusicBase::OnMessage(message);
202 bool CGUIWindowMusicNav::OnAction(const CAction& action)
204 if (action.GetID() == ACTION_SCAN_ITEM)
206 int item = m_viewControl.GetSelectedItem();
207 CMusicDatabaseDirectory dir;
208 if (item > -1 && m_vecItems->Get(item)->m_bIsFolder
209 && (dir.HasAlbumInfo(m_vecItems->Get(item)->GetPath())||
210 dir.IsArtistDir(m_vecItems->Get(item)->GetPath())))
211 OnContextButton(item,CONTEXT_BUTTON_INFO);
216 return CGUIWindowMusicBase::OnAction(action);
219 CStdString CGUIWindowMusicNav::GetQuickpathName(const CStdString& strPath) const
221 CStdString path = CLegacyPathTranslation::TranslateMusicDbPath(strPath);
222 if (path.Equals("musicdb://genres/"))
224 else if (path.Equals("musicdb://artists/"))
226 else if (path.Equals("musicdb://albums/"))
228 else if (path.Equals("musicdb://songs/"))
230 else if (path.Equals("musicdb://top100/"))
232 else if (path.Equals("musicdb://top100/songs/"))
233 return "Top100Songs";
234 else if (path.Equals("musicdb://top100/albums/"))
235 return "Top100Albums";
236 else if (path.Equals("musicdb://recentlyaddedalbums/"))
237 return "RecentlyAddedAlbums";
238 else if (path.Equals("musicdb://recentlyplayedalbums/"))
239 return "RecentlyPlayedAlbums";
240 else if (path.Equals("musicdb://compilations/"))
241 return "Compilations";
242 else if (path.Equals("musicdb://years/"))
244 else if (path.Equals("musicdb://singles/"))
246 else if (path.Equals("special://musicplaylists/"))
250 CLog::Log(LOGERROR, " CGUIWindowMusicNav::GetQuickpathName: Unknown parameter (%s)", strPath.c_str());
255 bool CGUIWindowMusicNav::OnClick(int iItem)
257 if (iItem < 0 || iItem >= m_vecItems->Size()) return false;
259 CFileItemPtr item = m_vecItems->Get(iItem);
260 if (item->GetPath().Left(14) == "musicsearch://")
262 if (m_searchWithEdit)
266 CStdString search(GetProperty("search").asString());
267 CGUIKeyboardFactory::ShowAndGetFilter(search, true);
268 SetProperty("search", search);
272 if (item->IsMusicDb() && !item->m_bIsFolder)
273 m_musicdatabase.SetPropertiesForFileItem(*item);
275 return CGUIWindowMusicBase::OnClick(iItem);
278 bool CGUIWindowMusicNav::Update(const CStdString &strDirectory, bool updateFilterPath /* = true */)
280 if (m_thumbLoader.IsLoading())
281 m_thumbLoader.StopThread();
283 if (CGUIWindowMusicBase::Update(strDirectory, updateFilterPath))
285 m_thumbLoader.Load(*m_unfilteredItems);
292 bool CGUIWindowMusicNav::GetDirectory(const CStdString &strDirectory, CFileItemList &items)
294 if (m_bDisplayEmptyDatabaseMessage)
297 if (strDirectory.IsEmpty())
300 bool bResult = CGUIWindowMusicBase::GetDirectory(strDirectory, items);
303 if (items.IsPlayList())
304 OnRetrieveMusicInfo(items);
307 // update our content in the info manager
308 if (StringUtils::StartsWithNoCase(strDirectory, "videodb://"))
310 CVideoDatabaseDirectory dir;
311 VIDEODATABASEDIRECTORY::NODE_TYPE node = dir.GetDirectoryChildType(strDirectory);
312 if (node == VIDEODATABASEDIRECTORY::NODE_TYPE_TITLE_MUSICVIDEOS)
313 items.SetContent("musicvideos");
315 else if (StringUtils::StartsWithNoCase(strDirectory, "musicdb://"))
317 CMusicDatabaseDirectory dir;
318 NODE_TYPE node = dir.GetDirectoryChildType(strDirectory);
319 if (node == NODE_TYPE_ALBUM ||
320 node == NODE_TYPE_ALBUM_RECENTLY_ADDED ||
321 node == NODE_TYPE_ALBUM_RECENTLY_PLAYED ||
322 node == NODE_TYPE_ALBUM_TOP100 ||
323 node == NODE_TYPE_ALBUM_COMPILATIONS ||
324 node == NODE_TYPE_YEAR_ALBUM)
325 items.SetContent("albums");
326 else if (node == NODE_TYPE_ARTIST)
327 items.SetContent("artists");
328 else if (node == NODE_TYPE_SONG ||
329 node == NODE_TYPE_SONG_TOP100 ||
330 node == NODE_TYPE_SINGLES)
331 items.SetContent("songs");
332 else if (node == NODE_TYPE_GENRE)
333 items.SetContent("genres");
334 else if (node == NODE_TYPE_YEAR)
335 items.SetContent("years");
337 else if (strDirectory.Equals("special://musicplaylists/"))
338 items.SetContent("playlists");
339 else if (strDirectory.Equals("plugin://music/"))
340 items.SetContent("plugins");
341 else if (items.IsPlayList())
342 items.SetContent("songs");
347 void CGUIWindowMusicNav::UpdateButtons()
349 CGUIWindowMusicBase::UpdateButtons();
351 // Update object count
352 int iItems = m_vecItems->Size();
355 // check for parent dir and "all" items
356 // should always be the first two items
357 for (int i = 0; i <= (iItems>=2 ? 1 : 0); i++)
359 CFileItemPtr pItem = m_vecItems->Get(i);
360 if (pItem->IsParentFolder()) iItems--;
361 if (StringUtils::StartsWith(pItem->GetPath(), "/-1/")) iItems--;
364 if (m_vecItems->Size() > 2 &&
365 StringUtils::StartsWith(m_vecItems->Get(m_vecItems->Size()-1)->GetPath(), "/-1/"))
369 items.Format("%i %s", iItems, g_localizeStrings.Get(127).c_str());
370 SET_CONTROL_LABEL(CONTROL_LABELFILES, items);
372 // set the filter label
376 if (m_vecItems->GetPath().Equals("special://musicplaylists/"))
377 strLabel = g_localizeStrings.Get(136);
379 else if (m_vecItems->IsPlayList())
381 // get playlist name from path
383 URIUtils::Split(m_vecItems->GetPath(), strDummy, strLabel);
385 // everything else is from a musicdb:// path
388 CMusicDatabaseDirectory dir;
389 dir.GetLabel(m_vecItems->GetPath(), strLabel);
392 SET_CONTROL_LABEL(CONTROL_FILTER, strLabel);
394 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNPARTYMODE, g_partyModeManager.IsEnabled());
396 CONTROL_ENABLE_ON_CONDITION(CONTROL_UPDATE_LIBRARY, !m_vecItems->IsAddonsPath() && !m_vecItems->IsPlugin() && !m_vecItems->IsScript());
399 void CGUIWindowMusicNav::PlayItem(int iItem)
401 // unlike additemtoplaylist, we need to check the items here
402 // before calling it since the current playlist will be stopped
405 // root is not allowed
406 if (m_vecItems->IsVirtualDirectoryRoot())
409 CGUIWindowMusicBase::PlayItem(iItem);
412 void CGUIWindowMusicNav::OnWindowLoaded()
414 const CGUIControl *control = GetControl(CONTROL_SEARCH);
415 m_searchWithEdit = (control && control->GetControlType() == CGUIControl::GUICONTROL_EDIT);
417 CGUIWindowMusicBase::OnWindowLoaded();
419 if (m_searchWithEdit)
421 SendMessage(GUI_MSG_SET_TYPE, CONTROL_SEARCH, CGUIEditControl::INPUT_TYPE_SEARCH);
422 SET_CONTROL_LABEL2(CONTROL_SEARCH, GetProperty("search").asString());
426 void CGUIWindowMusicNav::GetContextButtons(int itemNumber, CContextButtons &buttons)
428 CGUIWindowMusicBase::GetContextButtons(itemNumber, buttons);
431 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
432 item = m_vecItems->Get(itemNumber);
433 if (item && !StringUtils::StartsWithNoCase(item->GetPath(), "addons://more/"))
435 // are we in the playlists location?
436 bool inPlaylists = m_vecItems->GetPath().Equals(CUtil::MusicPlaylistsLocation()) ||
437 m_vecItems->GetPath().Equals("special://musicplaylists/");
439 CMusicDatabaseDirectory dir;
440 // enable music info button on an album or on a song.
441 if (item->IsAudio() && !item->IsPlayList() && !item->IsSmartPlayList() &&
444 buttons.Add(CONTEXT_BUTTON_SONG_INFO, 658);
446 else if (item->IsVideoDb())
448 if (!item->m_bIsFolder) // music video
449 buttons.Add(CONTEXT_BUTTON_INFO, 20393);
450 if (StringUtils::StartsWithNoCase(item->GetPath(), "videodb://musicvideos/artists/") && item->m_bIsFolder)
452 long idArtist = m_musicdatabase.GetArtistByName(m_vecItems->Get(itemNumber)->GetLabel());
454 buttons.Add(CONTEXT_BUTTON_INFO,21891);
457 else if (!inPlaylists && (dir.HasAlbumInfo(item->GetPath())||
458 dir.IsArtistDir(item->GetPath()) ) &&
459 !dir.IsAllItem(item->GetPath()) && !item->IsParentFolder() &&
460 !item->IsPlugin() && !item->IsScript() &&
461 !StringUtils::StartsWithNoCase(item->GetPath(), "musicsearch://"))
463 if (dir.IsArtistDir(item->GetPath()))
464 buttons.Add(CONTEXT_BUTTON_INFO, 21891);
466 buttons.Add(CONTEXT_BUTTON_INFO, 13351);
469 // enable query all albums button only in album view
470 if (dir.HasAlbumInfo(item->GetPath()) && !dir.IsAllItem(item->GetPath()) &&
471 item->m_bIsFolder && !item->IsVideoDb() && !item->IsParentFolder() &&
472 !item->IsPlugin() && !StringUtils::StartsWithNoCase(item->GetPath(), "musicsearch://"))
474 buttons.Add(CONTEXT_BUTTON_INFO_ALL, 20059);
477 // enable query all artist button only in album view
478 if (dir.IsArtistDir(item->GetPath()) && !dir.IsAllItem(item->GetPath()) &&
479 item->m_bIsFolder && !item->IsVideoDb())
481 ADDON::ScraperPtr info;
482 m_musicdatabase.GetScraperForPath(item->GetPath(), info, ADDON::ADDON_SCRAPER_ARTISTS);
483 if (info && info->Supports(CONTENT_ARTISTS))
484 buttons.Add(CONTEXT_BUTTON_INFO_ALL, 21884);
487 //Set default or clear default
488 NODE_TYPE nodetype = dir.GetDirectoryType(item->GetPath());
489 if (!item->IsParentFolder() && !inPlaylists &&
490 (nodetype == NODE_TYPE_ROOT ||
491 nodetype == NODE_TYPE_OVERVIEW ||
492 nodetype == NODE_TYPE_TOP100))
494 if (!item->GetPath().Equals(CSettings::Get().GetString("mymusic.defaultlibview").c_str()))
495 buttons.Add(CONTEXT_BUTTON_SET_DEFAULT, 13335); // set default
496 if (strcmp(CSettings::Get().GetString("mymusic.defaultlibview").c_str(), ""))
497 buttons.Add(CONTEXT_BUTTON_CLEAR_DEFAULT, 13403); // clear default
499 NODE_TYPE childtype = dir.GetDirectoryChildType(item->GetPath());
500 if (childtype == NODE_TYPE_ALBUM ||
501 childtype == NODE_TYPE_ARTIST ||
502 nodetype == NODE_TYPE_GENRE ||
503 nodetype == NODE_TYPE_ALBUM ||
504 nodetype == NODE_TYPE_ALBUM_RECENTLY_ADDED ||
505 nodetype == NODE_TYPE_ALBUM_COMPILATIONS)
507 // we allow the user to set content for
508 // 1. general artist and album nodes
509 // 2. specific per genre
510 // 3. specific per artist
511 // 4. specific per album
512 buttons.Add(CONTEXT_BUTTON_SET_CONTENT,20195);
514 if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetArtist().size() > 0)
516 CVideoDatabase database;
518 if (database.GetMatchingMusicVideo(StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator)) > -1)
519 buttons.Add(CONTEXT_BUTTON_GO_TO_ARTIST, 20400);
521 if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetArtist().size() > 0 &&
522 item->GetMusicInfoTag()->GetAlbum().size() > 0 &&
523 item->GetMusicInfoTag()->GetTitle().size() > 0)
525 CVideoDatabase database;
527 if (database.GetMatchingMusicVideo(StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator),item->GetMusicInfoTag()->GetAlbum(),item->GetMusicInfoTag()->GetTitle()) > -1)
528 buttons.Add(CONTEXT_BUTTON_PLAY_OTHER, 20401);
530 if (item->HasVideoInfoTag() && !item->m_bIsFolder)
532 if (item->GetVideoInfoTag()->m_playCount > 0)
533 buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
535 buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched
536 if ((CProfilesManager::Get().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !item->IsPlugin())
538 buttons.Add(CONTEXT_BUTTON_RENAME, 16105);
539 buttons.Add(CONTEXT_BUTTON_DELETE, 646);
542 if (inPlaylists && !URIUtils::GetFileName(item->GetPath()).Equals("PartyMode.xsp")
543 && (item->IsPlayList() || item->IsSmartPlayList()))
544 buttons.Add(CONTEXT_BUTTON_DELETE, 117);
546 if (item->IsPlugin() || item->IsScript() || m_vecItems->IsPlugin())
547 buttons.Add(CONTEXT_BUTTON_PLUGIN_SETTINGS, 1045);
549 // noncontextual buttons
551 CGUIWindowMusicBase::GetNonContextButtons(buttons);
554 bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
557 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
558 item = m_vecItems->Get(itemNumber);
562 case CONTEXT_BUTTON_INFO:
564 if (!item->IsVideoDb())
565 return CGUIWindowMusicBase::OnContextButton(itemNumber,button);
567 // music videos - artists
568 if (StringUtils::StartsWithNoCase(item->GetPath(), "videodb://musicvideos/artists/"))
570 long idArtist = m_musicdatabase.GetArtistByName(item->GetLabel());
573 CStdString path; path.Format("musicdb://artists/%ld/", idArtist);
575 m_musicdatabase.GetArtistInfo(idArtist,artist,false);
576 *item = CFileItem(artist);
578 CGUIWindowMusicBase::OnContextButton(itemNumber,button);
580 m_viewControl.SetSelectedItem(itemNumber);
584 // music videos - albums
585 if (StringUtils::StartsWithNoCase(item->GetPath(), "videodb://musicvideos/albums/"))
587 long idAlbum = m_musicdatabase.GetAlbumByName(item->GetLabel());
590 CStdString path; path.Format("musicdb://albums/%ld/", idAlbum);
592 m_musicdatabase.GetAlbumInfo(idAlbum,album,NULL);
593 *item = CFileItem(path,album);
595 CGUIWindowMusicBase::OnContextButton(itemNumber,button);
597 m_viewControl.SetSelectedItem(itemNumber);
601 if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_strTitle.IsEmpty())
603 CGUIWindowVideoNav* pWindow = (CGUIWindowVideoNav*)g_windowManager.GetWindow(WINDOW_VIDEO_NAV);
606 ADDON::ScraperPtr info;
607 pWindow->OnInfo(item.get(),info);
614 case CONTEXT_BUTTON_INFO_ALL:
615 OnInfoAll(itemNumber);
618 case CONTEXT_BUTTON_SET_DEFAULT:
619 CSettings::Get().SetString("mymusic.defaultlibview", GetQuickpathName(item->GetPath()));
620 CSettings::Get().Save();
623 case CONTEXT_BUTTON_CLEAR_DEFAULT:
624 CSettings::Get().SetString("mymusic.defaultlibview", "");
625 CSettings::Get().Save();
628 case CONTEXT_BUTTON_GO_TO_ARTIST:
631 CVideoDatabase database;
633 strPath.Format("videodb://musicvideos/artists/%ld/",database.GetMatchingMusicVideo(StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator)));
634 g_windowManager.ActivateWindow(WINDOW_VIDEO_NAV,strPath);
638 case CONTEXT_BUTTON_PLAY_OTHER:
640 CVideoDatabase database;
642 CVideoInfoTag details;
643 database.GetMusicVideoInfo("",details,database.GetMatchingMusicVideo(StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator),item->GetMusicInfoTag()->GetAlbum(),item->GetMusicInfoTag()->GetTitle()));
644 CApplicationMessenger::Get().PlayFile(CFileItem(details));
648 case CONTEXT_BUTTON_MARK_WATCHED:
649 CGUIDialogVideoInfo::MarkWatched(item, true);
650 CUtil::DeleteVideoDatabaseDirectoryCache();
654 case CONTEXT_BUTTON_MARK_UNWATCHED:
655 CGUIDialogVideoInfo::MarkWatched(item, false);
656 CUtil::DeleteVideoDatabaseDirectoryCache();
660 case CONTEXT_BUTTON_RENAME:
661 CGUIDialogVideoInfo::UpdateVideoItemTitle(item);
662 CUtil::DeleteVideoDatabaseDirectoryCache();
666 case CONTEXT_BUTTON_DELETE:
667 if (item->IsPlayList() || item->IsSmartPlayList())
669 item->m_bIsFolder = false;
670 CFileUtils::DeleteItem(item);
674 CGUIWindowVideoNav::DeleteItem(item.get());
675 CUtil::DeleteVideoDatabaseDirectoryCache();
680 case CONTEXT_BUTTON_SET_CONTENT:
682 ADDON::ScraperPtr scraper;
683 CStdString path(item->GetPath());
685 CDirectoryNode::GetDatabaseInfo(item->GetPath(), params);
686 CONTENT_TYPE content = CONTENT_ALBUMS;
687 if (params.GetAlbumId() != -1)
688 path.Format("musicdb://albums/%i/",params.GetAlbumId());
689 else if (params.GetArtistId() != -1)
691 path.Format("musicdb://artists/%i/",params.GetArtistId());
692 content = CONTENT_ARTISTS;
695 if (m_vecItems->GetPath().Equals("musicdb://genres/") || item->GetPath().Equals("musicdb://artists/"))
697 content = CONTENT_ARTISTS;
700 if (!m_musicdatabase.GetScraperForPath(path, scraper, ADDON::ScraperTypeFromContent(content)))
702 ADDON::AddonPtr defaultScraper;
703 if (ADDON::CAddonMgr::Get().GetDefault(ADDON::ScraperTypeFromContent(content), defaultScraper))
705 scraper = boost::dynamic_pointer_cast<ADDON::CScraper>(defaultScraper->Clone());
709 if (CGUIDialogContentSettings::Show(scraper, content))
711 m_musicdatabase.SetScraperForPath(path,scraper);
712 if (CGUIDialogYesNo::ShowAndGetInput(20442,20443,20444,20022))
714 OnInfoAll(itemNumber,true,true);
725 return CGUIWindowMusicBase::OnContextButton(itemNumber, button);
728 bool CGUIWindowMusicNav::GetSongsFromPlayList(const CStdString& strPlayList, CFileItemList &items)
730 CStdString strParentPath=m_history.GetParentPath();
732 if (m_guiState.get() && !m_guiState->HideParentDirItems())
734 CFileItemPtr pItem(new CFileItem(".."));
735 pItem->SetPath(strParentPath);
739 items.SetPath(strPlayList);
740 CLog::Log(LOGDEBUG,"CGUIWindowMusicNav, opening playlist [%s]", strPlayList.c_str());
742 auto_ptr<CPlayList> pPlayList (CPlayListFactory::Create(strPlayList));
743 if ( NULL != pPlayList.get())
746 if (!pPlayList->Load(strPlayList))
748 CGUIDialogOK::ShowAndGetInput(6, 0, 477, 0);
749 return false; //hmmm unable to load playlist?
751 CPlayList playlist = *pPlayList;
752 // convert playlist items to songs
753 for (int i = 0; i < (int)playlist.size(); ++i)
755 items.Add(playlist[i]);
762 void CGUIWindowMusicNav::DisplayEmptyDatabaseMessage(bool bDisplay)
764 m_bDisplayEmptyDatabaseMessage = bDisplay;
767 void CGUIWindowMusicNav::OnSearchUpdate()
769 CStdString search(GetProperty("search").asString());
770 CURL::Encode(search);
771 if (!search.IsEmpty())
773 CStdString path = "musicsearch://" + search + "/";
774 m_history.ClearSearchHistory();
777 else if (m_vecItems->IsVirtualDirectoryRoot())
783 void CGUIWindowMusicNav::FrameMove()
785 static const int search_timeout = 2000;
786 // update our searching
787 if (m_searchTimer.IsRunning() && m_searchTimer.GetElapsedMilliseconds() > search_timeout)
789 m_searchTimer.Stop();
792 if (m_bDisplayEmptyDatabaseMessage)
793 SET_CONTROL_LABEL(CONTROL_LABELEMPTY,g_localizeStrings.Get(745)+'\n'+g_localizeStrings.Get(746));
795 SET_CONTROL_LABEL(CONTROL_LABELEMPTY,"");
796 CGUIWindowMusicBase::FrameMove();
799 void CGUIWindowMusicNav::AddSearchFolder()
801 // we use a general viewstate (and not our member) here as our
802 // current viewstate may be specific to some other folder, and
803 // we know we're in the root here
805 CGUIViewState* viewState = CGUIViewState::GetViewState(GetID(), items);
808 // add our remove the musicsearch source
809 VECSOURCES &sources = viewState->GetSources();
810 bool haveSearchSource = false;
811 bool needSearchSource = !GetProperty("search").empty() || !m_searchWithEdit; // we always need it if we don't have the edit control
812 for (IVECSOURCES it = sources.begin(); it != sources.end(); ++it)
814 CMediaSource& share = *it;
815 if (share.strPath == "musicsearch://")
817 haveSearchSource = true;
818 if (!needSearchSource)
825 if (!haveSearchSource && needSearchSource)
829 share.strName=g_localizeStrings.Get(137); // Search
830 share.strPath = "musicsearch://";
831 share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
832 sources.push_back(share);
834 m_rootDir.SetSources(sources);
839 CStdString CGUIWindowMusicNav::GetStartFolder(const CStdString &dir)
841 if (dir.Equals("Genres"))
842 return "musicdb://genres/";
843 else if (dir.Equals("Artists"))
844 return "musicdb://artists/";
845 else if (dir.Equals("Albums"))
846 return "musicdb://albums/";
847 else if (dir.Equals("Singles"))
848 return "musicdb://singles/";
849 else if (dir.Equals("Songs"))
850 return "musicdb://songs/";
851 else if (dir.Equals("Top100"))
852 return "musicdb://top100/";
853 else if (dir.Equals("Top100Songs"))
854 return "musicdb://top100/songs/";
855 else if (dir.Equals("Top100Albums"))
856 return "musicdb://top100/albums/";
857 else if (dir.Equals("RecentlyAddedAlbums"))
858 return "musicdb://recentlyaddedalbums/";
859 else if (dir.Equals("RecentlyPlayedAlbums"))
860 return "musicdb://recentlyplayedalbums/";
861 else if (dir.Equals("Compilations"))
862 return "musicdb://compilations/";
863 else if (dir.Equals("Years"))
864 return "musicdb://years/";
865 return CGUIWindowMusicBase::GetStartFolder(dir);