[cstdstring] demise Format, replacing with StringUtils::Format
[vuplus_xbmc] / xbmc / music / dialogs / GUIDialogSongInfo.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
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)
8  *  any later version.
9  *
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.
14  *
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/>.
18  *
19  */
20
21 #include "GUIDialogSongInfo.h"
22 #include "utils/URIUtils.h"
23 #include "utils/StringUtils.h"
24 #include "dialogs/GUIDialogFileBrowser.h"
25 #include "GUIPassword.h"
26 #include "GUIUserMessages.h"
27 #include "music/MusicDatabase.h"
28 #include "music/windows/GUIWindowMusicBase.h"
29 #include "music/tags/MusicInfoTag.h"
30 #include "guilib/GUIWindowManager.h"
31 #include "guilib/Key.h"
32 #include "filesystem/File.h"
33 #include "filesystem/CurlFile.h"
34 #include "FileItem.h"
35 #include "settings/AdvancedSettings.h"
36 #include "settings/MediaSourceSettings.h"
37 #include "settings/Settings.h"
38 #include "guilib/LocalizeStrings.h"
39 #include "TextureCache.h"
40 #include "music/Album.h"
41 #include "storage/MediaManager.h"
42 #include "GUIDialogMusicInfo.h"
43
44 using namespace XFILE;
45
46 #define CONTROL_OK        10
47 #define CONTROL_CANCEL    11
48 #define CONTROL_ALBUMINFO 12
49 #define CONTROL_GETTHUMB  13
50
51 CGUIDialogSongInfo::CGUIDialogSongInfo(void)
52     : CGUIDialog(WINDOW_DIALOG_SONG_INFO, "DialogSongInfo.xml")
53     , m_song(new CFileItem)
54 {
55   m_cancelled = false;
56   m_needsUpdate = false;
57   m_startRating = -1;
58   m_loadType = KEEP_IN_MEMORY;
59 }
60
61 CGUIDialogSongInfo::~CGUIDialogSongInfo(void)
62 {
63 }
64
65 bool CGUIDialogSongInfo::OnMessage(CGUIMessage& message)
66 {
67   switch (message.GetMessage())
68   {
69   case GUI_MSG_WINDOW_DEINIT:
70     {
71       if (!m_cancelled && m_startRating != m_song->GetMusicInfoTag()->GetRating())
72       {
73         CMusicDatabase db;
74         if (db.Open())      // OpenForWrite() ?
75         {
76           db.SetSongRating(m_song->GetPath(), m_song->GetMusicInfoTag()->GetRating());
77           db.Close();
78         }
79         m_needsUpdate = true;
80       }
81       else
82       { // cancelled - reset the song rating
83         SetRating(m_startRating);
84         m_needsUpdate = false;
85       }
86       break;
87     }
88   case GUI_MSG_WINDOW_INIT:
89     m_cancelled = false;
90     break;
91
92   case GUI_MSG_CLICKED:
93     {
94       int iControl = message.GetSenderId();
95       if (iControl == CONTROL_CANCEL)
96       {
97         m_cancelled = true;
98         Close();
99         return true;
100       }
101       else if (iControl == CONTROL_OK)
102       {
103         m_cancelled = false;
104         Close();
105         return true;
106       }
107       else if (iControl == CONTROL_ALBUMINFO)
108       {
109         CGUIWindowMusicBase *window = (CGUIWindowMusicBase *)g_windowManager.GetWindow(WINDOW_MUSIC_NAV);
110         if (window)
111         {
112           CFileItem item(*m_song);
113           CStdString path = StringUtils::Format("musicdb://albums/%li",m_albumId);
114           item.SetPath(path);
115           item.m_bIsFolder = true;
116           window->OnInfo(&item, true);
117         }
118         return true;
119       }
120       else if (iControl == CONTROL_GETTHUMB)
121       {
122         OnGetThumb();
123         return true;
124       }
125     }
126     break;
127   }
128
129   return CGUIDialog::OnMessage(message);
130 }
131
132 bool CGUIDialogSongInfo::OnAction(const CAction &action)
133 {
134   char rating = m_song->GetMusicInfoTag()->GetRating();
135   if (action.GetID() == ACTION_INCREASE_RATING)
136   {
137     if (rating < '5')
138       SetRating(rating + 1);
139     return true;
140   }
141   else if (action.GetID() == ACTION_DECREASE_RATING)
142   {
143     if (rating > '0')
144       SetRating(rating - 1);
145     return true;
146   }
147   else if (action.GetID() == ACTION_SHOW_INFO)
148   {
149     Close();
150     return true;
151   }
152   return CGUIDialog::OnAction(action);
153 }
154
155 bool CGUIDialogSongInfo::OnBack(int actionID)
156 {
157   m_cancelled = true;
158   return CGUIDialog::OnBack(actionID);
159 }
160
161 void CGUIDialogSongInfo::OnInitWindow()
162 {
163   CMusicDatabase db;
164   db.Open();
165
166   // no known db info - check if parent dir is an album
167   if (m_song->GetMusicInfoTag()->GetDatabaseId() == -1)
168   {
169     CStdString path = URIUtils::GetDirectory(m_song->GetPath());
170     m_albumId = db.GetAlbumIdByPath(path);
171   }
172   else
173   {
174     CAlbum album;
175     db.GetAlbumFromSong(m_song->GetMusicInfoTag()->GetDatabaseId(),album);
176     m_albumId = album.idAlbum;
177   }
178   CONTROL_ENABLE_ON_CONDITION(CONTROL_ALBUMINFO, m_albumId > -1);
179
180   CGUIDialog::OnInitWindow();
181 }
182
183 void CGUIDialogSongInfo::SetRating(char rating)
184 {
185   if (rating < '0') rating = '0';
186   if (rating > '5') rating = '5';
187   if (rating != m_song->GetMusicInfoTag()->GetRating())
188   {
189     m_song->GetMusicInfoTag()->SetRating(rating);
190     // send a message to all windows to tell them to update the fileitem (eg playlistplayer, media windows)
191     CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE_ITEM, 0, m_song);
192     g_windowManager.SendMessage(msg);
193   }
194 }
195
196 void CGUIDialogSongInfo::SetSong(CFileItem *item)
197 {
198   *m_song = *item;
199   m_song->LoadMusicTag();
200   m_startRating = m_song->GetMusicInfoTag()->GetRating();
201   MUSIC_INFO::CMusicInfoLoader::LoadAdditionalTagInfo(m_song.get());
202    // set artist thumb as well
203   CMusicDatabase db;
204   db.Open();
205   if (item->IsMusicDb())
206   {
207     std::vector<int> artists;
208     CVariant artistthumbs;
209     db.GetArtistsBySong(item->GetMusicInfoTag()->GetDatabaseId(), true, artists);
210     for (std::vector<int>::const_iterator artistId = artists.begin(); artistId != artists.end(); ++artistId)
211     {
212       std::string thumb = db.GetArtForItem(*artistId, "artist", "thumb");
213       if (!thumb.empty())
214         artistthumbs.push_back(thumb);
215     }
216     if (artistthumbs.size())
217     {
218       m_song->SetProperty("artistthumbs", artistthumbs);
219       m_song->SetProperty("artistthumb", artistthumbs[0]);
220     }
221   }
222   else if (m_song->HasMusicInfoTag() && !m_song->GetMusicInfoTag()->GetArtist().empty())
223   {
224     int idArtist = db.GetArtistByName(m_song->GetMusicInfoTag()->GetArtist()[0]);
225     std::string thumb = db.GetArtForItem(idArtist, "artist", "thumb");
226     if (!thumb.empty())
227       m_song->SetProperty("artistthumb", thumb);
228   }
229   m_needsUpdate = false;
230 }
231
232 CFileItemPtr CGUIDialogSongInfo::GetCurrentListItem(int offset)
233 {
234   return m_song;
235 }
236
237 bool CGUIDialogSongInfo::DownloadThumbnail(const CStdString &thumbFile)
238 {
239   // TODO: Obtain the source...
240   CStdString source;
241   CCurlFile http;
242   http.Download(source, thumbFile);
243   return true;
244 }
245
246 // Get Thumb from user choice.
247 // Options are:
248 // 1.  Current thumb
249 // 2.  AllMusic.com thumb
250 // 3.  Local thumb
251 // 4.  No thumb (if no Local thumb is available)
252
253 // TODO: Currently no support for "embedded thumb" as there is no easy way to grab it
254 //       without sending a file that has this as it's album to this class
255 void CGUIDialogSongInfo::OnGetThumb()
256 {
257   CFileItemList items;
258
259
260   // Grab the thumbnail from the web
261   /*
262   CStdString thumbFromWeb;
263   thumbFromWeb = URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath, "allmusicThumb.jpg");
264   if (DownloadThumbnail(thumbFromWeb))
265   {
266     CFileItemPtr item(new CFileItem("thumb://allmusic.com", false));
267     item->SetArt("thumb", thumbFromWeb);
268     item->SetLabel(g_localizeStrings.Get(20055));
269     items.Add(item);
270   }*/
271
272   // Current thumb
273   if (CFile::Exists(m_song->GetArt("thumb")))
274   {
275     CFileItemPtr item(new CFileItem("thumb://Current", false));
276     item->SetArt("thumb", m_song->GetArt("thumb"));
277     item->SetLabel(g_localizeStrings.Get(20016));
278     items.Add(item);
279   }
280
281   // local thumb
282   CStdString cachedLocalThumb;
283   CStdString localThumb(m_song->GetUserMusicThumb(true));
284   if (m_song->IsMusicDb())
285   {
286     CFileItem item(m_song->GetMusicInfoTag()->GetURL(), false);
287     localThumb = item.GetUserMusicThumb(true);
288   }
289   if (CFile::Exists(localThumb))
290   {
291     CFileItemPtr item(new CFileItem("thumb://Local", false));
292     item->SetArt("thumb", localThumb);
293     item->SetLabel(g_localizeStrings.Get(20017));
294     items.Add(item);
295   }
296   else
297   { // no local thumb exists, so we are just using the allmusic.com thumb or cached thumb
298     // which is probably the allmusic.com thumb.  These could be wrong, so allow the user
299     // to delete the incorrect thumb
300     CFileItemPtr item(new CFileItem("thumb://None", false));
301     item->SetArt("thumb", "DefaultAlbumCover.png");
302     item->SetLabel(g_localizeStrings.Get(20018));
303     items.Add(item);
304   }
305
306   CStdString result;
307   VECSOURCES sources(*CMediaSourceSettings::Get().GetSources("music"));
308   CGUIDialogMusicInfo::AddItemPathToFileBrowserSources(sources, *m_song);
309   g_mediaManager.GetLocalDrives(sources);
310   if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(1030), result))
311     return;   // user cancelled
312
313   if (result == "thumb://Current")
314     return;   // user chose the one they have
315
316   // delete the thumbnail if that's what the user wants, else overwrite with the
317   // new thumbnail
318
319   CStdString newThumb;
320   if (result == "thumb://None")
321     newThumb = "-";
322   else if (result == "thumb://allmusic.com")
323     newThumb.clear();
324   else if (result == "thumb://Local")
325     newThumb = localThumb;
326   else
327     newThumb = result;
328
329   // update thumb in the database
330   CMusicDatabase db;
331   if (db.Open())
332   {
333     db.SetArtForItem(m_song->GetMusicInfoTag()->GetDatabaseId(), m_song->GetMusicInfoTag()->GetType(), "thumb", newThumb);
334     db.Close();
335   }
336
337   m_song->SetArt("thumb", newThumb);
338
339   // tell our GUI to completely reload all controls (as some of them
340   // are likely to have had this image in use so will need refreshing)
341   CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_REFRESH_THUMBS);
342   g_windowManager.SendMessage(msg);
343
344 //  m_hasUpdatedThumb = true;
345 }