guilib: add input validation functionality to CGUIEditControl
authormontellese <montellese@xbmc.org>
Fri, 9 Aug 2013 09:18:21 +0000 (11:18 +0200)
committermontellese <montellese@xbmc.org>
Mon, 9 Sep 2013 05:57:42 +0000 (07:57 +0200)
xbmc/guilib/GUIEditControl.cpp
xbmc/guilib/GUIEditControl.h
xbmc/guilib/GUIMessage.h
xbmc/utils/StringValidation.h [new file with mode: 0644]

index e4349b4..6179a51 100644 (file)
@@ -66,6 +66,9 @@ void CGUIEditControl::DefaultConstructor()
   m_label.SetAlign(m_label.GetLabelInfo().align & XBFONT_CENTER_Y); // left align
   m_label2.GetLabelInfo().offsetX = 0;
   m_isMD5 = false;
+  m_invalidInput = false;
+  m_inputValidator = NULL;
+  m_inputValidatorData = NULL;
 }
 
 CGUIEditControl::CGUIEditControl(const CGUIButtonControl &button)
@@ -335,6 +338,8 @@ void CGUIEditControl::UpdateText(bool sendUpdate)
   m_smsTimer.Stop();
   if (sendUpdate)
   {
+    ValidateInput();
+
     SEND_CLICK_MESSAGE(GetID(), GetParentID(), 0);
 
     m_textChangeActions.ExecuteActions(GetID(), GetParentID());
@@ -508,6 +513,7 @@ void CGUIEditControl::SetLabel2(const std::string &text)
     m_isMD5 = (m_inputType == INPUT_TYPE_PASSWORD_MD5 || m_inputType == INPUT_TYPE_PASSWORD_NUMBER_VERIFY_NEW);
     m_text2 = newText;
     m_cursorPos = m_text2.size();
+    ValidateInput();
     SetInvalid();
   }
 }
@@ -598,3 +604,40 @@ void CGUIEditControl::OnPasteClipboard()
     UpdateText();
   }
 }
+
+void CGUIEditControl::SetInputValidation(StringValidation::Validator inputValidator, void *data /* = NULL */)
+{
+  if (m_inputValidator == inputValidator)
+    return;
+  
+  m_inputValidator = inputValidator;
+  m_inputValidatorData = data;
+  // the input validator has changed, so re-validate the current data
+  ValidateInput();
+}
+
+bool CGUIEditControl::ValidateInput(const CStdStringW &data) const
+{
+  if (m_inputValidator == NULL)
+    return true;
+
+  return m_inputValidator(GetLabel2(), (void*)(m_inputValidatorData != NULL ? m_inputValidatorData : this));
+}
+
+void CGUIEditControl::ValidateInput()
+{
+  // validate the input
+  bool invalid = !ValidateInput(m_text2);
+  // nothing to do if still valid/invalid
+  if (invalid != m_invalidInput)
+  {
+    // the validity state has changed so we need to update the control
+    m_invalidInput = invalid;
+
+    // let the window/dialog know that the validity has changed
+    CGUIMessage msg(GUI_MSG_VALIDITY_CHANGED, GetID(), GetID(), m_invalidInput ? 0 : 1);
+    SendWindowMessage(msg);
+
+    SetInvalid();
+  }
+}
index 7eb28ff..4436cd0 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "GUIButtonControl.h"
 #include "utils/Stopwatch.h"
+#include "utils/StringValidation.h"
 
 /*!
  \ingroup controls
@@ -80,6 +81,9 @@ public:
 
   bool HasTextChangeActions() const { return m_textChangeActions.HasActionsMeetingCondition(); };
 
+  virtual bool HasInvalidInput() const { return m_invalidInput; }
+  virtual void SetInputValidation(StringValidation::Validator inputValidator, void *data = NULL);
+
 protected:
   virtual void ProcessText(unsigned int currentTime);
   virtual void RenderText();
@@ -91,6 +95,9 @@ protected:
   void OnSMSCharacter(unsigned int key);
   void DefaultConstructor();  
 
+  virtual bool ValidateInput(const CStdStringW &data) const;
+  void ValidateInput();
+
   /*! \brief Clear out the current text input if it's an MD5 password.
    \return true if the password is cleared, false otherwise.
    */
@@ -114,6 +121,10 @@ protected:
 
   CGUIAction m_textChangeActions;
 
+  bool m_invalidInput;
+  StringValidation::Validator m_inputValidator;
+  void *m_inputValidatorData;
+
   unsigned int m_smsKeyIndex;
   unsigned int m_smsLastKey;
   CStopWatch   m_smsTimer;
index 2b76ad0..eef8232 100644 (file)
 
 #define GUI_MSG_WINDOW_LOAD 43
 
+#define GUI_MSG_VALIDITY_CHANGED  44
+
 #define GUI_MSG_USER         1000
 
 /*!
diff --git a/xbmc/utils/StringValidation.h b/xbmc/utils/StringValidation.h
new file mode 100644 (file)
index 0000000..eb2fbd8
--- /dev/null
@@ -0,0 +1,33 @@
+#pragma once
+/*
+ *      Copyright (C) 2013 Team XBMC
+ *      http://xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <string>
+
+class StringValidation
+{
+public:
+  typedef bool (*Validator)(const std::string &input, void *data);
+
+  static bool NonEmpty(const std::string &input, void *data) { return !input.empty(); }
+
+private:
+  StringValidation() { }
+};