Neal Wilson 9 years ago
parent
commit
3c85ba8437
1 changed files with 65 additions and 2 deletions
  1. 65
    2
      src/typica.w

+ 65
- 2
src/typica.w View File

@@ -5717,6 +5717,66 @@ void NumericDelegate::updateEditorGeometry(QWidget *editor,
5717 5717
     editor->setGeometry(option.rect);
5718 5718
 }
5719 5719
 
5720
+@ The same general technique is useful for input to a |QLineEdit|, but there is
5721
+no model backing that widget to preserve multiple data roles. One way to get
5722
+this functionality without too much effort is to abuse |QValidator| to evaluate
5723
+expressions.
5724
+
5725
+@<Class declarations@>=
5726
+class ScriptValidator : public QValidator
5727
+{
5728
+	Q_OBJECT
5729
+	public:
5730
+		ScriptValidator(QValidator *validator, QObject *parent = NULL);
5731
+		void fixup(QString &input) const;
5732
+		QValidator::State validate(QString &input, int &pos) const;
5733
+	private:
5734
+		QValidator *v;
5735
+};
5736
+
5737
+@ The key to this is in the |fixup()| method. Here we over-write input with the
5738
+result of the script evaluation.
5739
+
5740
+@<ScriptValidator implementation@>=
5741
+void ScriptValidator::fixup(QString &input) const
5742
+{
5743
+	QScriptEngine *engine = AppInstance->engine;
5744
+	engine->pushContext();
5745
+	input = engine->evaluate(input).toString();
5746
+	engine->popContext();
5747
+}
5748
+
5749
+@ This validator is intended to be used in conjunction with another one which
5750
+determines if the result of the expression is acceptable. In this case
5751
+|Invalid| is never returned.
5752
+
5753
+@<ScriptValidator implementation@>=
5754
+QValidator::State ScriptValidator::validate(QString &input, int &pos) const
5755
+{
5756
+	if(v)
5757
+	{
5758
+		if(v->validate(input, pos) == QValidator::Acceptable)
5759
+		{
5760
+			return QValidator::Acceptable;
5761
+		}
5762
+	}
5763
+	return QValidator::Intermediate;
5764
+}
5765
+
5766
+@ The constructor is trivial.
5767
+
5768
+@<ScriptValidator implementation@>=
5769
+ScriptValidator::ScriptValidator(QValidator *validator, QObject *parent)
5770
+	: QValidator(parent), v(validator)
5771
+{
5772
+	/* Nothing needs to be done here. */
5773
+}
5774
+
5775
+@ This is included in typica.cpp.
5776
+
5777
+@<Class implementations@>=
5778
+@<ScriptValidator implementation@>
5779
+
5720 5780
 @ Line edits are useful when the user is expected to enter text without a
5721 5781
 predetermined set of values.
5722 5782
 
@@ -5730,6 +5790,9 @@ restricted to integer values. Finally, if the value is {\tt "expression"}, input
5730 5790
 is restricted to text which matches a regular expression specified as the value
5731 5791
 of the {\tt expression} attribute.
5732 5792
 
5793
+Note that when integer and numeric validators are specified, these are set for
5794
+a |ScriptValidator| to enable some basic expression evaluation.
5795
+
5733 5796
 @<Functions for scripting@>=
5734 5797
 void addLineToLayout(QDomElement element, QStack<QWidget *> *,@|
5735 5798
                      QStack<QLayout *> *layoutStack)
@@ -5750,11 +5813,11 @@ void addLineToLayout(QDomElement element, QStack<QWidget *> *,@|
5750 5813
     {
5751 5814
         if(element.attribute("validator") == "numeric")
5752 5815
         {
5753
-            widget->setValidator(new QDoubleValidator(NULL));
5816
+            widget->setValidator(new ScriptValidator(new QDoubleValidator));
5754 5817
         }
5755 5818
         else if(element.attribute("validator") == "integer")
5756 5819
         {
5757
-            widget->setValidator(new QIntValidator(NULL));
5820
+            widget->setValidator(new ScriptValidator(new QIntValidator));
5758 5821
         }
5759 5822
         else if(element.attribute("validator") == "expression" &&
5760 5823
                 element.hasAttribute("expression"))

Loading…
Cancel
Save