Merge pull request #5039 from CEikermann/patch-1
[vuplus_xbmc] / xbmc / windows / GUIWindowLoginScreen.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 "system.h"
22 #include "Application.h"
23 #include "ApplicationMessenger.h"
24 #include "GUIWindowLoginScreen.h"
25 #include "profiles/Profile.h"
26 #include "profiles/ProfilesManager.h"
27 #include "profiles/dialogs/GUIDialogProfileSettings.h"
28 #include "profiles/windows/GUIWindowSettingsProfile.h"
29 #include "dialogs/GUIDialogContextMenu.h"
30 #include "GUIPassword.h"
31 #ifdef HAS_JSONRPC
32 #include "interfaces/json-rpc/JSONRPC.h"
33 #endif
34 #include "interfaces/Builtins.h"
35 #include "utils/Weather.h"
36 #include "utils/StringUtils.h"
37 #include "network/Network.h"
38 #include "addons/Skin.h"
39 #include "guilib/GUIMessage.h"
40 #include "GUIUserMessages.h"
41 #include "guilib/GUIWindowManager.h"
42 #include "guilib/StereoscopicsManager.h"
43 #include "dialogs/GUIDialogOK.h"
44 #include "settings/Settings.h"
45 #include "FileItem.h"
46 #include "guilib/Key.h"
47 #include "guilib/LocalizeStrings.h"
48 #include "addons/AddonManager.h"
49 #include "view/ViewState.h"
50
51 #define CONTROL_BIG_LIST               52
52 #define CONTROL_LABEL_HEADER            2
53 #define CONTROL_LABEL_SELECTED_PROFILE  3
54
55 CGUIWindowLoginScreen::CGUIWindowLoginScreen(void)
56 : CGUIWindow(WINDOW_LOGIN_SCREEN, "LoginScreen.xml")
57 {
58   watch.StartZero();
59   m_vecItems = new CFileItemList;
60   m_iSelectedItem = -1;
61   m_loadType = KEEP_IN_MEMORY;
62 }
63
64 CGUIWindowLoginScreen::~CGUIWindowLoginScreen(void)
65 {
66   delete m_vecItems;
67 }
68
69 bool CGUIWindowLoginScreen::OnMessage(CGUIMessage& message)
70 {
71   switch ( message.GetMessage() )
72   {
73   case GUI_MSG_WINDOW_DEINIT:
74     {
75       m_vecItems->Clear();
76     }
77     break;
78
79   case GUI_MSG_CLICKED:
80     {
81       int iControl = message.GetSenderId();
82       if (iControl == CONTROL_BIG_LIST)
83       {
84         int iAction = message.GetParam1();
85
86         // iItem is checked for validity inside these routines
87         if (iAction == ACTION_CONTEXT_MENU || iAction == ACTION_MOUSE_RIGHT_CLICK)
88         {
89           int iItem = m_viewControl.GetSelectedItem();
90           bool bResult = OnPopupMenu(m_viewControl.GetSelectedItem());
91           if (bResult)
92           {
93             Update();
94             CGUIMessage msg(GUI_MSG_ITEM_SELECT,GetID(),CONTROL_BIG_LIST,iItem);
95             OnMessage(msg);
96           }
97
98           return bResult;
99         }
100         else if (iAction == ACTION_SELECT_ITEM || iAction == ACTION_MOUSE_LEFT_CLICK)
101         {
102           int iItem = m_viewControl.GetSelectedItem();
103           bool bCanceled;
104           bool bOkay = g_passwordManager.IsProfileLockUnlocked(iItem, bCanceled);
105
106           if (bOkay)
107           {
108             if (iItem >= 0)
109               LoadProfile((unsigned int)iItem);
110           }
111           else
112           {
113             if (!bCanceled && iItem != 0)
114               CGUIDialogOK::ShowAndGetInput(20068,20117,20022,20022);
115           }
116         }
117       }
118     }
119     break;
120     case GUI_MSG_SETFOCUS:
121     {
122       if (m_viewControl.HasControl(message.GetControlId()) && m_viewControl.GetCurrentControl() != message.GetControlId())
123       {
124         m_viewControl.SetFocused();
125         return true;
126       }
127     }
128     default:
129     break;
130
131   }
132
133   return CGUIWindow::OnMessage(message);
134 }
135
136 bool CGUIWindowLoginScreen::OnAction(const CAction &action)
137 {
138   // don't allow built in actions to act here except shutdown related ones.
139   // this forces only navigation type actions to be performed.
140   if (action.GetID() == ACTION_BUILT_IN_FUNCTION)
141   {
142     CStdString actionName = action.GetName();
143     StringUtils::ToLower(actionName);
144     if (actionName.find("shutdown") != std::string::npos)
145       CBuiltins::Execute(action.GetName());
146     return true;
147   }
148   return CGUIWindow::OnAction(action);
149 }
150
151 bool CGUIWindowLoginScreen::OnBack(int actionID)
152 {
153   // no escape from the login window
154   return false;
155 }
156
157 void CGUIWindowLoginScreen::FrameMove()
158 {
159   if (GetFocusedControlID() == CONTROL_BIG_LIST && g_windowManager.GetTopMostModalDialogID() == WINDOW_INVALID)
160     if (m_viewControl.HasControl(CONTROL_BIG_LIST))
161       m_iSelectedItem = m_viewControl.GetSelectedItem();
162   CStdString strLabel = StringUtils::Format(g_localizeStrings.Get(20114), m_iSelectedItem+1, CProfilesManager::Get().GetNumberOfProfiles());
163   SET_CONTROL_LABEL(CONTROL_LABEL_SELECTED_PROFILE,strLabel);
164   CGUIWindow::FrameMove();
165 }
166
167 void CGUIWindowLoginScreen::OnInitWindow()
168 {
169   m_iSelectedItem = (int)CProfilesManager::Get().GetLastUsedProfileIndex();
170   // Update list/thumb control
171   m_viewControl.SetCurrentView(DEFAULT_VIEW_LIST);
172   Update();
173   m_viewControl.SetFocused();
174   SET_CONTROL_LABEL(CONTROL_LABEL_HEADER,g_localizeStrings.Get(20115));
175   SET_CONTROL_VISIBLE(CONTROL_BIG_LIST);
176
177   CGUIWindow::OnInitWindow();
178 }
179
180 void CGUIWindowLoginScreen::OnWindowLoaded()
181 {
182   CGUIWindow::OnWindowLoaded();
183   m_viewControl.Reset();
184   m_viewControl.SetParentWindow(GetID());
185   m_viewControl.AddView(GetControl(CONTROL_BIG_LIST));
186 }
187
188 void CGUIWindowLoginScreen::OnWindowUnload()
189 {
190   CGUIWindow::OnWindowUnload();
191   m_viewControl.Reset();
192 }
193
194 void CGUIWindowLoginScreen::Update()
195 {
196   m_vecItems->Clear();
197   for (unsigned int i=0;i<CProfilesManager::Get().GetNumberOfProfiles(); ++i)
198   {
199     const CProfile *profile = CProfilesManager::Get().GetProfile(i);
200     CFileItemPtr item(new CFileItem(profile->getName()));
201     CStdString strLabel;
202     if (profile->getDate().empty())
203       strLabel = g_localizeStrings.Get(20113);
204     else
205       strLabel = StringUtils::Format(g_localizeStrings.Get(20112).c_str(), profile->getDate().c_str());
206     item->SetLabel2(strLabel);
207     item->SetArt("thumb", profile->getThumb());
208     if (profile->getThumb().empty() || profile->getThumb().Equals("-"))
209       item->SetArt("thumb", "unknown-user.png");
210     item->SetLabelPreformated(true);
211     m_vecItems->Add(item);
212   }
213   m_viewControl.SetItems(*m_vecItems);
214   m_viewControl.SetSelectedItem(m_iSelectedItem);
215 }
216
217 bool CGUIWindowLoginScreen::OnPopupMenu(int iItem)
218 {
219   if ( iItem < 0 || iItem >= m_vecItems->Size() ) return false;
220
221   bool bSelect = m_vecItems->Get(iItem)->IsSelected();
222   // mark the item
223   m_vecItems->Get(iItem)->Select(true);
224
225   CContextButtons choices;
226   choices.Add(1, 20067);
227 /*  if (m_viewControl.GetSelectedItem() != 0) // no deleting the default profile
228     choices.Add(2, 117); */
229   if (iItem == 0 && g_passwordManager.iMasterLockRetriesLeft == 0)
230     choices.Add(3, 12334);
231
232   int choice = CGUIDialogContextMenu::ShowAndGetChoice(choices);
233   if (choice == 3)
234   {
235     if (g_passwordManager.CheckLock(CProfilesManager::Get().GetMasterProfile().getLockMode(),CProfilesManager::Get().GetMasterProfile().getLockCode(),20075))
236       g_passwordManager.iMasterLockRetriesLeft = CSettings::Get().GetInt("masterlock.maxretries");
237     else // be inconvenient
238       CApplicationMessenger::Get().Shutdown();
239
240     return true;
241   }
242   
243   if (!g_passwordManager.IsMasterLockUnlocked(true))
244     return false;
245
246   if (choice == 1)
247     CGUIDialogProfileSettings::ShowForProfile(m_viewControl.GetSelectedItem());
248   if (choice == 2)
249   {
250     int iDelete = m_viewControl.GetSelectedItem();
251     m_viewControl.Clear();
252     if (iDelete >= 0)
253       CProfilesManager::Get().DeleteProfile((size_t)iDelete);
254     Update();
255     m_viewControl.SetSelectedItem(0);
256   }
257   //NOTE: this can potentially (de)select the wrong item if the filelisting has changed because of an action above.
258   if (iItem < (int)CProfilesManager::Get().GetNumberOfProfiles())
259     m_vecItems->Get(iItem)->Select(bSelect);
260
261   return (choice > 0);
262 }
263
264 CFileItemPtr CGUIWindowLoginScreen::GetCurrentListItem(int offset)
265 {
266   int item = m_viewControl.GetSelectedItem();
267   if (item < 0 || !m_vecItems->Size()) return CFileItemPtr();
268
269   item = (item + offset) % m_vecItems->Size();
270   if (item < 0) item += m_vecItems->Size();
271   return m_vecItems->Get(item);
272 }
273
274 void CGUIWindowLoginScreen::LoadProfile(unsigned int profile)
275 {
276   // stop service addons and give it some time before we start it again
277   ADDON::CAddonMgr::Get().StopServices(true);
278
279   // stop PVR related services
280   g_application.StopPVRManager();
281
282   if (profile != 0 || !CProfilesManager::Get().IsMasterProfile())
283   {
284     g_application.getNetwork().NetworkMessage(CNetwork::SERVICES_DOWN,1);
285     CProfilesManager::Get().LoadProfile(profile);
286   }
287   else
288   {
289     CGUIWindow* pWindow = g_windowManager.GetWindow(WINDOW_HOME);
290     if (pWindow)
291       pWindow->ResetControlStates();
292   }
293   g_application.getNetwork().NetworkMessage(CNetwork::SERVICES_UP,1);
294
295   CProfilesManager::Get().UpdateCurrentProfileDate();
296   CProfilesManager::Get().Save();
297
298   if (CProfilesManager::Get().GetLastUsedProfileIndex() != profile)
299   {
300     g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO);
301     g_playlistPlayer.ClearPlaylist(PLAYLIST_MUSIC);
302     g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_NONE);
303   }
304
305   // reload the add-ons, or we will first load all add-ons from the master account without checking disabled status
306   ADDON::CAddonMgr::Get().ReInit();
307
308   g_weatherManager.Refresh();
309   g_application.SetLoggingIn(true);
310
311 #ifdef HAS_JSONRPC
312   JSONRPC::CJSONRPC::Initialize();
313 #endif
314
315   // start services which should run on login 
316   ADDON::CAddonMgr::Get().StartServices(false);
317
318   // start PVR related services
319   g_application.StartPVRManager();
320
321   g_windowManager.ChangeActiveWindow(g_SkinInfo->GetFirstWindow());
322
323   g_application.UpdateLibraries();
324   CStereoscopicsManager::Get().Initialize();
325 }