[rkward-cvs] SF.net SVN: rkward:[4463] trunk/rkward

tfry at users.sourceforge.net tfry at users.sourceforge.net
Tue Nov 27 21:00:45 UTC 2012


Revision: 4463
          http://rkward.svn.sourceforge.net/rkward/?rev=4463&view=rev
Author:   tfry
Date:     2012-11-27 21:00:44 +0000 (Tue, 27 Nov 2012)
Log Message:
-----------
Add more options for type safe fetching of data from .js. In particular getList() allows to fetch string lists, directly.

Modified Paths:
--------------
    trunk/rkward/ChangeLog
    trunk/rkward/rkward/plugin/rkcomponentproperties.cpp
    trunk/rkward/rkward/plugin/rkcomponentproperties.h
    trunk/rkward/rkward/plugin/rkoptionset.cpp
    trunk/rkward/rkward/plugin/rkstandardcomponent.cpp
    trunk/rkward/rkward/plugin/rkstandardcomponent.h
    trunk/rkward/rkward/plugins/testing/optionset.js
    trunk/rkward/rkward/scriptbackends/common.js
    trunk/rkward/rkward/scriptbackends/qtscriptbackend.cpp
    trunk/rkward/rkward/scriptbackends/qtscriptbackend.h
    trunk/rkward/rkward/scriptbackends/scriptbackend.h
    trunk/rkward/rkward/scriptbackends/simplebackend.cpp
    trunk/rkward/rkward/scriptbackends/simplebackend.h

Modified: trunk/rkward/ChangeLog
===================================================================
--- trunk/rkward/ChangeLog	2012-11-27 16:09:16 UTC (rev 4462)
+++ trunk/rkward/ChangeLog	2012-11-27 21:00:44 UTC (rev 4463)
@@ -1,4 +1,5 @@
-- Boolean properties now return a numeric, not labelled representation of their value, by default. <checkbox>es should be unaffected.
+- New functions getString(), getList() and getBoolean() for fetching data in plugin scripts		TODO: document, more testing
+- Boolean properties now return a numeric, not labelled representation of their value, by default. <checkbox>es should be unaffected.	TODO: when announcing release, link to explanation mail.
 - Added GUI element for entering a set of options for an arbitrary number of items		TODO: document
 - Reduce CPU usage of pluings while idle
 - Fix conversion from Numeric to Factor in the data editor

Modified: trunk/rkward/rkward/plugin/rkcomponentproperties.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentproperties.cpp	2012-11-27 16:09:16 UTC (rev 4462)
+++ trunk/rkward/rkward/plugin/rkcomponentproperties.cpp	2012-11-27 21:00:44 UTC (rev 4463)
@@ -275,6 +275,21 @@
 	return false;
 }
 
+bool RKComponentPropertyBool::variantToBool (const QVariant &value, bool *ok) {
+	if (value.type () == QVariant::Bool) {
+		if (ok) *ok = true;
+		return value.toBool ();
+	} else if (value.canConvert (QVariant::Int)) {
+		bool valid;
+		bool ret = (bool) value.toInt (&valid);
+		if (valid) {
+			if (ok) *ok = true;
+			return ret;
+		}
+	}
+	return stringToBool (value.toString (), ok);
+}
+
 void RKComponentPropertyBool::internalSetValue (const QString &new_value) {
 	RK_TRACE (PLUGIN);
 
@@ -1209,9 +1224,7 @@
 				break;
 			} case And: {
 				bool ok;
-				QVariant v = source.property->value (source.modifier);
-				bool val = (bool) v.toInt (&ok);
-				if (!ok) val = stringToBool (fetchStringValue(source.property, source.modifier), &ok);
+				bool val = variantToBool (source.property->value (source.modifier), &ok);
 				if (ok) {
 					if (!val) {
 						setBoolValue (false);
@@ -1223,9 +1236,7 @@
 				break;
 			} case Or: {
 				bool ok;
-				QVariant v = source.property->value (source.modifier);
-				bool val = (bool) v.toInt (&ok);
-				if (!ok) val = stringToBool (fetchStringValue(source.property, source.modifier), &ok);
+				bool val = variantToBool (source.property->value (source.modifier), &ok);
 				if (ok) {
 					if (val) {
 						setBoolValue (true);

Modified: trunk/rkward/rkward/plugin/rkcomponentproperties.h
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentproperties.h	2012-11-27 16:09:16 UTC (rev 4462)
+++ trunk/rkward/rkward/plugin/rkcomponentproperties.h	2012-11-27 21:00:44 UTC (rev 4463)
@@ -131,6 +131,7 @@
 /** reimplemented to return a new negated boolean property if the identifier is "not" */
 	RKComponentBase* lookupComponent (const QString &identifier, QString *remainder);
 	static bool stringToBool (const QString &value, bool *ok);
+	static bool variantToBool (const QVariant &value, bool *ok);
 private:
 /** helper function. Sets the value without emitting change signal */
 	void internalSetValue (bool new_value);

Modified: trunk/rkward/rkward/plugin/rkoptionset.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkoptionset.cpp	2012-11-27 16:09:16 UTC (rev 4462)
+++ trunk/rkward/rkward/plugin/rkoptionset.cpp	2012-11-27 21:00:44 UTC (rev 4463)
@@ -154,9 +154,6 @@
 					if (!ci.governor_modifier.isEmpty ()) {
 						RK_DO (qDebug ("Cannot connect external column '%s' in optionset to property with modifier (%s).", qPrintable (ci.column_name), qPrintable (ci.governor)), PLUGIN, DL_ERROR);
 						continue;
-					} else if (gov_prop->isInternal ()) {
-						RK_DO (qDebug ("Cannot connect external column '%s' in optionset to property (%s), which is marked 'internal'.", qPrintable (ci.column_name), qPrintable (ci.governor)), PLUGIN, DL_ERROR);
-						continue;
 					}
 				}
 				columns_to_update.insertMulti (gov_prop, it.key ());

Modified: trunk/rkward/rkward/plugin/rkstandardcomponent.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponent.cpp	2012-11-27 16:09:16 UTC (rev 4462)
+++ trunk/rkward/rkward/plugin/rkstandardcomponent.cpp	2012-11-27 21:00:44 UTC (rev 4463)
@@ -111,7 +111,7 @@
 		backend = back;
 	}
 	connect (backend, SIGNAL (idle ()), this, SLOT (backendIdle ()));
-	connect (backend, SIGNAL (requestValue (const QString&)), this, SLOT (getValue (const QString&)));
+	connect (backend, SIGNAL (requestValue (const QString&, const int)), this, SLOT (getValue (const QString&, const int)));
 	connect (backend, SIGNAL (haveError ()), this, SLOT (kill ()));
 	if (!backend->initialize (code, parent_component == 0)) return;
 
@@ -419,11 +419,36 @@
 	RKComponent::changed ();		// notify parent, if any
 }
 
-void RKStandardComponent::getValue (const QString &id) {
+void RKStandardComponent::getValue (const QString &id, const int hint) {
 	RK_TRACE (PLUGIN);
 	RK_ASSERT (backend);
 
-	backend->writeData (fetchStringValue (id));
+	if (hint == StringValue) {
+		backend->writeData (fetchStringValue (id));
+	} else if (hint == TraditionalValue) {
+		QString val = fetchStringValue (id);
+		// return "0" as numeric constant. Many plugins rely on this form PHP times.
+		if (val == "0") backend->writeData (QVariant (0.0));
+		else backend->writeData (QVariant (val));
+	} else {
+		QString mod;
+		RKComponentBase *prop = lookupComponent (id, &mod);
+		QVariant val = prop->value (mod);
+		if (hint == BooleanValue) {
+			bool ok;
+			backend->writeData (RKComponentPropertyBool::variantToBool (val, &ok));
+			if (!ok) RK_DO (qDebug ("Could not convert value of %s to boolean", qPrintable (id)), PLUGIN, DL_WARNING);
+		} else {
+			if (hint == StringlistValue) {
+				if (val.type () != QVariant::StringList) RK_DO (qDebug ("Value of %s is not a string list", qPrintable (id)), PLUGIN, DL_WARNING);
+			} else if (hint == NumericValue) {
+				if (!val.canConvert (QVariant::Double)) RK_DO (qDebug ("Value of %s is not numeric", qPrintable (id)), PLUGIN, DL_WARNING);
+			} else {
+				RK_ASSERT (false);
+			}
+			backend->writeData (val);
+		}
+	}
 }
 
 bool RKStandardComponent::isWizardish () {

Modified: trunk/rkward/rkward/plugin/rkstandardcomponent.h
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponent.h	2012-11-27 16:09:16 UTC (rev 4462)
+++ trunk/rkward/rkward/plugin/rkstandardcomponent.h	2012-11-27 21:00:44 UTC (rev 4463)
@@ -81,6 +81,14 @@
 
 /** Return the GUI-scripting handler (creating it, if needed) */
 	RKComponentScriptingProxy* scriptingProxy ();
+
+	enum ValueTypeHint {
+		TraditionalValue,
+		BooleanValue,
+		StringValue,
+		StringlistValue,
+		NumericValue
+	};
 signals:
 	void standardInitializationComplete ();
 public slots:
@@ -91,8 +99,8 @@
 //	void getRVector (const QString &call);
 /** return result of given call to the R-backend */
 //	void doRCall (const QString &call);
-/** get a value for the backend */
-	void getValue (const QString &id);
+/** get a value for the backend. Note: hint should be one of ValueTypeHint */
+	void getValue (const QString &id, const int hint);
 /** reimplemented from QWidget to hide the gui if applicable */
 	void hide ();
 /** for enslaved components */

Modified: trunk/rkward/rkward/plugins/testing/optionset.js
===================================================================
--- trunk/rkward/rkward/plugins/testing/optionset.js	2012-11-27 16:09:16 UTC (rev 4462)
+++ trunk/rkward/rkward/plugins/testing/optionset.js	2012-11-27 21:00:44 UTC (rev 4463)
@@ -8,11 +8,11 @@
 	echo ("current_row <- " + getValue ("set.current_row") + "\n");
 	echo ("set.contents.enabled <- " + getValue ("set.contents.enabled") + "\n");
 
-	var codeprops = getValue ("set.plotoption_printout").split ("\n");
+	var codeprops = getList ("set.plotoption_printout");
 	for (i = 0; i < codeprops.length; ++i) {
 		echo ("Plotoption string printout " + i + " in driven set: " + codeprops[i] + "\n");
 	}
-	codeprops = getValue ("set.plotoption_pre").split ("\n");
+	codeprops = getList ("set.plotoption_pre");
 	for (i = 0; i < codeprops.length; ++i) {
 		echo ("Plotoption string preprocess " + i + " in driven set: " + codeprops[i] + "\n");
 	}

Modified: trunk/rkward/rkward/scriptbackends/common.js
===================================================================
--- trunk/rkward/rkward/scriptbackends/common.js	2012-11-27 16:09:16 UTC (rev 4462)
+++ trunk/rkward/rkward/scriptbackends/common.js	2012-11-27 21:00:44 UTC (rev 4463)
@@ -50,9 +50,19 @@
 
 getString = function (id) {
 	// getValue() sometimes returns numeric results (whenever the value is "0"). This variant always returns strings.
-	return (getValue (id).toString ());
+	return (_RK_backend.getString (id));
 }
 
+getList = function (id) {
+	// will try to return value as list, and produces a warning, if that fails.
+	return (_RK_backend.getList (id));
+}
+
+getBoolean = function (id) {
+	// will try to return value as logical, and produces a warning, if that fails.
+	return (_RK_backend.getBoolean (id));
+}
+
 printValue = function (id) {
 	echo (getValue (id));
 }

Modified: trunk/rkward/rkward/scriptbackends/qtscriptbackend.cpp
===================================================================
--- trunk/rkward/rkward/scriptbackends/qtscriptbackend.cpp	2012-11-27 16:09:16 UTC (rev 4462)
+++ trunk/rkward/rkward/scriptbackends/qtscriptbackend.cpp	2012-11-27 21:00:44 UTC (rev 4463)
@@ -56,7 +56,7 @@
 	script_thread = new QtScriptBackendThread (common_js, filename, this);
 	connect (script_thread, SIGNAL (error(const QString&)), this, SLOT (threadError(const QString&)));
 	connect (script_thread, SIGNAL (commandDone(const QString&)), this, SLOT (commandDone(const QString&)));
-	connect (script_thread, SIGNAL (needData(const QString&)), this, SLOT (needData(const QString&)));
+	connect (script_thread, SIGNAL (needData(const QString&, const int)), this, SLOT (needData(const QString&, const int)));
 	current_type = ScriptBackend::Ignore;
 	script_thread->start ();
 
@@ -105,10 +105,10 @@
 	}
 }
 
-void QtScriptBackend::writeData (const QString &data) {
+void QtScriptBackend::writeData (const QVariant &data) {
 	RK_TRACE (PHP);
 
-	RK_DO (qDebug ("submitting data: %s", data.toLatin1 ().data ()), PHP, DL_DEBUG);
+	RK_DO (qDebug ("submitting data: %s", qPrintable (data.toString ())), PHP, DL_DEBUG);
 	script_thread->setData (data);
 	tryNextFunction ();
 }
@@ -130,10 +130,10 @@
 	commandFinished (result);
 }
 
-void QtScriptBackend::needData (const QString &identifier) {
+void QtScriptBackend::needData (const QString &identifier, const int hint) {
 	RK_TRACE (PHP);
 
-	emit (requestValue (identifier));
+	emit (requestValue (identifier, hint));
 }
 
 
@@ -177,7 +177,7 @@
 	mutex.unlock ();
 }
 
-void QtScriptBackendThread::setData (const QString &data) {
+void QtScriptBackendThread::setData (const QVariant &data) {
 	RK_TRACE (PHP);
 
 	mutex.lock ();
@@ -187,12 +187,12 @@
 	mutex.unlock ();
 }
 
-QVariant QtScriptBackendThread::getValue (const QString &identifier) {
+QVariant QtScriptBackendThread::getValue (const QString &identifier, const int hint) {
 	RK_TRACE (PHP);
 
-	emit (needData (identifier));
+	emit (needData (identifier, hint));
 
-	QString ret;
+	QVariant ret;
 	while (1) {
 		if (killed) return QVariant ();
 
@@ -207,12 +207,25 @@
 
 		usleep (20);	// getValue () may be called very often, and we expect an answer very soon, so we don't sleep too long.
 	}
+	return (ret);
+}
 
-	// return "0" as numeric constant. Many plugins rely on this form PHP times.
-	if (ret == "0") return (QVariant (0.0));
-	else return (QVariant (ret));
+QVariant QtScriptBackendThread::getValue (const QString &identifier) {
+	return getValue (identifier, RKStandardComponent::TraditionalValue);
 }
 
+QVariant QtScriptBackendThread::getList (const QString &identifier) {
+	return getValue (identifier, RKStandardComponent::StringlistValue);
+}
+
+QVariant QtScriptBackendThread::getString (const QString &identifier) {
+	return getValue (identifier, RKStandardComponent::StringValue);
+}
+
+QVariant QtScriptBackendThread::getBoolean (const QString &identifier) {
+	return getValue (identifier, RKStandardComponent::BooleanValue);
+}
+
 bool QtScriptBackendThread::scriptError () {
 	RK_TRACE (PHP);
 

Modified: trunk/rkward/rkward/scriptbackends/qtscriptbackend.h
===================================================================
--- trunk/rkward/rkward/scriptbackends/qtscriptbackend.h	2012-11-27 16:09:16 UTC (rev 4462)
+++ trunk/rkward/rkward/scriptbackends/qtscriptbackend.h	2012-11-27 21:00:44 UTC (rev 4463)
@@ -41,11 +41,11 @@
 	void calculate (int flags) { callFunction ("do_calculate ();\n", flags, Calculate); };
 	void printout (int flags) { callFunction ("do_printout ();\n", flags, Printout); };
 	void preview (int flags) { callFunction ("do_preview ();\n", flags, Preview); };
-	void writeData (const QString &data);
+	void writeData (const QVariant &data);
 public slots:
 	void threadError (const QString &message);
 	void commandDone (const QString &result);
-	void needData (const QString &identifier);
+	void needData (const QString &identifier, const int hint);
 private:
 	void tryNextFunction ();
 	QtScriptBackendThread *script_thread;
@@ -66,24 +66,28 @@
 	~QtScriptBackendThread ();
 
 	void setCommand (const QString &command);
-	void setData (const QString &data);
+	void setData (const QVariant &data);
 	void kill () { killed = true; };
 	void goToSleep (bool sleep);
 signals:
 	void commandDone (const QString &result);
-	void needData (const QString &identifier);
+	void needData (const QString &identifier, const int hint);
 	void error (const QString &error);
 protected slots:
 	QVariant getValue (const QString &identifier);
+	QVariant getList (const QString &identifier);
+	QVariant getString (const QString &identifier);
+	QVariant getBoolean (const QString &identifier);
 	bool includeFile (const QString &filename);
 protected:
 	void run ();
 private:
 	/** for any script error in the last evaluation. If there was an error, a message is generated, and this function return true (and the thread should be made to exit!) */
 	bool scriptError ();
+	QVariant getValue (const QString &identifier, const int hint);
 
 	QString _command;
-	QString _data;
+	QVariant _data;
 	QString _commonfile;
 	QString _scriptfile;
 

Modified: trunk/rkward/rkward/scriptbackends/scriptbackend.h
===================================================================
--- trunk/rkward/rkward/scriptbackends/scriptbackend.h	2012-11-27 16:09:16 UTC (rev 4462)
+++ trunk/rkward/rkward/scriptbackends/scriptbackend.h	2012-11-27 21:00:44 UTC (rev 4463)
@@ -2,7 +2,7 @@
                           scriptbackend  -  description
                              -------------------
     begin                : Sun Aug 15 2004
-    copyright            : (C) 2004, 2007 by Thomas Friedrichsmeier
+    copyright            : (C) 2004, 2007, 2012 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -22,6 +22,8 @@
 #include <qstring.h>
 #include <QLinkedList>
 
+#include "../plugin/rkstandardcomponent.h"
+
 class RKComponentPropertyCode;
 
 /**
@@ -59,11 +61,11 @@
 	
 	virtual bool isBusy () { return busy; };
 	
-	virtual void writeData (const QString &data) = 0;
+	virtual void writeData (const QVariant &data) = 0;
 signals:
 	void commandDone (int);
 	void idle ();
-	void requestValue (const QString &);
+	void requestValue (const QString &, const int);
 	void haveError ();
 protected:
 	RKComponentPropertyCode *code_property;

Modified: trunk/rkward/rkward/scriptbackends/simplebackend.cpp
===================================================================
--- trunk/rkward/rkward/scriptbackends/simplebackend.cpp	2012-11-27 16:09:16 UTC (rev 4462)
+++ trunk/rkward/rkward/scriptbackends/simplebackend.cpp	2012-11-27 21:00:44 UTC (rev 4463)
@@ -2,7 +2,7 @@
                           simplebackend  -  description
                              -------------------
     begin                : Thu May 10 2007
-    copyright            : (C) 2007 by Thomas Friedrichsmeier
+    copyright            : (C) 2007, 2012 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -67,7 +67,7 @@
 	callFunction (QString::null, flags, Preview);
 }
 
-void SimpleBackend::writeData (const QString &data) {
+void SimpleBackend::writeData (const QVariant &data) {
 	RK_TRACE (PHP);
 
 	current_values.append (data);
@@ -120,7 +120,7 @@
 		RK_ASSERT (token_end >= 0);
 		QString token = current_template.mid (next_token + 3, token_end - (next_token + 3));
 		template_pos = token_end + 3;
-		emit (requestValue (token));
+		emit (requestValue (token, RKStandardComponent::StringValue));
 		return;
 	}
 
@@ -135,7 +135,7 @@
 	int repl = current_values.count();
 	for (int i = repl; i > 0; --i) {
 		QString placeholder = "%" + QString::number (i);
-		QString replacement = current_values[i-1];
+		QString replacement = current_values[i-1].toString ();
 		conds.replace (placeholder, replacement);
 	}
 

Modified: trunk/rkward/rkward/scriptbackends/simplebackend.h
===================================================================
--- trunk/rkward/rkward/scriptbackends/simplebackend.h	2012-11-27 16:09:16 UTC (rev 4462)
+++ trunk/rkward/rkward/scriptbackends/simplebackend.h	2012-11-27 21:00:44 UTC (rev 4463)
@@ -2,7 +2,7 @@
                           simplebackend  -  description
                              -------------------
     begin                : Thu May 10 2007
-    copyright            : (C) 2007 by Thomas Friedrichsmeier
+    copyright            : (C) 2007, 2012 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -48,7 +48,7 @@
 	void printout (int flags);
 	void preview (int flags);
 	
-	void writeData (const QString &data);
+	void writeData (const QVariant &data);
 	void tryNextFunction ();
 private:
 	QString preprocess_template;
@@ -59,7 +59,7 @@
 
 	int template_sep;
 	int template_pos;
-	QStringList current_values;
+	QList<QVariant> current_values;
 
 	void processCall ();
 	void finishCall (const QString &conditions);

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.





More information about the rkward-tracker mailing list