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