Merge pull request #4594 from FernetMenta/paplayer
[xbmc.git] / xbmc / dialogs / GUIDialogNumeric.cpp
blob3eed5d67c560e0bb45c7b5d16901013858a6deca
1 /*
2 * Copyright (C) 2005-2013 Team XBMC
3 * http://xbmc.org
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.
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 "GUIDialogNumeric.h"
22 #include "guilib/GUILabelControl.h"
23 #include "utils/md5.h"
24 #include "guilib/GUIWindowManager.h"
25 #include "GUIDialogOK.h"
26 #include "input/XBMC_vkeys.h"
27 #include "utils/StringUtils.h"
28 #include "guilib/Key.h"
29 #include "guilib/LocalizeStrings.h"
30 #include "interfaces/AnnouncementManager.h"
32 #define CONTROL_HEADING_LABEL 1
33 #define CONTROL_INPUT_LABEL 4
34 #define CONTROL_NUM0 10
35 #define CONTROL_NUM9 19
36 #define CONTROL_PREVIOUS 20
37 #define CONTROL_ENTER 21
38 #define CONTROL_NEXT 22
39 #define CONTROL_BACKSPACE 23
42 CGUIDialogNumeric::CGUIDialogNumeric(void)
43 : CGUIDialog(WINDOW_DIALOG_NUMERIC, "DialogNumeric.xml")
45 m_bConfirmed = false;
46 m_bCanceled = false;
48 m_mode = INPUT_PASSWORD;
49 m_block = 0;
50 memset(&m_datetime, 0, sizeof(SYSTEMTIME));
51 m_dirty = false;
52 m_loadType = KEEP_IN_MEMORY;
55 CGUIDialogNumeric::~CGUIDialogNumeric(void)
59 void CGUIDialogNumeric::OnInitWindow()
61 CGUIDialog::OnInitWindow();
63 CVariant data;
64 switch (m_mode)
66 case INPUT_TIME:
67 data["type"] = "time";
68 break;
69 case INPUT_DATE:
70 data["type"] = "date";
71 break;
72 case INPUT_IP_ADDRESS:
73 data["type"] = "ip";
74 break;
75 case INPUT_PASSWORD:
76 data["type"] = "numericpassword";
77 break;
78 case INPUT_NUMBER:
79 data["type"] = "number";
80 break;
81 case INPUT_TIME_SECONDS:
82 data["type"] = "seconds";
83 break;
84 default:
85 data["type"] = "keyboard";
86 break;
89 const CGUILabelControl *control = (const CGUILabelControl *)GetControl(CONTROL_HEADING_LABEL);
90 if (control != NULL)
91 data["title"] = control->GetDescription();
93 data["value"] = GetOutput();
94 ANNOUNCEMENT::CAnnouncementManager::Announce(ANNOUNCEMENT::Input, "xbmc", "OnInputRequested", data);
97 void CGUIDialogNumeric::OnDeinitWindow(int nextWindowID)
99 // call base class
100 CGUIDialog::OnDeinitWindow(nextWindowID);
102 ANNOUNCEMENT::CAnnouncementManager::Announce(ANNOUNCEMENT::Input, "xbmc", "OnInputFinished");
105 bool CGUIDialogNumeric::OnAction(const CAction &action)
107 if (action.GetID() == ACTION_NEXT_ITEM)
108 OnNext();
109 else if (action.GetID() == ACTION_PREV_ITEM)
110 OnPrevious();
111 else if (action.GetID() == ACTION_BACKSPACE)
112 OnBackSpace();
113 else if (action.GetID() == ACTION_ENTER)
114 OnOK();
115 else if (action.GetID() >= REMOTE_0 && action.GetID() <= REMOTE_9)
116 OnNumber(action.GetID() - REMOTE_0);
117 else if (action.GetID() >= KEY_VKEY && action.GetID() < KEY_ASCII)
118 { // input from the keyboard (vkey, not ascii)
119 BYTE b = action.GetID() & 0xFF;
120 if (b == XBMCVK_LEFT) OnPrevious();
121 else if (b == XBMCVK_RIGHT) OnNext();
122 else if (b == XBMCVK_RETURN || b == XBMCVK_NUMPADENTER) OnOK();
123 else if (b == XBMCVK_BACK) OnBackSpace();
124 else if (b == XBMCVK_ESCAPE) OnCancel();
126 else if (action.GetID() >= KEY_ASCII) // FIXME make it KEY_UNICODE
127 { // input from the keyboard
128 if (action.GetUnicode() == 10 || action.GetUnicode() == 13) OnOK(); // enter
129 else if (action.GetUnicode() == 8) OnBackSpace(); // backspace
130 else if (action.GetUnicode() == 27) OnCancel(); // escape
131 else if (action.GetUnicode() >= 48 && action.GetUnicode() < 58) // number
132 OnNumber(action.GetUnicode() - 48);
134 else
135 return CGUIDialog::OnAction(action);
136 return true;
139 bool CGUIDialogNumeric::OnBack(int actionID)
141 OnCancel();
142 return true;
145 bool CGUIDialogNumeric::OnMessage(CGUIMessage& message)
147 switch ( message.GetMessage() )
149 case GUI_MSG_WINDOW_INIT:
151 m_bConfirmed = false;
152 m_bCanceled = false;
153 m_dirty = false;
154 return CGUIDialog::OnMessage(message);
156 break;
158 case GUI_MSG_CLICKED:
160 int iControl = message.GetSenderId();
161 m_bConfirmed = false;
162 m_bCanceled = false;
163 if (CONTROL_NUM0 <= iControl && iControl <= CONTROL_NUM9) // User numeric entry via dialog button UI
165 OnNumber(iControl - 10);
166 return true;
168 else if (iControl == CONTROL_PREVIOUS)
170 OnPrevious();
171 return true;
173 else if (iControl == CONTROL_NEXT)
175 OnNext();
176 return true;
178 else if (iControl == CONTROL_BACKSPACE)
180 OnBackSpace();
181 return true;
183 else if (iControl == CONTROL_ENTER)
185 OnOK();
186 return true;
189 break;
191 case GUI_MSG_SET_TEXT:
192 SetMode(m_mode, message.GetLabel());
194 // close the dialog if requested
195 if (message.GetParam1() > 0)
196 OnOK();
197 break;
199 return CGUIDialog::OnMessage(message);
202 void CGUIDialogNumeric::OnBackSpace()
204 if (!m_dirty && m_block)
206 m_block--;
207 return;
209 if (m_mode == INPUT_NUMBER || m_mode == INPUT_PASSWORD)
210 { // just go back one character
211 if (!m_number.empty())
212 m_number.erase(m_number.size() - 1);
214 else if (m_mode == INPUT_IP_ADDRESS)
216 if (m_ip[m_block])
217 m_ip[m_block] /= 10;
218 else if (m_block)
220 m_block--;
221 m_dirty = false;
224 else if (m_mode == INPUT_TIME)
226 if (m_block == 0)
227 m_datetime.wHour /= 10;
228 else if (m_datetime.wMinute)
229 m_datetime.wMinute /= 10;
230 else
232 m_block = 0;
233 m_dirty = false;
236 else if (m_mode == INPUT_TIME_SECONDS)
238 if (m_block == 0) // minutes
239 m_datetime.wMinute /= 10;
240 else if (m_datetime.wSecond)
241 m_datetime.wSecond /= 10;
242 else
244 m_block = 0;
245 m_dirty = false;
248 else if (m_mode == INPUT_DATE)
250 if (m_block == 0)
251 m_datetime.wDay /= 10;
252 else if (m_block == 1)
254 if (m_datetime.wMonth)
255 m_datetime.wMonth /= 10;
256 else
258 m_block = 0;
259 m_dirty = false;
262 else if (m_datetime.wYear) // m_block == 2
263 m_datetime.wYear /= 10;
264 else
266 m_block = 1;
267 m_dirty = false;
272 void CGUIDialogNumeric::OnPrevious()
274 if (m_block)
275 m_block--;
276 m_dirty = false;
279 void CGUIDialogNumeric::OnNext()
281 if (m_mode == INPUT_IP_ADDRESS && m_block==0 && m_ip[0]==0)
282 return;
284 if (m_block < m_lastblock)
285 m_block++;
286 m_dirty = false;
287 if (m_mode == INPUT_DATE)
288 VerifyDate(m_block == 2);
291 void CGUIDialogNumeric::FrameMove()
293 CStdString strLabel;
294 unsigned int start = 0;
295 unsigned int end = 0;
296 if (m_mode == INPUT_PASSWORD)
298 for (unsigned int i=0; i < m_number.size(); i++)
299 strLabel += '*';
301 else if (m_mode == INPUT_NUMBER)
302 { // simple - just render text directly
303 strLabel = m_number;
305 else if (m_mode == INPUT_TIME)
306 { // format up the time
307 strLabel = StringUtils::Format("%2d:%02d", m_datetime.wHour, m_datetime.wMinute);
308 start = m_block * 3;
309 end = m_block * 3 + 2;
311 else if (m_mode == INPUT_TIME_SECONDS)
312 { // format up the time
313 strLabel = StringUtils::Format("%2d:%02d", m_datetime.wMinute, m_datetime.wSecond);
314 start = m_block * 3;
315 end = m_block * 3 + 2;
317 else if (m_mode == INPUT_DATE)
318 { // format up the date
319 strLabel = StringUtils::Format("%2d/%2d/%4d", m_datetime.wDay, m_datetime.wMonth, m_datetime.wYear);
320 start = m_block * 3;
321 end = m_block * 3 + 2;
322 if (m_block == 2)
323 end = m_block * 3 + 4;
325 else if (m_mode == INPUT_IP_ADDRESS)
326 { // format up the date
327 strLabel = StringUtils::Format("%3d.%3d.%3d.%3d", m_ip[0], m_ip[1], m_ip[2], m_ip[3]);
328 start = m_block * 4;
329 end = m_block * 4 + 3;
331 CGUILabelControl *pLabel = (CGUILabelControl *)GetControl(CONTROL_INPUT_LABEL);
332 if (pLabel)
334 pLabel->SetLabel(strLabel);
335 pLabel->SetHighlight(start, end);
337 CGUIDialog::FrameMove();
340 void CGUIDialogNumeric::OnNumber(unsigned int num)
342 ResetAutoClose();
344 if (m_mode == INPUT_NUMBER || m_mode == INPUT_PASSWORD)
346 m_number += num + '0';
348 else if (m_mode == INPUT_TIME)
350 if (m_block == 0) // hour
352 if (m_dirty) // have input the first digit
354 if (m_datetime.wHour < 2 || num < 4)
356 m_datetime.wHour *= 10;
357 m_datetime.wHour += num;
359 else
360 m_datetime.wHour = num;
361 m_block = 1; // move to minutes
362 m_dirty = false;
364 else // this is the first digit
366 m_datetime.wHour = num;
367 if (num > 2)
369 m_block = 1; // move to minutes
370 m_dirty = false;
372 else
373 m_dirty = true;
376 else // minute
378 if (m_dirty) // have input the first digit
380 m_datetime.wMinute *= 10;
381 m_datetime.wMinute += num;
382 m_block = 0; // move to hours
383 m_dirty = false;
385 else // this is the first digit
387 m_datetime.wMinute = num;
388 if (num > 5)
390 m_block = 0; // move to hours
391 m_dirty = false;
393 else
394 m_dirty = true;
398 else if (m_mode == INPUT_TIME_SECONDS)
400 if (m_block == 0) // minute
402 if (m_dirty) // have input the first digit
404 m_datetime.wMinute *= 10;
405 m_datetime.wMinute += num;
406 m_block = 1; // move to seconds - allows up to 99 minutes
407 m_dirty = false;
409 else // this is the first digit
411 m_datetime.wMinute = num;
412 m_dirty = true;
415 else // seconds
417 if (m_dirty) // have input the first digit
419 m_datetime.wSecond *= 10;
420 m_datetime.wSecond += num;
421 m_block = 0; // move to minutes
422 m_dirty = false;
424 else // this is the first digit
426 m_datetime.wSecond = num;
427 if (num > 5)
429 m_block = 0; // move to minutes
430 m_dirty = false;
432 else
433 m_dirty = true;
437 else if (m_mode == INPUT_DATE)
439 if (m_block == 0) // day of month
441 if (m_dirty && (m_datetime.wDay < 3 || num < 2))
443 m_datetime.wDay *= 10;
444 m_datetime.wDay += num;
446 else
447 m_datetime.wDay = num;
448 if (m_datetime.wDay > 3)
450 m_block = 1; // move to months
451 m_dirty = false;
453 else
454 m_dirty = true;
456 else if (m_block == 1) // months
458 if (m_dirty && num < 3)
460 m_datetime.wMonth *= 10;
461 m_datetime.wMonth += num;
463 else
464 m_datetime.wMonth = num;
465 if (m_datetime.wMonth > 1)
467 VerifyDate(false);
468 m_block = 2; // move to year
469 m_dirty = false;
471 else
472 m_dirty = true;
474 else // year
476 if (m_dirty && m_datetime.wYear < 1000) // have taken input
478 m_datetime.wYear *= 10;
479 m_datetime.wYear += num;
481 else
482 m_datetime.wYear = num;
483 if (m_datetime.wYear > 1000)
485 VerifyDate(true);
486 m_block = 0; // move to day of month
487 m_dirty = false;
489 else
490 m_dirty = true;
493 else if (m_mode == INPUT_IP_ADDRESS)
495 if (m_dirty && ((m_ip[m_block] < 25) || (m_ip[m_block] == 25 && num < 6) || !(m_block==0 && num==0)))
497 m_ip[m_block] *= 10;
498 m_ip[m_block] += num;
500 else
501 m_ip[m_block] = num;
502 if (m_ip[m_block] > 25 || (m_ip[m_block] == 0 && num == 0))
504 m_block++;
505 if (m_block > 3) m_block = 0;
506 m_dirty = false;
508 else
509 m_dirty = true;
513 void CGUIDialogNumeric::SetMode(INPUT_MODE mode, void *initial)
515 m_mode = mode;
516 m_block = 0;
517 m_lastblock = 0;
518 if (m_mode == INPUT_TIME || m_mode == INPUT_TIME_SECONDS || m_mode == INPUT_DATE)
520 m_datetime = *(SYSTEMTIME *)initial;
521 m_lastblock = (m_mode == INPUT_DATE) ? 2 : 1;
523 else if (m_mode == INPUT_IP_ADDRESS)
525 m_lastblock = 3;
526 m_ip[0] = m_ip[1] = m_ip[2] = m_ip[3] = 0;
527 // copy ip string into numeric form
528 CStdString ip = *(CStdString *)initial;
529 unsigned int block = 0;
530 for (unsigned int i=0; i < ip.size(); i++)
532 if (ip[i] == '.')
534 block++;
535 if (block > m_lastblock)
536 break;
538 else if (isdigit(ip[i]))
540 m_ip[block] *= 10;
541 m_ip[block] += ip[i] - '0';
545 else if (m_mode == INPUT_NUMBER || m_mode == INPUT_PASSWORD)
546 m_number = *(CStdString *)initial;
549 void CGUIDialogNumeric::SetMode(INPUT_MODE mode, const CStdString &initial)
551 m_mode = mode;
552 m_block = 0;
553 m_lastblock = 0;
554 if (m_mode == INPUT_TIME || m_mode == INPUT_TIME_SECONDS || m_mode == INPUT_DATE)
556 CDateTime dateTime;
557 if (m_mode == INPUT_TIME || m_mode == INPUT_TIME_SECONDS)
559 // check if we have a pure number
560 if (initial.find_first_not_of("0123456789") == std::string::npos)
562 long seconds = strtol(initial.c_str(), NULL, 10);
563 dateTime = seconds;
565 else
567 CStdString tmp = initial;
568 // if we are handling seconds and if the string only contains
569 // "mm:ss" we need to add dummy "hh:" to get "hh:mm:ss"
570 if (m_mode == INPUT_TIME_SECONDS && tmp.size() <= 5)
571 tmp = "00:" + tmp;
572 dateTime.SetFromDBTime(tmp);
575 else if (m_mode == INPUT_DATE)
577 CStdString tmp = initial;
578 StringUtils::Replace(tmp, '/', '.');
579 dateTime.SetFromDBDate(tmp);
582 if (!dateTime.IsValid())
583 return;
585 dateTime.GetAsSystemTime(m_datetime);
586 m_lastblock = (m_mode == INPUT_DATE) ? 2 : 1;
588 else
589 SetMode(mode, (void*)&initial);
592 void CGUIDialogNumeric::GetOutput(void *output) const
594 if (!output) return;
595 if (m_mode == INPUT_TIME || m_mode == INPUT_TIME_SECONDS || m_mode == INPUT_DATE)
596 memcpy(output, &m_datetime, sizeof(m_datetime));
597 else if (m_mode == INPUT_IP_ADDRESS)
598 *(CStdString *)output = StringUtils::Format("%d.%d.%d.%d", m_ip[0], m_ip[1], m_ip[2], m_ip[3]);
599 else if (m_mode == INPUT_NUMBER || m_mode == INPUT_PASSWORD)
600 *(CStdString *)output = m_number;
603 CStdString CGUIDialogNumeric::GetOutput() const
605 CStdString output;
606 if (m_mode == INPUT_DATE)
607 output = StringUtils::Format("%02i/%02i/%04i", m_datetime.wDay, m_datetime.wMonth, m_datetime.wYear);
608 else if (m_mode == INPUT_TIME)
609 output = StringUtils::Format("%i:%02i", m_datetime.wHour, m_datetime.wMinute);
610 else if (m_mode == INPUT_TIME_SECONDS)
611 output = StringUtils::Format("%i:%02i", m_datetime.wMinute, m_datetime.wSecond);
612 else
613 GetOutput(&output);
614 return output;
617 bool CGUIDialogNumeric::ShowAndGetSeconds(CStdString &timeString, const CStdString &heading)
619 CGUIDialogNumeric *pDialog = (CGUIDialogNumeric *)g_windowManager.GetWindow(WINDOW_DIALOG_NUMERIC);
620 if (!pDialog) return false;
621 int seconds = StringUtils::TimeStringToSeconds(timeString);
622 SYSTEMTIME time = {0};
623 time.wHour = seconds / 3600;
624 time.wMinute = (seconds - time.wHour * 3600) / 60;
625 time.wSecond = seconds - time.wHour * 3600 - time.wMinute * 60;
626 pDialog->SetMode(INPUT_TIME_SECONDS, (void *)&time);
627 pDialog->SetHeading(heading);
628 pDialog->DoModal();
629 if (!pDialog->IsConfirmed() || pDialog->IsCanceled())
630 return false;
631 pDialog->GetOutput(&time);
632 seconds = time.wHour * 3600 + time.wMinute * 60 + time.wSecond;
633 timeString = StringUtils::SecondsToTimeString(seconds);
634 return true;
637 bool CGUIDialogNumeric::ShowAndGetTime(SYSTEMTIME &time, const CStdString &heading)
639 CGUIDialogNumeric *pDialog = (CGUIDialogNumeric *)g_windowManager.GetWindow(WINDOW_DIALOG_NUMERIC);
640 if (!pDialog) return false;
641 pDialog->SetMode(INPUT_TIME, (void *)&time);
642 pDialog->SetHeading(heading);
643 pDialog->DoModal();
644 if (!pDialog->IsConfirmed() || pDialog->IsCanceled())
645 return false;
646 pDialog->GetOutput(&time);
647 return true;
650 bool CGUIDialogNumeric::ShowAndGetDate(SYSTEMTIME &date, const CStdString &heading)
652 CGUIDialogNumeric *pDialog = (CGUIDialogNumeric *)g_windowManager.GetWindow(WINDOW_DIALOG_NUMERIC);
653 if (!pDialog) return false;
654 pDialog->SetMode(INPUT_DATE, (void *)&date);
655 pDialog->SetHeading(heading);
656 pDialog->DoModal();
657 if (!pDialog->IsConfirmed() || pDialog->IsCanceled())
658 return false;
659 pDialog->GetOutput(&date);
660 return true;
663 bool CGUIDialogNumeric::ShowAndGetIPAddress(CStdString &IPAddress, const CStdString &heading)
665 CGUIDialogNumeric *pDialog = (CGUIDialogNumeric *)g_windowManager.GetWindow(WINDOW_DIALOG_NUMERIC);
666 if (!pDialog || !IPAddress) return false;
667 pDialog->SetMode(INPUT_IP_ADDRESS, (void *)&IPAddress);
668 pDialog->SetHeading(heading);
669 pDialog->DoModal();
670 if (!pDialog->IsConfirmed() || pDialog->IsCanceled())
671 return false;
672 pDialog->GetOutput(&IPAddress);
673 return true;
676 bool CGUIDialogNumeric::ShowAndGetNumber(CStdString& strInput, const CStdString &strHeading, unsigned int iAutoCloseTimeoutMs /* = 0 */)
678 // Prompt user for password input
679 CGUIDialogNumeric *pDialog = (CGUIDialogNumeric *)g_windowManager.GetWindow(WINDOW_DIALOG_NUMERIC);
680 pDialog->SetHeading( strHeading );
682 pDialog->SetMode(INPUT_NUMBER, (void *)&strInput);
683 if (iAutoCloseTimeoutMs)
684 pDialog->SetAutoClose(iAutoCloseTimeoutMs);
686 pDialog->DoModal();
688 if (!pDialog->IsAutoClosed() && (!pDialog->IsConfirmed() || pDialog->IsCanceled()))
689 return false;
690 pDialog->GetOutput(&strInput);
691 return true;
694 // \brief Show numeric keypad twice to get and confirm a user-entered password string.
695 // \param strNewPassword String to preload into the keyboard accumulator. Overwritten with user input if return=true.
696 // \return true if successful display and user input entry/re-entry. false if unsuccessful display, no user input, or canceled editing.
697 bool CGUIDialogNumeric::ShowAndVerifyNewPassword(CStdString& strNewPassword)
699 // Prompt user for password input
700 CStdString strUserInput = "";
701 if (!ShowAndVerifyInput(strUserInput, g_localizeStrings.Get(12340), false))
703 // Show error to user saying the password entry was blank
704 CGUIDialogOK::ShowAndGetInput(12357, 12358, 0, 0); // Password is empty/blank
705 return false;
708 if (strUserInput.empty())
709 // user canceled out
710 return false;
712 // Prompt again for password input, this time sending previous input as the password to verify
713 if (!ShowAndVerifyInput(strUserInput, g_localizeStrings.Get(12341), true))
715 // Show error to user saying the password re-entry failed
716 CGUIDialogOK::ShowAndGetInput(12357, 12344, 0, 0); // Password do not match
717 return false;
720 // password entry and re-entry succeeded
721 strNewPassword = strUserInput;
722 return true;
725 // \brief Show numeric keypad and verify user input against strPassword.
726 // \param strPassword Value to compare against user input.
727 // \param strHeading String shown on dialog title. Converts to localized string if contains a positive integer.
728 // \param iRetries If greater than 0, shows "Incorrect password, %d retries left" on dialog line 2, else line 2 is blank.
729 // \return 0 if successful display and user input. 1 if unsuccessful input. -1 if no user input or canceled editing.
730 int CGUIDialogNumeric::ShowAndVerifyPassword(CStdString& strPassword, const CStdString& strHeading, int iRetries)
732 CStdString strTempHeading = strHeading;
733 if (0 < iRetries)
735 // Show a string telling user they have iRetries retries left
736 strTempHeading = StringUtils::Format("%s. %s %i %s", strHeading.c_str(), g_localizeStrings.Get(12342).c_str(), iRetries, g_localizeStrings.Get(12343).c_str());
738 // make a copy of strPassword to prevent from overwriting it later
739 CStdString strPassTemp = strPassword;
740 if (ShowAndVerifyInput(strPassTemp, strTempHeading, true))
741 return 0; // user entered correct password
742 if (strPassTemp.empty()) return -1; // user canceled out
743 return 1; // user must have entered an incorrect password
746 // \brief Show numeric keypad and verify user input against strToVerify.
747 // \param strToVerify Value to compare against user input.
748 // \param dlgHeading String shown on dialog title.
749 // \param bVerifyInput If set as true we verify the users input versus strToVerify.
750 // \return true if successful display and user input. false if unsuccessful display, no user input, or canceled editing.
751 bool CGUIDialogNumeric::ShowAndVerifyInput(CStdString& strToVerify, const CStdString& dlgHeading, bool bVerifyInput)
753 // Prompt user for password input
754 CGUIDialogNumeric *pDialog = (CGUIDialogNumeric *)g_windowManager.GetWindow(WINDOW_DIALOG_NUMERIC);
755 pDialog->SetHeading( dlgHeading );
757 CStdString strInput = "";
758 if (!bVerifyInput)
759 strInput = strToVerify;
760 pDialog->SetMode(INPUT_PASSWORD, (void *)&strInput);
761 pDialog->DoModal();
763 pDialog->GetOutput(&strInput);
765 if (!pDialog->IsConfirmed() || pDialog->IsCanceled())
767 // user canceled out
768 strToVerify ="";
769 return false;
772 CStdString md5pword2;
773 XBMC::XBMC_MD5 md5state;
774 md5state.append(strInput);
775 md5state.getDigest(md5pword2);
777 if (!bVerifyInput)
779 strToVerify = md5pword2;
780 StringUtils::ToLower(strToVerify);
781 return true;
784 if (strToVerify.Equals(md5pword2))
785 return true; // entered correct password
787 // incorrect password
788 return false;
791 bool CGUIDialogNumeric::IsConfirmed() const
793 return m_bConfirmed;
796 bool CGUIDialogNumeric::IsCanceled() const
798 return m_bCanceled;
801 void CGUIDialogNumeric::SetHeading(const CStdString& strHeading)
803 Initialize();
804 CGUIMessage msg(GUI_MSG_LABEL_SET, GetID(), CONTROL_HEADING_LABEL);
805 msg.SetLabel(strHeading);
806 OnMessage(msg);
809 void CGUIDialogNumeric::VerifyDate(bool checkYear)
811 if (m_datetime.wDay == 0)
812 m_datetime.wDay = 1;
813 if (m_datetime.wMonth == 0)
814 m_datetime.wMonth = 1;
815 // check for number of days in the month
816 if (m_datetime.wDay == 31)
818 if (m_datetime.wMonth == 4 || m_datetime.wMonth == 6 || m_datetime.wMonth == 9 || m_datetime.wMonth == 11)
819 m_datetime.wDay = 30;
821 if (m_datetime.wMonth == 2 && m_datetime.wDay > 28)
823 m_datetime.wDay = 29; // max in february.
824 if (checkYear)
826 // leap years occur when the year is divisible by 4 but not by 100, or the year is divisible by 400
827 // thus they don't occur, if the year has a remainder when divided by 4, or when the year is divisible by 100 but not by 400
828 if ( (m_datetime.wYear % 4) || ( !(m_datetime.wYear % 100) && (m_datetime.wYear % 400) ) )
829 m_datetime.wDay = 28;
834 void CGUIDialogNumeric::OnOK()
836 m_bConfirmed = true;
837 m_bCanceled = false;
838 Close();
841 void CGUIDialogNumeric::OnCancel()
843 m_bConfirmed = false;
844 m_bCanceled = true;
845 Close();