[videodb] remove unused seasons table from episode_view
[xbmc.git] / xbmc / dialogs / GUIDialogKeyboardGeneric.cpp
blobeaccfe5de9ac06aa3f734ef98c04c7e27dcdb9e8
1 /*
2 * Copyright (C) 2012-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.
7 */
9 #include "GUIDialogKeyboardGeneric.h"
11 #include "GUIDialogNumeric.h"
12 #include "GUIUserMessages.h"
13 #include "ServiceBroker.h"
14 #include "dialogs/GUIDialogKaiToast.h"
15 #include "guilib/GUIComponent.h"
16 #include "guilib/GUIEditControl.h"
17 #include "guilib/GUILabelControl.h"
18 #include "guilib/GUIWindowManager.h"
19 #include "guilib/LocalizeStrings.h"
20 #include "input/InputCodingTable.h"
21 #include "input/actions/Action.h"
22 #include "input/actions/ActionIDs.h"
23 #include "input/keyboard/KeyIDs.h"
24 #include "input/keyboard/KeyboardLayoutManager.h"
25 #include "input/keyboard/XBMC_vkeys.h"
26 #include "interfaces/AnnouncementManager.h"
27 #include "messaging/ApplicationMessenger.h"
28 #include "settings/Settings.h"
29 #include "settings/SettingsComponent.h"
30 #include "speech/ISpeechRecognition.h"
31 #include "speech/ISpeechRecognitionListener.h"
32 #include "speech/SpeechRecognitionErrors.h"
33 #include "utils/CharsetConverter.h"
34 #include "utils/RegExp.h"
35 #include "utils/StringUtils.h"
36 #include "utils/Variant.h"
37 #include "utils/log.h"
38 #include "windowing/WinSystem.h"
40 #include <mutex>
42 using namespace KODI;
43 using namespace MESSAGING;
45 #define BUTTON_ID_OFFSET 100
46 #define BUTTONS_PER_ROW 20
47 #define BUTTONS_MAX_ROWS 4
49 #define CTL_BUTTON_DONE 300
50 #define CTL_BUTTON_CANCEL 301
51 #define CTL_BUTTON_SHIFT 302
52 #define CTL_BUTTON_CAPS 303
53 #define CTL_BUTTON_SYMBOLS 304
54 #define CTL_BUTTON_LEFT 305
55 #define CTL_BUTTON_RIGHT 306
56 #define CTL_BUTTON_IP_ADDRESS 307
57 #define CTL_BUTTON_CLEAR 308
58 #define CTL_BUTTON_LAYOUT 309
59 #define CTL_BUTTON_REVEAL 310
60 #define CTL_LABEL_HEADING 311
61 #define CTL_EDIT 312
62 #define CTL_LABEL_HZCODE 313
63 #define CTL_LABEL_HZLIST 314
65 #define CTL_BUTTON_BACKSPACE 8
66 #define CTL_BUTTON_SPACE 32
68 #define SEARCH_DELAY 1000
70 class CSpeechRecognitionListener : public speech::ISpeechRecognitionListener
72 public:
73 CSpeechRecognitionListener(int dialogId) : m_dialogId(dialogId) {}
75 void OnReadyForSpeech() override
77 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info,
78 g_localizeStrings.Get(39177), // Speech to text
79 g_localizeStrings.Get(39179)); // Listening...
82 void OnError(int recognitionError) override
84 uint32_t msgId = 0;
85 switch (recognitionError)
87 case speech::RecognitionError::SERVICE_NOT_AVAILABLE:
88 msgId = 39178; // Speech recognition service not available
89 break;
90 case speech::RecognitionError::NO_MATCH:
91 msgId = 39180; // No recognition result matched
92 break;
93 case speech::RecognitionError::INSUFFICIENT_PERMISSIONS:
94 msgId = 39185; // Insufficient permissions for speech recognition
95 break;
96 default:
97 msgId = 39181; // Speech recognition error
98 break;
101 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error,
102 g_localizeStrings.Get(39177), // Speech to text
103 g_localizeStrings.Get(msgId));
106 void OnResults(const std::vector<std::string>& results) override
108 if (!results.empty())
110 CGUIMessage msg(GUI_MSG_SET_TEXT, m_dialogId, CTL_EDIT);
111 msg.SetLabel(results.front());
113 // dispatch to GUI thread
114 CServiceBroker::GetAppMessenger()->SendGUIMessage(msg, m_dialogId);
118 private:
119 const int m_dialogId{0};
122 CGUIDialogKeyboardGeneric::CGUIDialogKeyboardGeneric()
123 : CGUIDialog(WINDOW_DIALOG_KEYBOARD, "DialogKeyboard.xml")
124 , CGUIKeyboard()
125 , m_pCharCallback(NULL)
127 m_bIsConfirmed = false;
128 m_bShift = false;
129 m_hiddenInput = false;
130 m_keyType = KEY_TYPE::LOWER;
131 m_currentLayout = 0;
132 m_loadType = KEEP_IN_MEMORY;
133 m_isKeyboardNavigationMode = false;
134 m_previouslyFocusedButton = 0;
135 m_pos = 0;
136 m_listwidth = 600;
139 void CGUIDialogKeyboardGeneric::OnWindowLoaded()
141 CGUIEditControl *edit = static_cast<CGUIEditControl*>(GetControl(CTL_EDIT));
142 if (edit)
144 // add control CTL_LABEL_HZCODE and CTL_LABEL_HZLIST if not exist
145 CGUIControlGroup *ParentControl = static_cast<CGUIControlGroup*>(edit->GetParentControl());
146 CLabelInfo labelInfo = edit->GetLabelInfo();
147 float px = edit->GetXPosition();
148 float py = edit->GetYPosition();
149 float pw = edit->GetWidth();
150 float ph = edit->GetHeight();
152 CGUILabelControl* control = static_cast<CGUILabelControl*>(GetControl(CTL_LABEL_HZCODE));
153 if (!control)
155 control = new CGUILabelControl(GetID(), CTL_LABEL_HZCODE, px, py + ph, 90, 30, labelInfo, false, false);
156 ParentControl->AddControl(control);
159 control = static_cast<CGUILabelControl*>(GetControl(CTL_LABEL_HZLIST));
160 if (!control)
162 labelInfo.align = XBFONT_CENTER_Y;
163 control = new CGUILabelControl(GetID(), CTL_LABEL_HZLIST, px + 95, py + ph, pw - 95, 30, labelInfo, false, false);
164 ParentControl->AddControl(control);
168 CGUIDialog::OnWindowLoaded();
171 void CGUIDialogKeyboardGeneric::OnInitWindow()
173 CGUIDialog::OnInitWindow();
175 m_bIsConfirmed = false;
176 m_isKeyboardNavigationMode = false;
178 // fill in the keyboard layouts
179 m_currentLayout = 0;
180 m_layouts.clear();
181 const KEYBOARD::KeyboardLayouts& keyboardLayouts =
182 CServiceBroker::GetKeyboardLayoutManager()->GetLayouts();
183 const std::shared_ptr<CSettings> settings = CServiceBroker::GetSettingsComponent()->GetSettings();
184 std::vector<CVariant> layoutNames = settings->GetList(CSettings::SETTING_LOCALE_KEYBOARDLAYOUTS);
185 std::string activeLayout = settings->GetString(CSettings::SETTING_LOCALE_ACTIVEKEYBOARDLAYOUT);
187 for (const auto& layoutName : layoutNames)
189 const auto keyboardLayout = keyboardLayouts.find(layoutName.asString());
190 if (keyboardLayout != keyboardLayouts.end())
192 m_layouts.emplace_back(keyboardLayout->second);
193 if (layoutName.asString() == activeLayout)
194 m_currentLayout = m_layouts.size() - 1;
198 // set alphabetic (capitals)
199 UpdateButtons();
201 // set heading
202 if (!m_strHeading.empty())
204 SET_CONTROL_LABEL(CTL_LABEL_HEADING, m_strHeading);
205 SET_CONTROL_VISIBLE(CTL_LABEL_HEADING);
207 else
209 SET_CONTROL_HIDDEN(CTL_LABEL_HEADING);
211 // set type
213 CGUIMessage msg(GUI_MSG_SET_TYPE, GetID(), CTL_EDIT, m_hiddenInput ? CGUIEditControl::INPUT_TYPE_PASSWORD : CGUIEditControl::INPUT_TYPE_TEXT);
214 OnMessage(msg);
216 if (m_hiddenInput)
218 SET_CONTROL_VISIBLE(CTL_BUTTON_REVEAL);
219 SET_CONTROL_LABEL(CTL_BUTTON_REVEAL, g_localizeStrings.Get(12308));
221 else
222 SET_CONTROL_HIDDEN(CTL_BUTTON_REVEAL);
224 SetEditText(m_text);
226 // get HZLIST label options
227 CGUILabelControl* pEdit = static_cast<CGUILabelControl*>(GetControl(CTL_LABEL_HZLIST));
228 CLabelInfo labelInfo = pEdit->GetLabelInfo();
229 m_listfont = labelInfo.font;
230 m_listwidth = pEdit->GetWidth();
231 m_hzcode.clear();
232 m_words.clear();
233 SET_CONTROL_LABEL(CTL_LABEL_HZCODE, "");
234 SET_CONTROL_LABEL(CTL_LABEL_HZLIST, "");
236 CVariant data;
237 data["title"] = m_strHeading;
238 data["type"] = !m_hiddenInput ? "keyboard" : "password";
239 data["value"] = GetText();
240 CServiceBroker::GetAnnouncementManager()->Announce(ANNOUNCEMENT::Input, "OnInputRequested", data);
243 bool CGUIDialogKeyboardGeneric::OnAction(const CAction &action)
245 int actionId = action.GetID();
246 bool handled = true;
247 if (actionId == (KEY_VKEY | XBMCVK_BACK))
248 Backspace();
249 else if (actionId == ACTION_ENTER ||
250 (actionId == ACTION_SELECT_ITEM && (m_isKeyboardNavigationMode || GetFocusedControlID() == CTL_EDIT)))
251 OnOK();
252 else if (actionId == ACTION_SHIFT)
253 OnShift();
254 else if (actionId == ACTION_SYMBOLS)
255 OnSymbols();
256 // don't handle move left/right and select in the edit control
257 else if (!m_isKeyboardNavigationMode &&
258 (actionId == ACTION_MOVE_LEFT ||
259 actionId == ACTION_MOVE_RIGHT ||
260 actionId == ACTION_SELECT_ITEM))
261 handled = false;
262 else if (actionId == ACTION_VOICE_RECOGNIZE)
263 OnVoiceRecognition();
264 else
266 std::wstring wch = L"";
267 wch.insert(wch.begin(), action.GetUnicode());
268 std::string ch;
269 g_charsetConverter.wToUTF8(wch, ch);
270 handled = CodingCharacter(ch);
271 if (!handled)
273 // send action to edit control
274 CGUIControl *edit = GetControl(CTL_EDIT);
275 if (edit)
276 handled = edit->OnAction(action);
277 if (!handled && actionId >= KEY_VKEY && actionId < KEY_UNICODE)
279 unsigned char b = actionId & 0xFF;
280 if (b == XBMCVK_TAB)
282 // Toggle left/right key mode
283 m_isKeyboardNavigationMode = !m_isKeyboardNavigationMode;
284 if (m_isKeyboardNavigationMode)
286 m_previouslyFocusedButton = GetFocusedControlID();
287 SET_CONTROL_FOCUS(edit->GetID(), 0);
289 else
290 SET_CONTROL_FOCUS(m_previouslyFocusedButton, 0);
291 handled = true;
297 if (!handled) // unhandled by us - let's see if the baseclass wants it
298 handled = CGUIDialog::OnAction(action);
300 return handled;
303 bool CGUIDialogKeyboardGeneric::OnMessage(CGUIMessage& message)
305 switch ( message.GetMessage() )
307 case GUI_MSG_CLICKED:
309 int iControl = message.GetSenderId();
311 switch (iControl)
313 case CTL_BUTTON_DONE:
314 OnOK();
315 break;
316 case CTL_BUTTON_CANCEL:
317 Close();
318 break;
319 case CTL_BUTTON_SHIFT:
320 OnShift();
321 break;
322 case CTL_BUTTON_CAPS:
323 if (m_keyType == KEY_TYPE::LOWER)
324 m_keyType = KEY_TYPE::CAPS;
325 else if (m_keyType == KEY_TYPE::CAPS)
326 m_keyType = KEY_TYPE::LOWER;
327 UpdateButtons();
328 break;
329 case CTL_BUTTON_LAYOUT:
330 OnLayout();
331 break;
332 case CTL_BUTTON_REVEAL:
333 OnReveal();
334 break;
335 case CTL_BUTTON_SYMBOLS:
336 OnSymbols();
337 break;
338 case CTL_BUTTON_LEFT:
339 MoveCursor( -1);
340 break;
341 case CTL_BUTTON_RIGHT:
342 MoveCursor(1);
343 break;
344 case CTL_BUTTON_IP_ADDRESS:
345 OnIPAddress();
346 break;
347 case CTL_BUTTON_CLEAR:
348 SetEditText("");
349 break;
350 case CTL_EDIT:
352 CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), CTL_EDIT);
353 OnMessage(msg);
354 // update callback I guess?
355 if (m_pCharCallback)
356 { // we did _something_, so make sure our search message filter is reset
357 m_pCharCallback(this, msg.GetLabel());
359 m_text = msg.GetLabel();
360 return true;
362 default:
363 OnClickButton(iControl);
364 break;
367 break;
369 case GUI_MSG_SET_TEXT:
371 // the edit control only handles these messages if it is either focused
372 // or its specific control ID is set in the message. As neither is the
373 // case here (focus is on one of the keyboard buttons) we have to force
374 // the control ID of the message to the control ID of the edit control
375 // (unfortunately we have to create a whole copy of the message object for that)
376 CGUIMessage messageCopy(message.GetMessage(), message.GetSenderId(), CTL_EDIT, message.GetParam1(), message.GetParam2(), message.GetItem());
377 messageCopy.SetLabel(message.GetLabel());
379 // ensure this goes to the edit control
380 CGUIControl *edit = GetControl(CTL_EDIT);
381 if (edit)
382 edit->OnMessage(messageCopy);
384 // close the dialog if requested
385 if (message.GetMessage() == GUI_MSG_SET_TEXT && message.GetParam1() > 0)
386 OnOK();
387 return true;
389 case GUI_MSG_CODINGTABLE_LOOKUP_COMPLETED:
391 const std::string& code = message.GetStringParam();
392 if (code == m_hzcode)
394 int response = message.GetParam1();
395 auto words = m_codingtable->GetResponse(response);
396 m_words.insert(m_words.end(), words.begin(), words.end());
397 ShowWordList(0);
402 return CGUIDialog::OnMessage(message);
405 void CGUIDialogKeyboardGeneric::SetEditText(const std::string &text)
407 CGUIMessage msg(GUI_MSG_SET_TEXT, GetID(), CTL_EDIT);
408 msg.SetLabel(text);
409 OnMessage(msg);
412 void CGUIDialogKeyboardGeneric::SetText(const std::string& text)
414 m_text = text;
417 const std::string &CGUIDialogKeyboardGeneric::GetText() const
419 return m_text;
422 void CGUIDialogKeyboardGeneric::Character(const std::string &ch)
424 if (ch.empty()) return;
425 if (!CodingCharacter(ch))
426 NormalCharacter(ch);
429 void CGUIDialogKeyboardGeneric::NormalCharacter(const std::string &ch)
431 // send text to edit control
432 CGUIControl *edit = GetControl(CTL_EDIT);
433 if (edit)
435 CAction action(ACTION_INPUT_TEXT);
436 action.SetText(ch);
437 edit->OnAction(action);
441 void CGUIDialogKeyboardGeneric::Backspace()
443 if (m_codingtable && m_hzcode.length() > 0)
445 std::wstring tmp;
446 g_charsetConverter.utf8ToW(m_hzcode, tmp);
447 tmp.erase(tmp.length() - 1, 1);
448 g_charsetConverter.wToUTF8(tmp, m_hzcode);
450 switch (m_codingtable->GetType())
452 case IInputCodingTable::TYPE_WORD_LIST:
453 SetControlLabel(CTL_LABEL_HZCODE, m_hzcode);
454 ChangeWordList(0);
455 break;
457 case IInputCodingTable::TYPE_CONVERT_STRING:
458 SetEditText(m_codingtable->ConvertString(m_hzcode));
459 break;
462 else
464 // send action to edit control
465 CGUIControl *edit = GetControl(CTL_EDIT);
466 if (edit)
467 edit->OnAction(CAction(ACTION_BACKSPACE));
469 if (m_codingtable && m_codingtable->GetType() == IInputCodingTable::TYPE_CONVERT_STRING)
470 m_codingtable->SetTextPrev(GetText());
474 void CGUIDialogKeyboardGeneric::OnClickButton(int iButtonControl)
476 if (iButtonControl == CTL_BUTTON_BACKSPACE)
478 Backspace();
480 else if (iButtonControl == CTL_BUTTON_SPACE)
482 Character(" ");
484 else
486 const CGUIControl* pButton = GetControl(iButtonControl);
487 // Do not register input for buttons with id >= 500
488 if (pButton && iButtonControl < 500)
490 Character(pButton->GetDescription());
491 // reset the shift keys
492 if (m_bShift) OnShift();
497 void CGUIDialogKeyboardGeneric::UpdateButtons()
499 SET_CONTROL_SELECTED(GetID(), CTL_BUTTON_SHIFT, m_bShift);
500 SET_CONTROL_SELECTED(GetID(), CTL_BUTTON_CAPS, m_keyType == KEY_TYPE::CAPS);
501 SET_CONTROL_SELECTED(GetID(), CTL_BUTTON_SYMBOLS, m_keyType == KEY_TYPE::SYMBOLS);
503 if (m_currentLayout >= m_layouts.size())
504 m_currentLayout = 0;
505 KEYBOARD::CKeyboardLayout layout =
506 m_layouts.empty() ? KEYBOARD::CKeyboardLayout() : m_layouts[m_currentLayout];
507 m_codingtable = layout.GetCodingTable();
508 if (m_codingtable && !m_codingtable->IsInitialized())
509 m_codingtable->Initialize();
511 bool bShowWordList = false;
512 if (m_codingtable)
514 switch (m_codingtable->GetType())
516 case IInputCodingTable::TYPE_WORD_LIST:
517 bShowWordList = true;
518 break;
520 case IInputCodingTable::TYPE_CONVERT_STRING:
521 m_codingtable->SetTextPrev(GetText());
522 m_hzcode.clear();
523 break;
527 if (bShowWordList)
529 SET_CONTROL_VISIBLE(CTL_LABEL_HZCODE);
530 SET_CONTROL_VISIBLE(CTL_LABEL_HZLIST);
532 else
534 SET_CONTROL_HIDDEN(CTL_LABEL_HZCODE);
535 SET_CONTROL_HIDDEN(CTL_LABEL_HZLIST);
537 SET_CONTROL_LABEL(CTL_BUTTON_LAYOUT, layout.GetName());
539 unsigned int modifiers = KEYBOARD::CKeyboardLayout::ModifierKeyNone;
540 if ((m_keyType == KEY_TYPE::CAPS && !m_bShift) || (m_keyType == KEY_TYPE::LOWER && m_bShift))
541 modifiers |= KEYBOARD::CKeyboardLayout::ModifierKeyShift;
542 if (m_keyType == KEY_TYPE::SYMBOLS)
544 modifiers |= KEYBOARD::CKeyboardLayout::ModifierKeySymbol;
545 if (m_bShift)
546 modifiers |= KEYBOARD::CKeyboardLayout::ModifierKeyShift;
549 for (unsigned int row = 0; row < BUTTONS_MAX_ROWS; row++)
551 for (unsigned int column = 0; column < BUTTONS_PER_ROW; column++)
553 int buttonID = (row * BUTTONS_PER_ROW) + column + BUTTON_ID_OFFSET;
554 std::string label = layout.GetCharAt(row, column, modifiers);
555 SetControlLabel(buttonID, label);
556 if (!label.empty())
557 SET_CONTROL_VISIBLE(buttonID);
558 else
559 SET_CONTROL_HIDDEN(buttonID);
564 void CGUIDialogKeyboardGeneric::OnDeinitWindow(int nextWindowID)
566 for (auto& layout : m_layouts)
568 auto codingTable = layout.GetCodingTable();
569 if (codingTable && codingTable->IsInitialized())
570 codingTable->Deinitialize();
572 // call base class
573 CGUIDialog::OnDeinitWindow(nextWindowID);
574 // reset the heading (we don't always have this)
575 m_strHeading = "";
577 CServiceBroker::GetAnnouncementManager()->Announce(ANNOUNCEMENT::Input, "OnInputFinished");
580 void CGUIDialogKeyboardGeneric::MoveCursor(int iAmount)
582 if (m_codingtable && m_words.size())
583 ChangeWordList(iAmount);
584 else
586 CGUIControl *edit = GetControl(CTL_EDIT);
587 if (edit)
588 edit->OnAction(CAction(iAmount < 0 ? ACTION_CURSOR_LEFT : ACTION_CURSOR_RIGHT));
592 void CGUIDialogKeyboardGeneric::OnLayout()
594 m_currentLayout++;
595 if (m_currentLayout >= m_layouts.size())
596 m_currentLayout = 0;
597 KEYBOARD::CKeyboardLayout layout =
598 m_layouts.empty() ? KEYBOARD::CKeyboardLayout() : m_layouts[m_currentLayout];
599 CServiceBroker::GetSettingsComponent()->GetSettings()->SetString(CSettings::SETTING_LOCALE_ACTIVEKEYBOARDLAYOUT, layout.GetName());
600 UpdateButtons();
603 void CGUIDialogKeyboardGeneric::OnSymbols()
605 if (m_keyType == KEY_TYPE::SYMBOLS)
606 m_keyType = KEY_TYPE::LOWER;
607 else
608 m_keyType = KEY_TYPE::SYMBOLS;
609 UpdateButtons();
612 void CGUIDialogKeyboardGeneric::OnReveal()
614 m_hiddenInput = !m_hiddenInput;
615 SET_CONTROL_LABEL(CTL_BUTTON_REVEAL, g_localizeStrings.Get(m_hiddenInput ? 12308 : 12309));
616 CGUIMessage msg(GUI_MSG_SET_TYPE, GetID(), CTL_EDIT,
617 m_hiddenInput ? CGUIEditControl::INPUT_TYPE_PASSWORD
618 : CGUIEditControl::INPUT_TYPE_TEXT);
619 OnMessage(msg);
622 void CGUIDialogKeyboardGeneric::OnShift()
624 m_bShift = !m_bShift;
625 UpdateButtons();
628 void CGUIDialogKeyboardGeneric::OnIPAddress()
630 // find any IP address in the current string if there is any
631 // We match to #.#.#.#
632 std::string text = GetText();
633 std::string ip;
634 CRegExp reg;
635 reg.RegComp("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+");
636 int start = reg.RegFind(text.c_str());
637 int length = 0;
638 if (start > -1)
640 length = reg.GetSubLength(0);
641 ip = text.substr(start, length);
643 else
644 start = text.size();
645 if (CGUIDialogNumeric::ShowAndGetIPAddress(ip, g_localizeStrings.Get(14068)))
646 SetEditText(text.substr(0, start) + ip + text.substr(start + length));
649 void CGUIDialogKeyboardGeneric::OnVoiceRecognition()
651 const auto speechRecognition = CServiceBroker::GetSpeechRecognition();
652 if (speechRecognition)
654 if (!m_speechRecognitionListener)
655 m_speechRecognitionListener = std::make_shared<CSpeechRecognitionListener>(GetID());
657 speechRecognition->StartSpeechRecognition(m_speechRecognitionListener);
659 else
661 CLog::LogF(LOGWARNING, "No voice recognition implementation available.");
665 void CGUIDialogKeyboardGeneric::SetControlLabel(int id, const std::string &label)
666 { // find all controls with this id, and set all their labels
667 CGUIMessage message(GUI_MSG_LABEL_SET, GetID(), id);
668 message.SetLabel(label);
669 for (unsigned int i = 0; i < m_children.size(); i++)
671 if (m_children[i]->GetID() == id || m_children[i]->IsGroup())
672 m_children[i]->OnMessage(message);
676 void CGUIDialogKeyboardGeneric::OnOK()
678 m_bIsConfirmed = true;
679 Close();
682 void CGUIDialogKeyboardGeneric::SetHeading(const std::string &heading)
684 m_strHeading = heading;
687 int CGUIDialogKeyboardGeneric::GetWindowId() const
689 return GetID();
692 void CGUIDialogKeyboardGeneric::Cancel()
694 m_bIsConfirmed = false;
695 Close();
698 bool CGUIDialogKeyboardGeneric::ShowAndGetInput(char_callback_t pCallback, const std::string &initialString, std::string &typedString, const std::string &heading, bool bHiddenInput)
700 CGUIDialogKeyboardGeneric *pKeyboard = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogKeyboardGeneric>(WINDOW_DIALOG_KEYBOARD);
702 if (!pKeyboard)
703 return false;
705 m_pCharCallback = pCallback;
706 // setup keyboard
707 pKeyboard->Initialize();
708 pKeyboard->SetHeading(heading);
709 pKeyboard->SetHiddenInput(bHiddenInput);
710 pKeyboard->SetText(initialString);
711 pKeyboard->Open();
712 pKeyboard->Close();
714 // If have text - update this.
715 if (pKeyboard->IsConfirmed())
717 typedString = pKeyboard->GetText();
718 return true;
720 else return false;
723 float CGUIDialogKeyboardGeneric::GetStringWidth(const std::wstring & utf16)
725 vecText utf32;
727 utf32.resize(utf16.size());
728 for (unsigned int i = 0; i < utf16.size(); i++)
729 utf32[i] = utf16[i];
731 return m_listfont->GetTextWidth(utf32);
734 void CGUIDialogKeyboardGeneric::ChangeWordList(int direct)
736 if (direct == 0)
738 m_pos = 0;
739 m_words.clear();
740 m_codingtable->GetWordListPage(m_hzcode, true);
742 else
744 ShowWordList(direct);
745 if (direct > 0 && m_pos + m_num == static_cast<int>(m_words.size()))
746 m_codingtable->GetWordListPage(m_hzcode, false);
750 void CGUIDialogKeyboardGeneric::ShowWordList(int direct)
752 std::unique_lock<CCriticalSection> lock(m_CS);
753 std::wstring hzlist = L"";
754 CServiceBroker::GetWinSystem()->GetGfxContext().SetScalingResolution(m_coordsRes, true);
755 float width = m_listfont->GetCharWidth(L'<') + m_listfont->GetCharWidth(L'>');
756 float spacewidth = m_listfont->GetCharWidth(L' ');
757 float numwidth = m_listfont->GetCharWidth(L'1') + m_listfont->GetCharWidth(L'.');
758 int i;
760 if (direct >= 0)
762 if (direct > 0)
763 m_pos += m_num;
764 if (m_pos > static_cast<int>(m_words.size()) - 1)
765 m_pos = 0;
766 for (i = 0; m_pos + i < static_cast<int>(m_words.size()); i++)
768 if ((i > 0 && width + GetStringWidth(m_words[m_pos + i]) + numwidth > m_listwidth) || i > 9)
769 break;
770 hzlist.insert(hzlist.length(), 1, (wchar_t)(i + 48));
771 hzlist.insert(hzlist.length(), 1, L'.');
772 hzlist.append(m_words[m_pos + i]);
773 hzlist.insert(hzlist.length(), 1, L' ');
774 width += GetStringWidth(m_words[m_pos + i]) + numwidth + spacewidth;
776 m_num = i;
778 else
780 if (m_pos == 0)
781 return;
782 for (i = 1; i <= 10; i++)
784 if (m_pos - i < 0 || (i > 1 && width + GetStringWidth(m_words[m_pos - i]) + numwidth > m_listwidth))
785 break;
786 width += GetStringWidth(m_words[m_pos - i]) + numwidth + spacewidth;
788 m_num = --i;
789 m_pos -= m_num;
790 for (i = 0; i < m_num; i++)
792 hzlist.insert(hzlist.length(), 1, (wchar_t)(i + 48));
793 hzlist.insert(hzlist.length(), 1, L'.');
794 hzlist.append(m_words[m_pos + i]);
795 hzlist.insert(hzlist.length(), 1, L' ');
798 hzlist.erase(hzlist.find_last_not_of(L' ') + 1);
799 if (m_pos > 0)
800 hzlist.insert(0, 1, L'<');
801 if (m_pos + m_num < static_cast<int>(m_words.size()))
802 hzlist.insert(hzlist.length(), 1, L'>');
803 std::string utf8String;
804 g_charsetConverter.wToUTF8(hzlist, utf8String);
805 SET_CONTROL_LABEL(CTL_LABEL_HZLIST, utf8String);
808 bool CGUIDialogKeyboardGeneric::CodingCharacter(const std::string &ch)
810 if (!m_codingtable)
811 return false;
813 switch (m_codingtable->GetType())
815 case IInputCodingTable::TYPE_CONVERT_STRING:
816 if (!ch.empty() && ch[0] != 0)
818 m_hzcode += ch;
819 SetEditText(m_codingtable->ConvertString(m_hzcode));
820 return true;
822 break;
824 case IInputCodingTable::TYPE_WORD_LIST:
825 if (m_codingtable->GetCodeChars().find(ch) != std::string::npos)
827 m_hzcode += ch;
828 SetControlLabel(CTL_LABEL_HZCODE, m_hzcode);
829 ChangeWordList(0);
830 return true;
832 if (ch[0] >= '0' && ch[0] <= '9')
834 int i = m_pos + (int)ch[0] - 48;
835 if (i < (m_pos + m_num))
837 m_hzcode = "";
838 SetControlLabel(CTL_LABEL_HZCODE, m_hzcode);
839 std::string utf8String;
840 g_charsetConverter.wToUTF8(m_words[i], utf8String);
841 NormalCharacter(utf8String);
843 return true;
845 break;
848 return false;