Merge pull request #3819 from arnova/subtitles_for_stacks
[vuplus_xbmc] / xbmc / profiles / dialogs / GUIDialogProfileSettings.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 "GUIDialogProfileSettings.h"
22 #include "dialogs/GUIDialogFileBrowser.h"
23 #include "guilib/GUIKeyboardFactory.h"
24 #include "profiles/ProfilesManager.h"
25 #include "profiles/dialogs/GUIDialogLockSettings.h"
26 #include "guilib/GUIImage.h"
27 #include "guilib/GUIWindowManager.h"
28 #include "storage/MediaManager.h"
29 #include "Util.h"
30 #include "utils/URIUtils.h"
31 #include "GUIPassword.h"
32 #include "dialogs/GUIDialogYesNo.h"
33 #include "filesystem/Directory.h"
34 #include "filesystem/File.h"
35 #include "FileItem.h"
36 #include "settings/Settings.h"
37 #include "guilib/LocalizeStrings.h"
38 #include "TextureCache.h"
39
40 using namespace XFILE;
41
42 #define CONTROL_PROFILE_IMAGE       2
43 #define CONTROL_START              30
44
45 CGUIDialogProfileSettings::CGUIDialogProfileSettings(void)
46     : CGUIDialogSettings(WINDOW_DIALOG_PROFILE_SETTINGS, "ProfileSettings.xml")
47 {
48   m_bNeedSave = false;
49 }
50
51 CGUIDialogProfileSettings::~CGUIDialogProfileSettings(void)
52 {
53 }
54
55 bool CGUIDialogProfileSettings::OnMessage(CGUIMessage &message)
56 {
57   if (message.GetMessage() == GUI_MSG_CLICKED)
58   {
59     int iControl = message.GetSenderId();
60     if (iControl == 500)
61       Close();
62     if (iControl == 501)
63     {
64       m_bNeedSave = false;
65       Close();
66     }
67   }
68   return CGUIDialogSettings::OnMessage(message);
69 }
70
71 void CGUIDialogProfileSettings::OnWindowLoaded()
72 {
73   CGUIDialogSettings::OnWindowLoaded();
74   CGUIImage *pImage = (CGUIImage*)GetControl(2);
75   m_strDefaultImage = pImage ? pImage->GetFileName() : "";
76 }
77
78 void CGUIDialogProfileSettings::SetupPage()
79 {
80   CGUIDialogSettings::SetupPage();
81   SET_CONTROL_LABEL(1000,m_strName);
82   SET_CONTROL_LABEL(1001,m_strDirectory);
83   CGUIImage *pImage = (CGUIImage*)GetControl(2);
84   if (pImage)
85     pImage->SetFileName(!m_strThumb.empty() ? m_strThumb : m_strDefaultImage);
86 }
87
88 void CGUIDialogProfileSettings::CreateSettings()
89 {
90   // clear out any old settings
91   m_settings.clear();
92
93   AddButton(1,20093);
94   AddButton(2,20065);
95   if (!m_bIsDefault && m_bShowDetails)
96     AddButton(3,20070);
97
98   if (m_bShowDetails)
99     AddButton(4,20066);
100   if (!m_bShowDetails && m_locks.mode == LOCK_MODE_EVERYONE && CProfilesManager::Get().GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE)
101     AddButton(4,20066);
102
103   if (!m_bIsDefault && m_bShowDetails)
104   {
105     SettingInfo setting;
106     setting.id = 5;
107     setting.name = g_localizeStrings.Get(20060);
108     setting.data = &m_iDbMode;
109     setting.type = SettingInfo::SPIN;
110     setting.entry.push_back(make_pair(setting.entry.size(), g_localizeStrings.Get(20062)));
111     setting.entry.push_back(make_pair(setting.entry.size(), g_localizeStrings.Get(20063)));
112     setting.entry.push_back(make_pair(setting.entry.size(), g_localizeStrings.Get(20061)));
113     if (CProfilesManager::Get().GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE)
114       setting.entry.push_back(make_pair(setting.entry.size(), g_localizeStrings.Get(20107)));
115
116     m_settings.push_back(setting);
117
118     SettingInfo setting2;
119     setting2.id = 6;
120     setting2.name = g_localizeStrings.Get(20094);
121     setting2.data = &m_iSourcesMode;
122     setting2.type = SettingInfo::SPIN;
123     setting2.entry.push_back(make_pair(setting2.entry.size(), g_localizeStrings.Get(20062)));
124     setting2.entry.push_back(make_pair(setting2.entry.size(), g_localizeStrings.Get(20063)));
125     setting2.entry.push_back(make_pair(setting2.entry.size(), g_localizeStrings.Get(20061)));
126     if (CProfilesManager::Get().GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE)
127       setting2.entry.push_back(make_pair(setting2.entry.size(), g_localizeStrings.Get(20107)));
128
129     m_settings.push_back(setting2);
130   }
131 }
132
133 void CGUIDialogProfileSettings::OnSettingChanged(unsigned int num)
134 {
135   // setting has changed - update anything that needs it
136   if (num >= m_settings.size()) return;
137   OnSettingChanged(m_settings.at(num));
138 }
139
140 void CGUIDialogProfileSettings::OnSettingChanged(SettingInfo &setting)
141 {
142   // check and update anything that needs it
143   if (setting.id == 1)
144   {
145     if (CGUIKeyboardFactory::ShowAndGetInput(m_strName,g_localizeStrings.Get(20093),false))
146     {
147       m_bNeedSave = true;
148       SET_CONTROL_LABEL(1000,m_strName);
149     }
150   }
151   if (setting.id == 2)
152   {
153     CStdString strThumb;
154     VECSOURCES shares;
155     g_mediaManager.GetLocalDrives(shares);
156     CFileItemList items;
157     if (!m_strThumb.empty())
158     {
159       CFileItemPtr item(new CFileItem("thumb://Current", false));
160       item->SetArt("thumb", m_strThumb);
161       item->SetLabel(g_localizeStrings.Get(20016));
162       items.Add(item);
163     }
164     CFileItemPtr item(new CFileItem("thumb://None", false));
165     item->SetArt("thumb", m_strDefaultImage);
166     item->SetLabel(g_localizeStrings.Get(20018));
167     items.Add(item);
168     if (CGUIDialogFileBrowser::ShowAndGetImage(items,shares,g_localizeStrings.Get(1030),strThumb) &&
169         !strThumb.Equals("thumb://Current"))
170     {
171       m_bNeedSave = true;
172       m_strThumb = strThumb.Equals("thumb://None") ? "" : strThumb;
173
174       CGUIImage *pImage = (CGUIImage*)GetControl(2);
175       if (pImage)
176       {
177         pImage->SetFileName("");
178         pImage->SetInvalid();
179         pImage->SetFileName(!m_strThumb.empty() ? m_strThumb : m_strDefaultImage);
180       }
181     }
182   }
183   if (setting.id == 3)
184   {
185     if (OnProfilePath(m_strDirectory, m_bIsDefault))
186     {
187       m_bNeedSave = true;
188       SET_CONTROL_LABEL(1001,m_strDirectory);
189     }
190   }
191
192   if (setting.id == 4)
193   {
194     if (m_bShowDetails)
195     {
196       if (CProfilesManager::Get().GetMasterProfile().getLockMode() == LOCK_MODE_EVERYONE && !m_bIsDefault)
197       {
198         if (CGUIDialogYesNo::ShowAndGetInput(20066,20118,20119,20022))
199           g_passwordManager.SetMasterLockMode(false);
200         if (CProfilesManager::Get().GetMasterProfile().getLockMode() == LOCK_MODE_EVERYONE)
201           return;
202       }
203       if (CGUIDialogLockSettings::ShowAndGetLock(m_locks, m_bIsDefault ? 12360 : 20068, CProfilesManager::Get().GetMasterProfile().getLockMode() == LOCK_MODE_EVERYONE || m_bIsDefault))
204         m_bNeedSave = true;
205     }
206     else
207     {
208       if (CGUIDialogLockSettings::ShowAndGetLock(m_locks, m_bIsDefault ? 12360 : 20068, false, false))
209         m_bNeedSave = true;
210     }
211   }
212   if (setting.id > 4)
213     m_bNeedSave = true;
214 }
215
216 void CGUIDialogProfileSettings::OnCancel()
217 {
218   m_bNeedSave = false;
219 }
220
221 bool CGUIDialogProfileSettings::OnProfilePath(CStdString &dir, bool isDefault)
222 {
223   VECSOURCES shares;
224   CMediaSource share;
225   share.strName = "Profiles";
226   share.strPath = "special://masterprofile/profiles/";
227   shares.push_back(share);
228   CStdString strDirectory;
229   if (dir.empty())
230     strDirectory = share.strPath;
231   else
232     strDirectory = URIUtils::AddFileToFolder("special://masterprofile/", dir);
233   if (CGUIDialogFileBrowser::ShowAndGetDirectory(shares,g_localizeStrings.Get(657),strDirectory,true))
234   {
235     dir = strDirectory;
236     if (!isDefault)
237       dir.erase(0,24);
238     return true;
239   }
240   return false;
241 }
242
243 bool CGUIDialogProfileSettings::ShowForProfile(unsigned int iProfile, bool firstLogin)
244 {
245   CGUIDialogProfileSettings *dialog = (CGUIDialogProfileSettings *)g_windowManager.GetWindow(WINDOW_DIALOG_PROFILE_SETTINGS);
246   if (!dialog) return false;
247   if (iProfile == 0)
248     dialog->m_bIsDefault = true;
249   else
250     dialog->m_bIsDefault = false;
251   if (firstLogin && iProfile > CProfilesManager::Get().GetNumberOfProfiles())
252     return false;
253
254   dialog->m_bNeedSave = false;
255   dialog->m_bShowDetails = !firstLogin;
256   dialog->SetProperty("heading", g_localizeStrings.Get(firstLogin ? 20255 : 20067));
257
258   const CProfile *profile = CProfilesManager::Get().GetProfile(iProfile);
259
260   if (!profile)
261   { // defaults
262     dialog->m_strName.clear();
263     dialog->m_iDbMode = 2;
264     dialog->m_iSourcesMode = 2;
265     dialog->m_locks = CProfile::CLock();
266
267     bool bLock = CProfilesManager::Get().GetMasterProfile().getLockMode() != LOCK_MODE_EVERYONE && !g_passwordManager.bMasterUser;
268     dialog->m_locks.addonManager = bLock;
269     dialog->m_locks.settings = (bLock) ? LOCK_LEVEL::ALL : LOCK_LEVEL::NONE;
270     dialog->m_locks.files = bLock;
271
272     dialog->m_strDirectory.clear();
273     dialog->m_strThumb.clear();
274     // prompt for a name
275     if (!CGUIKeyboardFactory::ShowAndGetInput(dialog->m_strName,g_localizeStrings.Get(20093),false) || dialog->m_strName.empty())
276       return false;
277     // create a default path
278     CStdString defaultDir = URIUtils::AddFileToFolder("profiles",CUtil::MakeLegalFileName(dialog->m_strName));
279     URIUtils::AddSlashAtEnd(defaultDir);
280     CDirectory::Create(URIUtils::AddFileToFolder("special://masterprofile/", defaultDir));
281     // prompt for the user to change it if they want
282     CStdString userDir = defaultDir;
283     if (dialog->OnProfilePath(userDir, false)) // can't be the master user
284     {
285       if (!StringUtils::StartsWith(userDir, defaultDir)) // user chose a different folder
286         CDirectory::Remove(URIUtils::AddFileToFolder("special://masterprofile/", defaultDir));
287     }
288     dialog->m_strDirectory = userDir;
289     dialog->m_bNeedSave = true;
290   }
291   else
292   {
293     dialog->m_strName = profile->getName();
294     dialog->m_strThumb = profile->getThumb();
295     dialog->m_strDirectory = profile->getDirectory();
296     dialog->m_iDbMode = profile->canWriteDatabases()?0:1;
297     dialog->m_iSourcesMode = profile->canWriteSources()?0:1;
298     if (profile->hasDatabases())
299       dialog->m_iDbMode += 2;
300     if (profile->hasSources())
301       dialog->m_iSourcesMode += 2;
302
303     dialog->m_locks = profile->GetLocks();
304   }
305   dialog->DoModal();
306   if (dialog->m_bNeedSave)
307   {
308     if (iProfile >= CProfilesManager::Get().GetNumberOfProfiles())
309     {
310       if (dialog->m_strName.empty() || dialog->m_strDirectory.empty())
311         return false;
312       /*CStdString strLabel;
313       strLabel.Format(g_localizeStrings.Get(20047),dialog->m_strName);
314       if (!CGUIDialogYesNo::ShowAndGetInput(g_localizeStrings.Get(20058),strLabel,dialog->m_strDirectory,""))
315       {
316         CDirectory::Remove(URIUtils::AddFileToFolder(CProfilesManager::Get().GetUserDataFolder(), dialog->m_strDirectory));
317         return false;
318       }*/
319
320       // check for old profile settings
321       CProfile profile(dialog->m_strDirectory, dialog->m_strName, CProfilesManager::Get().GetNextProfileId());
322       CProfilesManager::Get().AddProfile(profile);
323       bool bExists = CFile::Exists(URIUtils::AddFileToFolder("special://masterprofile/",
324                                                           dialog->m_strDirectory+"/guisettings.xml"));
325
326       if (bExists)
327         if (!CGUIDialogYesNo::ShowAndGetInput(20058,20104,20105,20022))
328           bExists = false;
329
330       if (!bExists)
331       {
332         // copy masterprofile guisettings to new profile guisettings
333         // If the user selects 'start fresh', do nothing as a fresh
334         // guisettings.xml will be created on first profile use.
335         if (CGUIDialogYesNo::ShowAndGetInput(20058,20048,20102,20022,20044,20064))
336         {
337           CFile::Cache(URIUtils::AddFileToFolder("special://masterprofile/","guisettings.xml"),
338                        URIUtils::AddFileToFolder("special://masterprofile/",
339                                               dialog->m_strDirectory+"/guisettings.xml"));
340         }
341       }
342
343       bExists = CFile::Exists(URIUtils::AddFileToFolder("special://masterprofile/",
344                                                      dialog->m_strDirectory+"/sources.xml"));
345       if (bExists)
346         if (!CGUIDialogYesNo::ShowAndGetInput(20058,20106,20105,20022))
347           bExists = false;
348
349       if (!bExists)
350       {
351         if ((dialog->m_iSourcesMode & 2) == 2)
352           // prompt user to copy masterprofile's sources.xml file
353           // If 'start fresh' (no) is selected, do nothing.
354           if (CGUIDialogYesNo::ShowAndGetInput(20058,20071,20102,20022,20044,20064))
355           {
356             CFile::Cache(URIUtils::AddFileToFolder("special://masterprofile/","sources.xml"),
357                          URIUtils::AddFileToFolder("special://masterprofile/",
358                          dialog->m_strDirectory+"/sources.xml"));
359           }
360       }
361     }
362
363     /*if (!dialog->m_bIsNewUser)
364       if (!CGUIDialogYesNo::ShowAndGetInput(20067,20103,20022,20022))
365         return false;*/
366
367     CProfile *profile = CProfilesManager::Get().GetProfile(iProfile);
368     assert(profile);
369     profile->setName(dialog->m_strName);
370     profile->setDirectory(dialog->m_strDirectory);
371     profile->setThumb(dialog->m_strThumb);
372     profile->setWriteDatabases(!((dialog->m_iDbMode & 1) == 1));
373     profile->setWriteSources(!((dialog->m_iSourcesMode & 1) == 1));
374     profile->setDatabases((dialog->m_iDbMode & 2) == 2);
375     profile->setSources((dialog->m_iSourcesMode & 2) == 2);
376     profile->SetLocks(dialog->m_locks);
377
378     CProfilesManager::Get().Save();
379     return true;
380   }
381
382   return !dialog->m_bNeedSave;
383 }
384