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 "GUIDialogGamepad.h"
22 #include "utils/md5.h"
23 #include "utils/StringUtils.h"
24 #include "guilib/GUIAudioManager.h"
25 #include "guilib/GUIWindowManager.h"
26 #include "GUIDialogOK.h"
27 #include "utils/StringUtils.h"
28 #include "guilib/Key.h"
29 #include "guilib/LocalizeStrings.h"
31 CGUIDialogGamepad::CGUIDialogGamepad(void)
32 : CGUIDialogBoxBase(WINDOW_DIALOG_GAMEPAD, "DialogGamepad.xml")
38 m_bUserInputCleanup = true;
41 CGUIDialogGamepad::~CGUIDialogGamepad(void)
44 bool CGUIDialogGamepad::OnAction(const CAction &action)
46 if ((action.GetButtonCode() >= KEY_BUTTON_A &&
47 action.GetButtonCode() <= KEY_BUTTON_RIGHT_TRIGGER) ||
48 (action.GetButtonCode() >= KEY_BUTTON_DPAD_UP &&
49 action.GetButtonCode() <= KEY_BUTTON_DPAD_RIGHT) ||
50 (action.GetID() >= ACTION_MOVE_LEFT &&
51 action.GetID() <= ACTION_MOVE_DOWN) ||
52 action.GetID() == ACTION_PLAYER_PLAY
55 switch (action.GetButtonCode())
57 case KEY_BUTTON_A : m_strUserInput += "A"; break;
58 case KEY_BUTTON_B : m_strUserInput += "B"; break;
59 case KEY_BUTTON_X : m_strUserInput += "X"; break;
60 case KEY_BUTTON_Y : m_strUserInput += "Y"; break;
61 case KEY_BUTTON_BLACK : m_strUserInput += "K"; break;
62 case KEY_BUTTON_WHITE : m_strUserInput += "W"; break;
63 case KEY_BUTTON_LEFT_TRIGGER : m_strUserInput += "("; break;
64 case KEY_BUTTON_RIGHT_TRIGGER : m_strUserInput += ")"; break;
65 case KEY_BUTTON_DPAD_UP : m_strUserInput += "U"; break;
66 case KEY_BUTTON_DPAD_DOWN : m_strUserInput += "D"; break;
67 case KEY_BUTTON_DPAD_LEFT : m_strUserInput += "L"; break;
68 case KEY_BUTTON_DPAD_RIGHT : m_strUserInput += "R"; break;
70 switch (action.GetID())
72 case ACTION_MOVE_LEFT: m_strUserInput += "L"; break;
73 case ACTION_MOVE_RIGHT: m_strUserInput += "R"; break;
74 case ACTION_MOVE_UP: m_strUserInput += "U"; break;
75 case ACTION_MOVE_DOWN: m_strUserInput += "D"; break;
76 case ACTION_PLAYER_PLAY: m_strUserInput += "P"; break;
83 CStdString strHiddenInput(m_strUserInput);
84 for (int i = 0; i < (int)strHiddenInput.size(); i++)
86 strHiddenInput[i] = m_cHideInputChar;
88 SetLine(2, strHiddenInput);
91 else if (action.GetButtonCode() == KEY_BUTTON_BACK || action.GetID() == ACTION_PREVIOUS_MENU || action.GetID() == ACTION_NAV_BACK)
96 m_bHideInputChars = true;
100 else if (action.GetButtonCode() == KEY_BUTTON_START || action.GetID() == ACTION_SELECT_ITEM)
102 m_bConfirmed = false;
105 CStdString md5pword2;
106 XBMC::XBMC_MD5 md5state;
107 md5state.append(m_strUserInput);
108 md5state.getDigest(md5pword2);
110 if (!m_strPassword.Equals(md5pword2))
112 // incorrect password entered
115 // don't clean up if the calling code wants the bad user input
116 if (m_bUserInputCleanup)
119 m_bUserInputCleanup = true;
121 m_bHideInputChars = true;
126 // correct password entered
130 m_bHideInputChars = true;
134 else if (action.GetID() >= REMOTE_0 && action.GetID() <= REMOTE_9)
136 return true; // unhandled
140 return CGUIDialog::OnAction(action);
144 bool CGUIDialogGamepad::OnMessage(CGUIMessage& message)
146 switch ( message.GetMessage() )
148 case GUI_MSG_WINDOW_INIT:
150 m_bConfirmed = false;
152 m_cHideInputChar = g_localizeStrings.Get(12322).c_str()[0];
153 CGUIDialog::OnMessage(message);
158 case GUI_MSG_CLICKED:
160 m_bConfirmed = false;
165 return CGUIDialogBoxBase::OnMessage(message);
168 // \brief Show gamepad keypad and replace aTextString with user input.
169 // \param aTextString String to preload into the keyboard accumulator. Overwritten with user input if return=true.
170 // \param dlgHeading String shown on dialog title. Converts to localized string if contains a positive integer.
171 // \param bHideUserInput Masks user input as asterisks if set as true. Currently not yet implemented.
172 // \return true if successful display and user input. false if unsucessful display, no user input, or canceled editing.
173 bool CGUIDialogGamepad::ShowAndGetInput(CStdString& aTextString, const CStdString &dlgHeading, bool bHideUserInput)
175 // Prompt user for input
176 CStdString strUserInput = "";
177 if (ShowAndVerifyInput(strUserInput, dlgHeading, aTextString, "", "", true, bHideUserInput))
179 // user entry was blank
183 if (strUserInput.IsEmpty())
188 // We should have a string to return
189 aTextString = strUserInput;
193 // \brief Show gamepad keypad twice to get and confirm a user-entered password string.
194 // \param strNewPassword String to preload into the keyboard accumulator. Overwritten with user input if return=true.
195 // \return true if successful display and user input entry/re-entry. false if unsucessful display, no user input, or canceled editing.
196 bool CGUIDialogGamepad::ShowAndVerifyNewPassword(CStdString& strNewPassword)
198 // Prompt user for password input
199 CStdString strUserInput = "";
200 if (ShowAndVerifyInput(strUserInput, "12340", "12330", "12331", "", true, true))
202 // TODO: Show error to user saying the password entry was blank
203 CGUIDialogOK::ShowAndGetInput(12357, 12358, 0, 0); // Password is empty/blank
207 if (strUserInput.IsEmpty())
211 // Prompt again for password input, this time sending previous input as the password to verify
212 if (!ShowAndVerifyInput(strUserInput, "12341", "12330", "12331", "", false, true))
214 // TODO: Show error to user saying the password re-entry failed
215 CGUIDialogOK::ShowAndGetInput(12357, 12344, 0, 0); // Password do not match
219 // password entry and re-entry succeeded
220 strNewPassword = strUserInput;
224 // \brief Show gamepad keypad and verify user input against strPassword.
225 // \param strPassword Value to compare against user input.
226 // \param dlgHeading String shown on dialog title. Converts to localized string if contains a positive integer.
227 // \param iRetries If greater than 0, shows "Incorrect password, %d retries left" on dialog line 2, else line 2 is blank.
228 // \return 0 if successful display and user input. 1 if unsucessful input. -1 if no user input or canceled editing.
229 int CGUIDialogGamepad::ShowAndVerifyPassword(CStdString& strPassword, const CStdString& dlgHeading, int iRetries)
231 CStdString strLine2 = "";
234 // Show a string telling user they have iRetries retries left
235 strLine2 = StringUtils::Format("%s %i %s", g_localizeStrings.Get(12342).c_str(), iRetries, g_localizeStrings.Get(12343).c_str());
238 // make a copy of strPassword to prevent from overwriting it later
239 CStdString strPassTemp = strPassword;
240 if (ShowAndVerifyInput(strPassTemp, dlgHeading, g_localizeStrings.Get(12330), g_localizeStrings.Get(12331), strLine2, true, true))
242 // user entered correct password
246 if (strPassTemp.IsEmpty())
250 // user must have entered an incorrect password
254 // \brief Show gamepad keypad and verify user input against strToVerify.
255 // \param strToVerify Value to compare against user input.
256 // \param dlgHeading String shown on dialog title. Converts to localized string if contains a positive integer.
257 // \param dlgLine0 String shown on dialog line 0. Converts to localized string if contains a positive integer.
258 // \param dlgLine1 String shown on dialog line 1. Converts to localized string if contains a positive integer.
259 // \param dlgLine2 String shown on dialog line 2. Converts to localized string if contains a positive integer.
260 // \param bGetUserInput If set as true and return=true, strToVerify is overwritten with user input string.
261 // \param bHideInputChars Masks user input as asterisks if set as true. Currently not yet implemented.
262 // \return true if successful display and user input. false if unsucessful display, no user input, or canceled editing.
263 bool CGUIDialogGamepad::ShowAndVerifyInput(CStdString& strToVerify, const CStdString& dlgHeading,
264 const CStdString& dlgLine0, const CStdString& dlgLine1,
265 const CStdString& dlgLine2, bool bGetUserInput, bool bHideInputChars)
267 // Prompt user for password input
268 CGUIDialogGamepad *pDialog = (CGUIDialogGamepad *)g_windowManager.GetWindow(WINDOW_DIALOG_GAMEPAD);
269 pDialog->m_strPassword = strToVerify;
270 pDialog->m_bUserInputCleanup = !bGetUserInput;
271 pDialog->m_bHideInputChars = bHideInputChars;
273 // HACK: This won't work if the label specified is actually a positive numeric value, but that's very unlikely
274 if (!StringUtils::IsNaturalNumber(dlgHeading))
275 pDialog->SetHeading( dlgHeading );
277 pDialog->SetHeading( atoi(dlgHeading.c_str()) );
279 if (!StringUtils::IsNaturalNumber(dlgLine0))
280 pDialog->SetLine( 0, dlgLine0 );
282 pDialog->SetLine( 0, atoi(dlgLine0.c_str()) );
284 if (!StringUtils::IsNaturalNumber(dlgLine1))
285 pDialog->SetLine( 1, dlgLine1 );
287 pDialog->SetLine( 1, atoi(dlgLine1.c_str()) );
289 if (!StringUtils::IsNaturalNumber(dlgLine2))
290 pDialog->SetLine( 2, dlgLine2 );
292 pDialog->SetLine( 2, atoi(dlgLine2.c_str()) );
294 g_audioManager.Enable(false); // dont do sounds during pwd input
296 g_audioManager.Enable(true);
298 if (bGetUserInput && !pDialog->IsCanceled())
300 XBMC::XBMC_MD5 md5state;
301 md5state.append(pDialog->m_strUserInput);
302 md5state.getDigest(strToVerify);
303 strToVerify.ToLower();
304 pDialog->m_strUserInput = "";
307 if (!pDialog->IsConfirmed() || pDialog->IsCanceled())
309 // user canceled out or entered an incorrect password
313 // user entered correct password
317 bool CGUIDialogGamepad::IsCanceled() const