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 "FavouritesDirectory.h"
24 #include "profiles/ProfilesManager.h"
26 #include "utils/XBMCTinyXML.h"
27 #include "utils/log.h"
28 #include "utils/StringUtils.h"
29 #include "utils/URIUtils.h"
30 #include "settings/AdvancedSettings.h"
31 #include "video/VideoInfoTag.h"
32 #include "music/tags/MusicInfoTag.h"
39 bool CFavouritesDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
44 if (url.GetProtocol() == "favourites")
46 return Load(items); //load the default favourite files
48 return LoadFavourites(strPath, items); //directly load the given file
51 bool CFavouritesDirectory::Exists(const char* strPath)
55 if (url.GetProtocol() == "favourites")
57 return XFILE::CFile::Exists("special://xbmc/system/favourites.xml")
58 || XFILE::CFile::Exists(URIUtils::AddFileToFolder(CProfilesManager::Get().GetProfileUserDataFolder(), "favourites.xml"));
60 return XFILE::CFile::Exists(strPath); //directly load the given file
63 bool CFavouritesDirectory::Load(CFileItemList &items)
66 CStdString favourites;
68 favourites = "special://xbmc/system/favourites.xml";
69 if(XFILE::CFile::Exists(favourites))
70 CFavouritesDirectory::LoadFavourites(favourites, items);
72 CLog::Log(LOGDEBUG, "CFavourites::Load - no system favourites found, skipping");
73 favourites = URIUtils::AddFileToFolder(CProfilesManager::Get().GetProfileUserDataFolder(), "favourites.xml");
74 if(XFILE::CFile::Exists(favourites))
75 CFavouritesDirectory::LoadFavourites(favourites, items);
77 CLog::Log(LOGDEBUG, "CFavourites::Load - no userdata favourites found, skipping");
82 bool CFavouritesDirectory::LoadFavourites(const CStdString& strPath, CFileItemList& items)
85 if (!doc.LoadFile(strPath))
87 CLog::Log(LOGERROR, "Unable to load %s (row %i column %i)", strPath.c_str(), doc.Row(), doc.Column());
90 TiXmlElement *root = doc.RootElement();
91 if (!root || strcmp(root->Value(), "favourites"))
93 CLog::Log(LOGERROR, "Favourites.xml doesn't contain the <favourites> root element");
97 TiXmlElement *favourite = root->FirstChildElement("favourite");
101 // <favourite name="Cool Video" thumb="foo.jpg">PlayMedia(c:\videos\cool_video.avi)</favourite>
102 // <favourite name="My Album" thumb="bar.tbn">ActivateWindow(MyMusic,c:\music\my album)</favourite>
103 // <favourite name="Apple Movie Trailers" thumb="path_to_thumb.png">RunScript(special://xbmc/scripts/apple movie trailers/default.py)</favourite>
104 const char *name = favourite->Attribute("name");
105 const char *thumb = favourite->Attribute("thumb");
106 if (name && favourite->FirstChild())
108 if(!items.Contains(favourite->FirstChild()->Value()))
110 CFileItemPtr item(new CFileItem(name));
111 item->SetPath(favourite->FirstChild()->Value());
112 if (thumb) item->SetArt("thumb", thumb);
116 favourite = favourite->NextSiblingElement("favourite");
121 bool CFavouritesDirectory::Save(const CFileItemList &items)
123 CStdString favourites;
125 TiXmlElement xmlRootElement("favourites");
126 TiXmlNode *rootNode = doc.InsertEndChild(xmlRootElement);
127 if (!rootNode) return false;
129 for (int i = 0; i < items.Size(); i++)
131 const CFileItemPtr item = items[i];
132 TiXmlElement favNode("favourite");
133 favNode.SetAttribute("name", item->GetLabel().c_str());
134 if (item->HasArt("thumb"))
135 favNode.SetAttribute("thumb", item->GetArt("thumb").c_str());
136 TiXmlText execute(item->GetPath());
137 favNode.InsertEndChild(execute);
138 rootNode->InsertEndChild(favNode);
141 favourites = URIUtils::AddFileToFolder(CProfilesManager::Get().GetProfileUserDataFolder(), "favourites.xml");
142 return doc.SaveFile(favourites);
145 bool CFavouritesDirectory::AddOrRemove(CFileItem *item, int contextWindow)
147 if (!item) return false;
153 CStdString executePath(GetExecutePath(*item, contextWindow));
155 CFileItemPtr match = items.Get(executePath);
158 items.Remove(match.get());
161 { // create our new favourite item
162 CFileItemPtr favourite(new CFileItem(item->GetLabel()));
163 if (item->GetLabel().empty())
164 favourite->SetLabel(CUtil::GetTitleFromPath(item->GetPath(), item->m_bIsFolder));
165 favourite->SetArt("thumb", item->GetArt("thumb"));
166 favourite->SetPath(executePath);
167 items.Add(favourite);
170 // and save our list again
174 bool CFavouritesDirectory::IsFavourite(CFileItem *item, int contextWindow)
177 if (!Load(items)) return false;
179 return items.Contains(GetExecutePath(*item, contextWindow));
182 CStdString CFavouritesDirectory::GetExecutePath(const CFileItem &item, int contextWindow)
184 return GetExecutePath(item, StringUtils::Format("%i", contextWindow));
187 CStdString CFavouritesDirectory::GetExecutePath(const CFileItem &item, const std::string &contextWindow)
190 if (item.m_bIsFolder && (g_advancedSettings.m_playlistAsFolders ||
191 !(item.IsSmartPlayList() || item.IsPlayList())))
193 if (!contextWindow.empty())
194 execute = StringUtils::Format("ActivateWindow(%s,%s,return)", contextWindow.c_str(), StringUtils::Paramify(item.GetPath()).c_str());
196 /* TODO:STRING_CLEANUP */
197 else if (item.IsScript() && item.GetPath().size() > 9) // plugin://<foo>
198 execute = StringUtils::Format("RunScript(%s)", StringUtils::Paramify(item.GetPath().substr(9)).c_str());
199 else if (item.IsAndroidApp() && item.GetPath().size() > 26) // androidapp://sources/apps/<foo>
200 execute = StringUtils::Format("StartAndroidActivity(%s)", StringUtils::Paramify(item.GetPath().substr(26)).c_str());
201 else // assume a media file
203 if (item.IsVideoDb() && item.HasVideoInfoTag())
204 execute = StringUtils::Format("PlayMedia(%s)", StringUtils::Paramify(item.GetVideoInfoTag()->m_strFileNameAndPath).c_str());
205 else if (item.IsMusicDb() && item.HasMusicInfoTag())
206 execute = StringUtils::Format("PlayMedia(%s)", StringUtils::Paramify(item.GetMusicInfoTag()->GetURL()).c_str());
208 execute = StringUtils::Format("PlayMedia(%s)", StringUtils::Paramify(item.GetPath()).c_str());