2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
9 #include "ServiceBroker.h"
10 #include "GUIComponent.h"
11 #include "messaging/ApplicationMessenger.h"
12 #include "LocalizeStrings.h"
13 #include "GUIKeyboardFactory.h"
14 #include "GUIUserMessages.h"
15 #include "GUIWindowManager.h"
16 #include "messaging/helpers/DialogOKHelper.h"
17 #include "settings/Settings.h"
18 #include "settings/SettingsComponent.h"
19 #include "utils/Digest.h"
20 #include "utils/StringUtils.h"
21 #include "utils/Variant.h"
23 #include "dialogs/GUIDialogKeyboardGeneric.h"
24 #if defined(TARGET_DARWIN_EMBEDDED)
25 #include "dialogs/GUIDialogKeyboardTouch.h"
27 #include "platform/darwin/ios-common/DarwinEmbedKeyboard.h"
30 using namespace KODI::MESSAGING
;
31 using KODI::UTILITY::CDigest
;
33 CGUIKeyboard
*CGUIKeyboardFactory::g_activeKeyboard
= NULL
;
34 FILTERING
CGUIKeyboardFactory::m_filtering
= FILTERING_NONE
;
36 CGUIKeyboardFactory::CGUIKeyboardFactory(void) = default;
38 CGUIKeyboardFactory::~CGUIKeyboardFactory(void) = default;
40 void CGUIKeyboardFactory::keyTypedCB(CGUIKeyboard
*ref
, const std::string
&typedString
)
44 // send our search message in safe way (only the active window needs it)
45 CGUIMessage
message(GUI_MSG_NOTIFY_ALL
, ref
->GetWindowId(), 0);
48 case FILTERING_SEARCH
:
49 message
.SetParam1(GUI_MSG_SEARCH_UPDATE
);
50 message
.SetStringParam(typedString
);
51 CServiceBroker::GetAppMessenger()->SendGUIMessage(
52 message
, CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow());
54 case FILTERING_CURRENT
:
55 message
.SetParam1(GUI_MSG_FILTER_ITEMS
);
56 message
.SetStringParam(typedString
);
57 CServiceBroker::GetAppMessenger()->SendGUIMessage(message
);
62 ref
->resetAutoCloseTimer();
66 bool CGUIKeyboardFactory::SendTextToActiveKeyboard(const std::string
&aTextString
, bool closeKeyboard
/* = false */)
68 if (!g_activeKeyboard
)
70 return g_activeKeyboard
->SetTextToKeyboard(aTextString
, closeKeyboard
);
74 // Show keyboard with initial value (aTextString) and replace with result string.
75 // Returns: true - successful display and input (empty result may return true or false depending on parameter)
76 // false - unsuccessful display of the keyboard or cancelled editing
77 bool CGUIKeyboardFactory::ShowAndGetInput(std::string
& aTextString
,
78 const CVariant
& heading
,
79 bool allowEmptyResult
,
80 bool hiddenInput
/* = false */,
81 unsigned int autoCloseMs
/* = 0 */)
83 bool confirmed
= false;
84 //heading can be a string or a localization id
85 std::string headingStr
;
86 if (heading
.isString())
87 headingStr
= heading
.asString();
88 else if (heading
.isInteger() && heading
.asInteger())
89 headingStr
= g_localizeStrings
.Get((uint32_t)heading
.asInteger());
91 bool useKodiKeyboard
= true;
92 #if defined(TARGET_DARWIN_EMBEDDED)
93 #if defined(TARGET_DARWIN_TVOS)
94 useKodiKeyboard
= CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
95 CSettings::SETTING_INPUT_TVOSUSEKODIKEYBOARD
);
97 useKodiKeyboard
= CDarwinEmbedKeyboard::hasExternalKeyboard();
98 #endif // defined(TARGET_DARWIN_TVOS)
101 auto& winManager
= CServiceBroker::GetGUI()->GetWindowManager();
102 CGUIKeyboard
* kb
= nullptr;
104 kb
= winManager
.GetWindow
<CGUIDialogKeyboardGeneric
>(WINDOW_DIALOG_KEYBOARD
);
105 #if defined(TARGET_DARWIN_EMBEDDED)
107 kb
= winManager
.GetWindow
<CGUIDialogKeyboardTouch
>(WINDOW_DIALOG_KEYBOARD_TOUCH
);
108 #endif // defined(TARGET_DARWIN_EMBEDDED)
112 g_activeKeyboard
= kb
;
113 kb
->startAutoCloseTimer(autoCloseMs
);
114 confirmed
= kb
->ShowAndGetInput(keyTypedCB
, aTextString
, aTextString
, headingStr
, hiddenInput
);
115 g_activeKeyboard
= NULL
;
120 if (!allowEmptyResult
&& aTextString
.empty())
127 bool CGUIKeyboardFactory::ShowAndGetInput(std::string
& aTextString
, bool allowEmptyResult
, unsigned int autoCloseMs
/* = 0 */)
129 return ShowAndGetInput(aTextString
, CVariant
{""}, allowEmptyResult
, false, autoCloseMs
);
132 // Shows keyboard and prompts for a password.
133 // Differs from ShowAndVerifyNewPassword() in that no second verification is necessary.
134 bool CGUIKeyboardFactory::ShowAndGetNewPassword(std::string
& newPassword
,
135 const CVariant
& heading
,
137 unsigned int autoCloseMs
/* = 0 */)
139 return ShowAndGetInput(newPassword
, heading
, allowEmpty
, true, autoCloseMs
);
142 // Shows keyboard and prompts for a password.
143 // Differs from ShowAndVerifyNewPassword() in that no second verification is necessary.
144 bool CGUIKeyboardFactory::ShowAndGetNewPassword(std::string
& newPassword
, unsigned int autoCloseMs
/* = 0 */)
146 return ShowAndGetNewPassword(newPassword
, 12340, false, autoCloseMs
);
149 bool CGUIKeyboardFactory::ShowAndGetFilter(std::string
&filter
, bool searching
, unsigned int autoCloseMs
/* = 0 */)
151 m_filtering
= searching
? FILTERING_SEARCH
: FILTERING_CURRENT
;
152 bool ret
= ShowAndGetInput(filter
, searching
? 16017 : 16028, true, false, autoCloseMs
);
153 m_filtering
= FILTERING_NONE
;
158 // \brief Show keyboard twice to get and confirm a user-entered password string.
159 // \param newPassword Overwritten with user input if return=true.
160 // \param heading Heading to display
161 // \param allowEmpty Whether a blank password is valid or not.
162 // \return true if successful display and user input entry/re-entry. false if unsuccessful display, no user input, or canceled editing.
163 bool CGUIKeyboardFactory::ShowAndVerifyNewPassword(std::string
& newPassword
,
164 const CVariant
& heading
,
166 unsigned int autoCloseMs
/* = 0 */)
168 // Prompt user for password input
169 std::string userInput
;
170 if (!ShowAndGetInput(userInput
, heading
, allowEmpty
, true, autoCloseMs
))
171 { // user cancelled, or invalid input
174 // success - verify the password
175 std::string checkInput
;
176 if (!ShowAndGetInput(checkInput
, 12341, allowEmpty
, true, autoCloseMs
))
177 { // user cancelled, or invalid input
180 // check the password
181 if (checkInput
== userInput
)
183 newPassword
= CDigest::Calculate(CDigest::Type::MD5
, userInput
);
186 HELPERS::ShowOKDialogText(CVariant
{12341}, CVariant
{12344});
190 // \brief Show keyboard twice to get and confirm a user-entered password string.
191 // \param strNewPassword Overwritten with user input if return=true.
192 // \return true if successful display and user input entry/re-entry. false if unsuccessful display, no user input, or canceled editing.
193 bool CGUIKeyboardFactory::ShowAndVerifyNewPassword(std::string
& newPassword
, unsigned int autoCloseMs
/* = 0 */)
195 const std::string
& heading
= g_localizeStrings
.Get(12340);
196 return ShowAndVerifyNewPassword(newPassword
, heading
, false, autoCloseMs
);
199 // \brief Show keyboard and verify user input against strPassword.
200 // \param strPassword Value to compare against user input.
201 // \param dlgHeading String shown on dialog title. Converts to localized string if contains a positive integer.
202 // \param iRetries If greater than 0, shows "Incorrect password, %d retries left" on dialog line 2, else line 2 is blank.
203 // \return 0 if successful display and user input. 1 if unsuccessful input. -1 if no user input or canceled editing.
204 int CGUIKeyboardFactory::ShowAndVerifyPassword(std::string
& strPassword
, const std::string
& strHeading
, int iRetries
, unsigned int autoCloseMs
/* = 0 */)
206 std::string strHeadingTemp
;
207 if (1 > iRetries
&& strHeading
.size())
208 strHeadingTemp
= strHeading
;
211 StringUtils::Format("{} - {} {}", g_localizeStrings
.Get(12326),
212 CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(
213 CSettings::SETTING_MASTERLOCK_MAXRETRIES
) -
215 g_localizeStrings
.Get(12343));
217 std::string strUserInput
;
218 //! @todo GUI Setting to enable disable this feature y/n?
219 if (!ShowAndGetInput(strUserInput
, strHeadingTemp
, false, true, autoCloseMs
)) //bool hiddenInput = false/true ?
220 return -1; // user canceled out
222 if (!strPassword
.empty())
224 std::string md5pword2
= CDigest::Calculate(CDigest::Type::MD5
, strUserInput
);
225 if (StringUtils::EqualsNoCase(strPassword
, md5pword2
))
226 return 0; // user entered correct password
227 else return 1; // user must have entered an incorrect password
231 if (!strUserInput
.empty())
233 strPassword
= CDigest::Calculate(CDigest::Type::MD5
, strUserInput
);
234 return 0; // user entered correct password