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().empty())
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 (StringUtils::StartsWith(item->GetPath(), "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.empty())
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/"))
368 CStdString items = StringUtils::Format("%i %s", iItems, g_localizeStrings.Get(127).c_str());
369 SET_CONTROL_LABEL(CONTROL_LABELFILES, items);
371 // set the filter label
375 if (m_vecItems->GetPath().Equals("special://musicplaylists/"))
376 strLabel = g_localizeStrings.Get(136);
378 else if (m_vecItems->IsPlayList())
380 // get playlist name from path
382 URIUtils::Split(m_vecItems->GetPath(), strDummy, strLabel);
384 // everything else is from a musicdb:// path
387 CMusicDatabaseDirectory dir;
388 dir.GetLabel(m_vecItems->GetPath(), strLabel);
391 SET_CONTROL_LABEL(CONTROL_FILTER, strLabel);
393 SET_CONTROL_SELECTED(GetID(),CONTROL_BTNPARTYMODE, g_partyModeManager.IsEnabled());
395 CONTROL_ENABLE_ON_CONDITION(CONTROL_UPDATE_LIBRARY, !m_vecItems->IsAddonsPath() && !m_vecItems->IsPlugin() && !m_vecItems->IsScript());
398 void CGUIWindowMusicNav::PlayItem(int iItem)
400 // unlike additemtoplaylist, we need to check the items here
401 // before calling it since the current playlist will be stopped
404 // root is not allowed
405 if (m_vecItems->IsVirtualDirectoryRoot())
408 CGUIWindowMusicBase::PlayItem(iItem);
411 void CGUIWindowMusicNav::OnWindowLoaded()
413 const CGUIControl *control = GetControl(CONTROL_SEARCH);
414 m_searchWithEdit = (control && control->GetControlType() == CGUIControl::GUICONTROL_EDIT);
416 CGUIWindowMusicBase::OnWindowLoaded();
418 if (m_searchWithEdit)
420 SendMessage(GUI_MSG_SET_TYPE, CONTROL_SEARCH, CGUIEditControl::INPUT_TYPE_SEARCH);
421 SET_CONTROL_LABEL2(CONTROL_SEARCH, GetProperty("search").asString());
425 void CGUIWindowMusicNav::GetContextButtons(int itemNumber, CContextButtons &buttons)
427 CGUIWindowMusicBase::GetContextButtons(itemNumber, buttons);
430 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
431 item = m_vecItems->Get(itemNumber);
432 if (item && !StringUtils::StartsWithNoCase(item->GetPath(), "addons://more/"))
434 // are we in the playlists location?
435 bool inPlaylists = m_vecItems->GetPath().Equals(CUtil::MusicPlaylistsLocation()) ||
436 m_vecItems->GetPath().Equals("special://musicplaylists/");
438 CMusicDatabaseDirectory dir;
439 // enable music info button on an album or on a song.
440 if (item->IsAudio() && !item->IsPlayList() && !item->IsSmartPlayList() &&
443 buttons.Add(CONTEXT_BUTTON_SONG_INFO, 658);
445 else if (item->IsVideoDb())
447 if (!item->m_bIsFolder) // music video
448 buttons.Add(CONTEXT_BUTTON_INFO, 20393);
449 if (StringUtils::StartsWithNoCase(item->GetPath(), "videodb://musicvideos/artists/") && item->m_bIsFolder)
451 long idArtist = m_musicdatabase.GetArtistByName(m_vecItems->Get(itemNumber)->GetLabel());
453 buttons.Add(CONTEXT_BUTTON_INFO,21891);
456 else if (!inPlaylists && (dir.HasAlbumInfo(item->GetPath())||
457 dir.IsArtistDir(item->GetPath()) ) &&
458 !dir.IsAllItem(item->GetPath()) && !item->IsParentFolder() &&
459 !item->IsPlugin() && !item->IsScript() &&
460 !StringUtils::StartsWithNoCase(item->GetPath(), "musicsearch://"))
462 if (dir.IsArtistDir(item->GetPath()))
463 buttons.Add(CONTEXT_BUTTON_INFO, 21891);
465 buttons.Add(CONTEXT_BUTTON_INFO, 13351);
468 // enable query all albums button only in album view
469 if (dir.HasAlbumInfo(item->GetPath()) && !dir.IsAllItem(item->GetPath()) &&
470 item->m_bIsFolder && !item->IsVideoDb() && !item->IsParentFolder() &&
471 !item->IsPlugin() && !StringUtils::StartsWithNoCase(item->GetPath(), "musicsearch://"))
473 buttons.Add(CONTEXT_BUTTON_INFO_ALL, 20059);
476 // enable query all artist button only in album view
477 if (dir.IsArtistDir(item->GetPath()) && !dir.IsAllItem(item->GetPath()) &&
478 item->m_bIsFolder && !item->IsVideoDb())
480 ADDON::ScraperPtr info;
481 m_musicdatabase.GetScraperForPath(item->GetPath(), info, ADDON::ADDON_SCRAPER_ARTISTS);
482 if (info && info->Supports(CONTENT_ARTISTS))
483 buttons.Add(CONTEXT_BUTTON_INFO_ALL, 21884);
486 //Set default or clear default
487 NODE_TYPE nodetype = dir.GetDirectoryType(item->GetPath());
488 if (!item->IsParentFolder() && !inPlaylists &&
489 (nodetype == NODE_TYPE_ROOT ||
490 nodetype == NODE_TYPE_OVERVIEW ||
491 nodetype == NODE_TYPE_TOP100))
493 if (!item->GetPath().Equals(CSettings::Get().GetString("mymusic.defaultlibview").c_str()))
494 buttons.Add(CONTEXT_BUTTON_SET_DEFAULT, 13335); // set default
495 if (strcmp(CSettings::Get().GetString("mymusic.defaultlibview").c_str(), ""))
496 buttons.Add(CONTEXT_BUTTON_CLEAR_DEFAULT, 13403); // clear default
498 NODE_TYPE childtype = dir.GetDirectoryChildType(item->GetPath());
499 if (childtype == NODE_TYPE_ALBUM ||
500 childtype == NODE_TYPE_ARTIST ||
501 nodetype == NODE_TYPE_GENRE ||
502 nodetype == NODE_TYPE_ALBUM ||
503 nodetype == NODE_TYPE_ALBUM_RECENTLY_ADDED ||
504 nodetype == NODE_TYPE_ALBUM_COMPILATIONS)
506 // we allow the user to set content for
507 // 1. general artist and album nodes
508 // 2. specific per genre
509 // 3. specific per artist
510 // 4. specific per album
511 buttons.Add(CONTEXT_BUTTON_SET_CONTENT,20195);
513 if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetArtist().size() > 0)
515 CVideoDatabase database;
517 if (database.GetMatchingMusicVideo(StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator)) > -1)
518 buttons.Add(CONTEXT_BUTTON_GO_TO_ARTIST, 20400);
520 if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetArtist().size() > 0 &&
521 item->GetMusicInfoTag()->GetAlbum().size() > 0 &&
522 item->GetMusicInfoTag()->GetTitle().size() > 0)
524 CVideoDatabase database;
526 if (database.GetMatchingMusicVideo(StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator),item->GetMusicInfoTag()->GetAlbum(),item->GetMusicInfoTag()->GetTitle()) > -1)
527 buttons.Add(CONTEXT_BUTTON_PLAY_OTHER, 20401);
529 if (item->HasVideoInfoTag() && !item->m_bIsFolder)
531 if (item->GetVideoInfoTag()->m_playCount > 0)
532 buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
534 buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched
535 if ((CProfilesManager::Get().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !item->IsPlugin())
537 buttons.Add(CONTEXT_BUTTON_RENAME, 16105);
538 buttons.Add(CONTEXT_BUTTON_DELETE, 646);
541 if (inPlaylists && !URIUtils::GetFileName(item->GetPath()).Equals("PartyMode.xsp")
542 && (item->IsPlayList() || item->IsSmartPlayList()))
543 buttons.Add(CONTEXT_BUTTON_DELETE, 117);
545 if (item->IsPlugin() || item->IsScript() || m_vecItems->IsPlugin())
546 buttons.Add(CONTEXT_BUTTON_PLUGIN_SETTINGS, 1045);
548 // noncontextual buttons
550 CGUIWindowMusicBase::GetNonContextButtons(buttons);
553 bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
556 if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
557 item = m_vecItems->Get(itemNumber);
561 case CONTEXT_BUTTON_INFO:
563 if (!item->IsVideoDb())
564 return CGUIWindowMusicBase::OnContextButton(itemNumber,button);
566 // music videos - artists
567 if (StringUtils::StartsWithNoCase(item->GetPath(), "videodb://musicvideos/artists/"))
569 long idArtist = m_musicdatabase.GetArtistByName(item->GetLabel());
572 CStdString path = StringUtils::Format("musicdb://artists/%ld/", idArtist);
574 m_musicdatabase.GetArtist(idArtist, artist, false);
575 *item = CFileItem(artist);
577 CGUIWindowMusicBase::OnContextButton(itemNumber,button);
579 m_viewControl.SetSelectedItem(itemNumber);
583 // music videos - albums
584 if (StringUtils::StartsWithNoCase(item->GetPath(), "videodb://musicvideos/albums/"))
586 long idAlbum = m_musicdatabase.GetAlbumByName(item->GetLabel());
589 CStdString path = StringUtils::Format("musicdb://albums/%ld/", idAlbum);
591 m_musicdatabase.GetAlbum(idAlbum, album, false);
592 *item = CFileItem(path,album);
594 CGUIWindowMusicBase::OnContextButton(itemNumber,button);
596 m_viewControl.SetSelectedItem(itemNumber);
600 if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_strTitle.empty())
602 CGUIWindowVideoNav* pWindow = (CGUIWindowVideoNav*)g_windowManager.GetWindow(WINDOW_VIDEO_NAV);
605 ADDON::ScraperPtr info;
606 pWindow->OnInfo(item.get(),info);
613 case CONTEXT_BUTTON_INFO_ALL:
614 OnInfoAll(itemNumber);
617 case CONTEXT_BUTTON_SET_DEFAULT:
618 CSettings::Get().SetString("mymusic.defaultlibview", GetQuickpathName(item->GetPath()));
619 CSettings::Get().Save();
622 case CONTEXT_BUTTON_CLEAR_DEFAULT:
623 CSettings::Get().SetString("mymusic.defaultlibview", "");
624 CSettings::Get().Save();
627 case CONTEXT_BUTTON_GO_TO_ARTIST:
630 CVideoDatabase database;
632 strPath = StringUtils::Format("videodb://musicvideos/artists/%ld/",
633 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 CGUIDialogVideoInfo::DeleteVideoItemFromDatabase(item);
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 = StringUtils::Format("musicdb://albums/%i/",params.GetAlbumId());
689 else if (params.GetArtistId() != -1)
691 path = StringUtils::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(CURL::Encode(GetProperty("search").asString()));
772 CStdString path = "musicsearch://" + search + "/";
773 m_history.ClearSearchHistory();
776 else if (m_vecItems->IsVirtualDirectoryRoot())
782 void CGUIWindowMusicNav::FrameMove()
784 static const int search_timeout = 2000;
785 // update our searching
786 if (m_searchTimer.IsRunning() && m_searchTimer.GetElapsedMilliseconds() > search_timeout)
788 m_searchTimer.Stop();
791 if (m_bDisplayEmptyDatabaseMessage)
792 SET_CONTROL_LABEL(CONTROL_LABELEMPTY,g_localizeStrings.Get(745)+'\n'+g_localizeStrings.Get(746));
794 SET_CONTROL_LABEL(CONTROL_LABELEMPTY,"");
795 CGUIWindowMusicBase::FrameMove();
798 void CGUIWindowMusicNav::AddSearchFolder()
800 // we use a general viewstate (and not our member) here as our
801 // current viewstate may be specific to some other folder, and
802 // we know we're in the root here
804 CGUIViewState* viewState = CGUIViewState::GetViewState(GetID(), items);
807 // add our remove the musicsearch source
808 VECSOURCES &sources = viewState->GetSources();
809 bool haveSearchSource = false;
810 bool needSearchSource = !GetProperty("search").empty() || !m_searchWithEdit; // we always need it if we don't have the edit control
811 for (IVECSOURCES it = sources.begin(); it != sources.end(); ++it)
813 CMediaSource& share = *it;
814 if (share.strPath == "musicsearch://")
816 haveSearchSource = true;
817 if (!needSearchSource)
824 if (!haveSearchSource && needSearchSource)
828 share.strName=g_localizeStrings.Get(137); // Search
829 share.strPath = "musicsearch://";
830 share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;
831 sources.push_back(share);
833 m_rootDir.SetSources(sources);
838 CStdString CGUIWindowMusicNav::GetStartFolder(const CStdString &dir)
840 if (dir.Equals("Genres"))
841 return "musicdb://genres/";
842 else if (dir.Equals("Artists"))
843 return "musicdb://artists/";
844 else if (dir.Equals("Albums"))
845 return "musicdb://albums/";
846 else if (dir.Equals("Singles"))
847 return "musicdb://singles/";
848 else if (dir.Equals("Songs"))
849 return "musicdb://songs/";
850 else if (dir.Equals("Top100"))
851 return "musicdb://top100/";
852 else if (dir.Equals("Top100Songs"))
853 return "musicdb://top100/songs/";
854 else if (dir.Equals("Top100Albums"))
855 return "musicdb://top100/albums/";
856 else if (dir.Equals("RecentlyAddedAlbums"))
857 return "musicdb://recentlyaddedalbums/";
858 else if (dir.Equals("RecentlyPlayedAlbums"))
859 return "musicdb://recentlyplayedalbums/";
860 else if (dir.Equals("Compilations"))
861 return "musicdb://compilations/";
862 else if (dir.Equals("Years"))
863 return "musicdb://years/";
864 return CGUIWindowMusicBase::GetStartFolder(dir);