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

tfry at users.sourceforge.net tfry at users.sourceforge.net
Tue May 12 15:22:24 UTC 2009


Revision: 2467
          http://rkward.svn.sourceforge.net/rkward/?rev=2467&view=rev
Author:   tfry
Date:     2009-05-12 15:22:24 +0000 (Tue, 12 May 2009)

Log Message:
-----------
This changeset adds a "Run again" link after the output of each plugin in the output window.
Detailed items in this changeset (all needed to make the above possible):
- mark some component properties as "internal"
- serialize / unserialize plugin settings
- add handling for rkward://runplugin/-subprotocol
- parameterized invocation of plugins by id

Modified Paths:
--------------
    trunk/rkward/ChangeLog
    trunk/rkward/rkward/misc/rkcommonfunctions.cpp
    trunk/rkward/rkward/misc/rkcommonfunctions.h
    trunk/rkward/rkward/plugin/rkabstractoptionselector.cpp
    trunk/rkward/rkward/plugin/rkcomponent.cpp
    trunk/rkward/rkward/plugin/rkcomponent.h
    trunk/rkward/rkward/plugin/rkcomponentmap.cpp
    trunk/rkward/rkward/plugin/rkcomponentmap.h
    trunk/rkward/rkward/plugin/rkcomponentproperties.cpp
    trunk/rkward/rkward/plugin/rkcomponentproperties.h
    trunk/rkward/rkward/plugin/rkformula.cpp
    trunk/rkward/rkward/plugin/rkpluginspinbox.cpp
    trunk/rkward/rkward/plugin/rkstandardcomponent.cpp
    trunk/rkward/rkward/plugin/rkstandardcomponentgui.cpp
    trunk/rkward/rkward/plugin/rktext.cpp
    trunk/rkward/rkward/plugin/rkvarselector.cpp
    trunk/rkward/rkward/plugin/rkvarslot.cpp
    trunk/rkward/rkward/rbackend/rpackages/rkward/DESCRIPTION
    trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal.R
    trunk/rkward/rkward/rbackend/rthread.cpp
    trunk/rkward/rkward/windows/rkhtmlwindow.cpp
    trunk/rkward/rkward/windows/rkhtmlwindow.h

Modified: trunk/rkward/ChangeLog
===================================================================
--- trunk/rkward/ChangeLog	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/ChangeLog	2009-05-12 15:22:24 UTC (rev 2467)
@@ -1,3 +1,4 @@
+- Add "Run again" link for plugin generated output		TODO: add error handling, revisit plugins without header, what about wizard/dialog?
 - Fixed: All objects in .Globalenv would be revisited if a single object was added / removed		TODO: backport? (r2466)
 - Fixed: Screen device in rkward was not seen as interactive by R	TODO: backport (r2462)
 

Modified: trunk/rkward/rkward/misc/rkcommonfunctions.cpp
===================================================================
--- trunk/rkward/rkward/misc/rkcommonfunctions.cpp	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/misc/rkcommonfunctions.cpp	2009-05-12 15:22:24 UTC (rev 2467)
@@ -2,7 +2,7 @@
                           rkcommonfunctions  -  description
                              -------------------
     begin                : Mon Oct 17 2005
-    copyright            : (C) 2005, 2006, 2007 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2006, 2007, 2009 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -136,4 +136,36 @@
 		return (KGlobal::dirs ()->findResourceDir ("data", "rkward/all.pluginmap") + "rkward/");
 	}
 
+
+	QString escape (const QString &in) {
+		QString out;
+
+		for (int i = 0; i < in.size (); ++i) {
+			QChar c = in[i];
+			if (c == '\\') out.append ("\\\\");
+			else if (c == '\n') out.append ("\\n");
+			else if (c == '"') out.append ("\\\"");
+			else out.append (c);
+		}
+
+		return out;
+	}
+
+	QString unescape (const QString &in) {
+		QString out;
+
+		for (int i = 0; i < in.size (); ++i) {
+			QChar c = in[i];
+			if (c == '\\') {
+				++i;
+				if (i >= in.size ()) break;
+				c = in[i];
+				if (c == 'n') c = '\n';
+				else if (c == '"') c = '"';
+			}
+			out.append (c);
+		}
+
+		return out;
+	}
 }	// namespace

Modified: trunk/rkward/rkward/misc/rkcommonfunctions.h
===================================================================
--- trunk/rkward/rkward/misc/rkcommonfunctions.h	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/misc/rkcommonfunctions.h	2009-05-12 15:22:24 UTC (rev 2467)
@@ -2,7 +2,7 @@
                           rkcommonfunctions  -  description
                              -------------------
     begin                : Mon Oct 17 2005
-    copyright            : (C) 2005, 2006, 2007 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2006, 2007, 2009 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -42,6 +42,11 @@
 	QString getCurrentSymbol (const QString &context_line, int cursor_pos, bool strict=true);
 /** like get current symbol, but merely returns the start and end position of the current symbol */
 	void getCurrentSymbolOffset (const QString &context_line, int cursor_pos, bool strict, int *start, int *end);
+
+/** escape special chars in a QString */
+	QString escape (const QString &in);
+/** reverse of escape () */
+	QString unescape (const QString &in);
 };
 
 #endif

Modified: trunk/rkward/rkward/plugin/rkabstractoptionselector.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkabstractoptionselector.cpp	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/plugin/rkabstractoptionselector.cpp	2009-05-12 15:22:24 UTC (rev 2467)
@@ -2,7 +2,7 @@
                           rkabstractoptionselector  -  description
                              -------------------
     begin                : Tue Mar 20 2007
-    copyright            : (C) 2007 by Thomas Friedrichsmeier
+    copyright            : (C) 2007, 2009 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -30,6 +30,7 @@
 	connect (string, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (propertyChanged (RKComponentPropertyBase *)));
 	addChild ("number", number = new RKComponentPropertyInt (this, true, -1));
 	connect (number, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (propertyChanged (RKComponentPropertyBase *)));
+	number->setInternal (true);
 }
 
 RKAbstractOptionSelector::~RKAbstractOptionSelector(){

Modified: trunk/rkward/rkward/plugin/rkcomponent.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponent.cpp	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/plugin/rkcomponent.cpp	2009-05-12 15:22:24 UTC (rev 2467)
@@ -2,7 +2,7 @@
                           rkcomponent  -  description
                              -------------------
     begin                : Tue Dec 13 2005
-    copyright            : (C) 2005, 2006 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2006, 2009 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -17,6 +17,8 @@
 
 #include "rkcomponent.h"
 
+#include "../misc/rkcommonfunctions.h"
+
 #include "../debug.h"
 
 //############### RKComponentBase #####################
@@ -43,14 +45,17 @@
 	child_map.insertMulti (id, child);		// no overwriting even on duplicate ("#noid#") ids
 }
 
-void RKComponentBase::fetchPropertyValuesRecursive (QMap<QString, QString> *list, bool include_top_level, const QString &prefix) {
+void RKComponentBase::fetchPropertyValuesRecursive (QMap<QString, QString> *list, bool include_top_level, const QString &prefix) const {
 	RK_TRACE (PLUGIN);
 
 	for (QHash<QString, RKComponentBase*>::const_iterator it = child_map.constBegin (); it != child_map.constEnd (); ++it) {
 		if (it.key () != "#noid#") {
 			if (it.value ()->isProperty ()) {
 				if (include_top_level) {
-					list->insert (prefix + it.key (), it.value ()->value ());
+					RKComponentPropertyBase *p = static_cast<RKComponentPropertyBase*> (it.value ());
+					if (!p->isInternal ()) { 
+						list->insert (prefix + it.key (), it.value ()->value ());
+					}
 				}
 			} else {
 				it.value ()->fetchPropertyValuesRecursive (list, true, prefix + it.key () + '.');
@@ -67,11 +72,46 @@
 		QString mod;
 		RKComponentBase *prop = lookupComponent (it.key (), &mod);
 		if (mod.isEmpty () && prop->isProperty ()) {		// found a property
-			static_cast<RKComponentPropertyBase*>(prop)->setValue (it.value ());
+			RKComponentPropertyBase* p = static_cast<RKComponentPropertyBase*>(prop);
+			RK_ASSERT (!p->isInternal ());
+			p->setValue (it.value ());
 		}
 	}
 }
 
+QString RKComponentBase::serializeState () const {
+	RK_TRACE (PLUGIN);
+
+	QMap<QString, QString> props;
+	fetchPropertyValuesRecursive (&props, true);
+
+	QString out;
+	for (QMap<QString, QString>::const_iterator it = props.constBegin (); it != props.constEnd (); ++it) {
+		if (!out.isEmpty ()) out.append ("\n");
+		out.append (RKCommonFunctions::escape (it.key () + "=" + it.value ()));
+	}
+
+	return out;
+}
+
+bool RKComponentBase::unserializeState (const QString &state) {
+	RK_TRACE (PLUGIN);
+
+	QMap<QString, QString> props;
+
+	QStringList lines = state.split ('\n');
+	for (int i = 0; i < lines.count (); ++i) {
+		QString line = lines[i];
+		int sep = line.indexOf ('=');
+		if (sep < 0) return false;		// TODO: message
+		props.insert (RKCommonFunctions::unescape (line.left (sep)), RKCommonFunctions::unescape (line.mid (sep+1)));
+	}
+
+	setPropertyValues (&props);
+
+	return true;
+}
+
 QString RKComponentBase::fetchStringValue (const QString &identifier) {
 	RK_TRACE (PLUGIN);
 
@@ -112,12 +152,15 @@
 
 	addChild ("enabled", enabledness_property = new RKComponentPropertyBool (this, false));
 	enabledness_property->setBoolValue (true);
+	enabledness_property->setInternal (true);
 	connect (enabledness_property, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (propertyValueChanged (RKComponentPropertyBase *)));
 	addChild ("visible", visibility_property = new RKComponentPropertyBool (this, false));
 	visibility_property->setBoolValue (true);
+	visibility_property->setInternal (true);
 	connect (visibility_property, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (propertyValueChanged (RKComponentPropertyBase *)));
 	addChild ("required", requiredness_property = new RKComponentPropertyBool (this, false));
 	requiredness_property->setBoolValue (true);
+	requiredness_property->setInternal (true);
 	connect (requiredness_property, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (propertyValueChanged (RKComponentPropertyBase *)));
 }
 
@@ -229,7 +272,7 @@
 	// unfortunately, several items might hvae the same key, and there seems to be no way to selectively remove the current item only.
 	// however, this function should only ever be called in cases of emergency and to prevent crashes. So we make extra sure to remove the child,
 	// even if we remove a little more than necessary along the way.
-			while (parentComponent ()->child_map.remove (key));
+			while (parentComponent ()->child_map.remove (key)) {;}
 			return;
 		}
 	}

Modified: trunk/rkward/rkward/plugin/rkcomponent.h
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponent.h	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/plugin/rkcomponent.h	2009-05-12 15:22:24 UTC (rev 2467)
@@ -2,7 +2,7 @@
                           rkcomponent  -  description
                              -------------------
     begin                : Tue Dec 13 2005
-    copyright            : (C) 2005, 2006, 2007 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2006, 2007, 2009 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -83,14 +83,20 @@
 	void setRequired (bool require) { required = require; };
 /** simple convenience function to add a child to the map of children */
 	void addChild (const QString &id, RKComponentBase *child);
+
+/** serialize the state of this component / property and all its children. Note: Only the non-internal property-values are serialzed, not the components / properties themselves. @see fetchPropertyValuesRecursive() */
+	QString serializeState () const;
+/** set values from a string created with serializeState(). @see serializeState (), @see setPropertyValues ().
+ at returns false if unserializing failed. */
+	bool unserializeState (const QString &state);
 protected:
 	QHash<QString, RKComponentBase*> child_map;
 	bool required;
-/** recursively fetch the current values of all properties present as direct or indirect children of this component. Used to transfer values e.g. when switching interfaces (or to store settings per plugin in the future). Values are placed in the dictionary provided (be sure to create one first!).
+/** recursively fetch the current values of all properties present as direct or indirect children of this component. Used to transfer values e.g. when switching interfaces (or to store settings per plugin in the future). Values are placed in the dictionary provided (be sure to create one first!). Internal properties are ignored (@see RKComponentPropertyBase::isInternal ());
 @param list the list to store the object values in
 @param include_top_level include direct properties of the component in the list (or only properties of children)
 @param prefix used during recursion to provide full ids for the added objects */
-	void fetchPropertyValuesRecursive (QMap<QString, QString> *list, bool include_top_level=false, const QString &prefix=QString::null);
+	void fetchPropertyValuesRecursive (QMap<QString, QString> *list, bool include_top_level=false, const QString &prefix=QString::null) const;
 /** counterpart to fetchPropertyValuesRecursive (). Tries to apply all values from the list to properties of the given names. If some keys can not be found, or do not resolve to properties, the are ignored.
 @param list a list of id->value such as generated by fetchPropertyValuesRecursive () */
 	void setPropertyValues (QMap<QString, QString> *list);

Modified: trunk/rkward/rkward/plugin/rkcomponentmap.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentmap.cpp	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/plugin/rkcomponentmap.cpp	2009-05-12 15:22:24 UTC (rev 2467)
@@ -2,7 +2,7 @@
                           rkcomponentmap.cpp  -  description
                              -------------------
     begin                : Thu May 12 2005
-    copyright            : (C) 2005, 2006, 2007 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2006, 2007, 2009 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -24,6 +24,7 @@
 #include <kactioncollection.h>
 
 #include "rkcomponentcontext.h"
+#include "rkstandardcomponent.h"
 #include "../misc/xmlhelper.h"
 #include "../debug.h"
 #include "../rkglobals.h"
@@ -229,6 +230,21 @@
 	return (QString ());
 }
 
+//static
+bool RKComponentMap::invokeComponent (const QString &component_id, const QString &serialized_settings, bool dosubmit) {
+	RK_TRACE (PLUGIN);
+
+	RKComponentHandle *handle = getComponentHandle (component_id);
+	if (!handle) return false;
+
+	RKStandardComponent *component = handle->invoke (0, 0);
+	RK_ASSERT (component);
+
+	bool ok = component->unserializeState (serialized_settings);
+#warning TODO: support automatic submit
+	return ok;
+}
+
 int RKComponentMap::addPluginMap (const QString& plugin_map_file) {
 	RK_TRACE (PLUGIN);
 

Modified: trunk/rkward/rkward/plugin/rkcomponentmap.h
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentmap.h	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/plugin/rkcomponentmap.h	2009-05-12 15:22:24 UTC (rev 2467)
@@ -2,7 +2,7 @@
                           rkcomponentmap.h  -  description
                              -------------------
     begin                : Thu May 12 2005
-    copyright            : (C) 2005, 2006, 2007 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2006, 2007, 2009 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -164,6 +164,8 @@
 	static void initialize ();
 /** returns the context identified by id */
 	static RKContextMap *getContext (const QString &id);
+/** invokes the specified component as toplevel */
+	static bool invokeComponent (const QString &component_id, const QString &serialized_settings, bool dosubmit=false);
 private:
 /** typedef for easy reference to iterator */
 	typedef QMap<QString, RKComponentHandle*> ComponentMap;

Modified: trunk/rkward/rkward/plugin/rkcomponentproperties.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentproperties.cpp	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/plugin/rkcomponentproperties.cpp	2009-05-12 15:22:24 UTC (rev 2467)
@@ -2,7 +2,7 @@
                           rkcomponentproperties  -  description
                              -------------------
     begin                : Fri Nov 25 2005
-    copyright            : (C) 2005, 2006, 2007, 2008 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2006, 2007, 2008, 2009 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -101,6 +101,7 @@
 	RK_TRACE (PLUGIN);
 	RKComponentPropertyBase::required = required;
 	is_valid = true;
+	is_internal = false;
 }
 
 RKComponentPropertyBase::~RKComponentPropertyBase () {
@@ -172,6 +173,7 @@
 	if (next == "not") {
 		RKComponentPropertyBool *negated = new RKComponentPropertyBool (this, false, false, value_true, value_false);
 		negated->setInverted (true);
+		negated->setInternal (true);
 		negated->connectToGovernor (this);
 		*remainder = QString::null;		// reset
 		addChild ("not", negated);		// so subsequent lookups will not recreate the negated property

Modified: trunk/rkward/rkward/plugin/rkcomponentproperties.h
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentproperties.h	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/plugin/rkcomponentproperties.h	2009-05-12 15:22:24 UTC (rev 2467)
@@ -2,7 +2,7 @@
                           rkcomponentproperties  -  description
                              -------------------
     begin                : Fri Nov 25 2005
-    copyright            : (C) 2005, 2006, 2007 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2006, 2007, 2009 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -53,6 +53,10 @@
 Generally with few exceptions, you can only connect to properties that are either of the same class as this property, or of an extended class. Maybe in the future we will add some sophisticated converters allowing to connect vastly different types of properties in a meaningful way.
 If you specify a modifier, only the sub-value indicated by the modifier will be retrieved from the governing property on governorValueChanged. In this case reconcile_requirements is ignored. */
 	virtual void connectToGovernor (RKComponentPropertyBase *governor, const QString &modifier=QString::null, bool reconcile_requirements=true);
+
+/** Some properties will be marked as internal, such as visibility properties, which are not meant to be set directly by the user. These will be ignored in RKComponent::fetchPropertyValuesRecursive() */
+	void setInternal (bool internal) { is_internal = internal; };
+	bool isInternal () const { return is_internal; };
 signals:
 /** property has changed its value. Any connected RKComponentPropertys/RKComponents should update their state
 @param property A pointer to the changed property for easy reference */
@@ -66,6 +70,8 @@
 	QString _value;
 /** if we're only interested in a specific sub-information of the governor-property, we need to remember the corresponding modifier */
 	QString governor_modifier;
+private:
+	bool is_internal;
 };
 
 

Modified: trunk/rkward/rkward/plugin/rkformula.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkformula.cpp	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/plugin/rkformula.cpp	2009-05-12 15:22:24 UTC (rev 2467)
@@ -2,7 +2,7 @@
                           rkformula  -  description
                              -------------------
     begin                : Thu Aug 12 2004
-    copyright            : (C) 2004, 2006, 2007 by Thomas Friedrichsmeier
+    copyright            : (C) 2004, 2006, 2007, 2009 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -48,10 +48,13 @@
 	addChild ("dependent", dependent);
 	model = new RKComponentPropertyBase (this, true);
 	addChild ("model", model);
+	model->setInternal (true);
 	table = new RKComponentPropertyBase (this, true);
 	addChild ("table", table);
+	table->setInternal (true);
 	labels = new RKComponentPropertyBase (this, true);
 	addChild ("labels", labels);
+	labels->setInternal (true);
 
 	// get xmlHelper
 	XMLHelper *xml = XMLHelper::getStaticHelper ();

Modified: trunk/rkward/rkward/plugin/rkpluginspinbox.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkpluginspinbox.cpp	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/plugin/rkpluginspinbox.cpp	2009-05-12 15:22:24 UTC (rev 2467)
@@ -2,7 +2,7 @@
                           rkpluginspinbox  -  description
                              -------------------
     begin                : Wed Aug 11 2004
-    copyright            : (C) 2004, 2006 by Thomas Friedrichsmeier
+    copyright            : (C) 2004, 2006, 2009 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -36,6 +36,7 @@
 
 	// create and add properties
 	addChild ("int", intvalue = new RKComponentPropertyInt (this, intmode, 0));
+	intvalue->setInternal (true);
 	addChild ("real", realvalue = new RKComponentPropertyDouble (this, !intmode, 0));
 
 	// layout and label

Modified: trunk/rkward/rkward/plugin/rkstandardcomponent.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponent.cpp	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/plugin/rkstandardcomponent.cpp	2009-05-12 15:22:24 UTC (rev 2467)
@@ -2,7 +2,7 @@
                           rkstandardcomponent  -  description
                              -------------------
     begin                : Sun Feb 19 2006
-    copyright            : (C) 2006, 2007 by Thomas Friedrichsmeier
+    copyright            : (C) 2006, 2007, 2009 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -66,7 +66,8 @@
 	wizard = 0;
 	created = false;
 	addChild ("code", code = new RKComponentPropertyCode (this, true));		// do not change this name!
-	
+	code->setInternal (true);
+
 	// open the main description file for parsing
 	XMLHelper* xml = XMLHelper::getStaticHelper ();
 	QDomElement doc_element = xml->openXMLFile (filename, DL_ERROR);
@@ -627,6 +628,7 @@
 		QString id = xml->getStringAttribute (*it, "id", "#noid#", DL_WARNING);
 		RKComponentPropertyBase *prop = new RKComponentPropertyBase (component (), xml->getBoolAttribute (*it, "required", false, DL_INFO));
 		component ()->addChild (id, prop);
+		prop->setInternal (true);
 		component ()->connect (prop, SIGNAL (valueChanged (RKComponentPropertyBase *)), component (), SLOT (outsideValueChanged (RKComponentPropertyBase *)));
 
 		QString dummy = xml->getStringAttribute (*it, "default", QString::null, DL_INFO);
@@ -640,6 +642,7 @@
 	children = xml->getChildElements (element, "convert", DL_INFO);
 	for (it = children.constBegin (); it != children.constEnd (); ++it) {
 		RKComponentPropertyConvert *convert = new RKComponentPropertyConvert (component ());
+		convert->setInternal (true);
 		QString id = xml->getStringAttribute (*it, "id", "#noid#", DL_WARNING);
 		int mode = xml->getMultiChoiceAttribute (*it, "mode", convert->convertModeOptionString (), 0, DL_WARNING);
 		QString sources = xml->getStringAttribute (*it, "sources", QString::null, DL_WARNING);

Modified: trunk/rkward/rkward/plugin/rkstandardcomponentgui.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponentgui.cpp	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/plugin/rkstandardcomponentgui.cpp	2009-05-12 15:22:24 UTC (rev 2467)
@@ -154,7 +154,14 @@
 	command.append (code_property->calculate ());
 	command.append (code_property->printout ());
 	command.append ("})\n");
+
 	RKGlobals::rInterface ()->issueCommand (new RCommand (command, RCommand::Plugin | RCommand::DirectToOutput | RCommand::ObjectListUpdate));
+
+	// re-run link
+	command = "\n.rk.rerun.plugin.link(plugin=\"" + RKComponentMap::getComponentId (component->getHandle ()) + "\", settings=\"" + component->serializeState () + "\", label=\"" + i18n ("Run again") + "\")\n";
+	// horizontal line
+	command.append (".rk.make.hr()\n");
+	RKGlobals::rInterface ()->issueCommand (new RCommand (command, RCommand::Plugin | RCommand::DirectToOutput | RCommand::ObjectListUpdate));
 }
 
 void RKStandardComponentGUI::cancel () {

Modified: trunk/rkward/rkward/plugin/rktext.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rktext.cpp	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/plugin/rktext.cpp	2009-05-12 15:22:24 UTC (rev 2467)
@@ -70,6 +70,7 @@
 
 	// create and add property
 	addChild ("text", text = new RKComponentPropertyBase (this, true));
+	text->setInternal (true);
 	connect (text, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (textChanged (RKComponentPropertyBase *)));
 
 	// initialize

Modified: trunk/rkward/rkward/plugin/rkvarselector.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkvarselector.cpp	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/plugin/rkvarselector.cpp	2009-05-12 15:22:24 UTC (rev 2467)
@@ -2,7 +2,7 @@
                           rkvarselector.cpp  -  description
                              -------------------
     begin                : Thu Nov 7 2002
-    copyright            : (C) 2002,2006 by Thomas Friedrichsmeier
+    copyright            : (C) 2002, 2006, 2009 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -32,6 +32,7 @@
 
 // TODO: read filter settings
 	addChild ("selected", selected = new RKComponentPropertyRObjects (this, false));
+	selected->setInternal (true);
 
 	QVBoxLayout *vbox = new QVBoxLayout (this);
 	vbox->setContentsMargins (0, 0, 0, 0);

Modified: trunk/rkward/rkward/plugin/rkvarslot.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkvarslot.cpp	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/plugin/rkvarslot.cpp	2009-05-12 15:22:24 UTC (rev 2467)
@@ -2,7 +2,7 @@
                           rkvarslot.cpp  -  description
                              -------------------
     begin                : Thu Nov 7 2002
-    copyright            : (C) 2002, 2007, 2008 by Thomas Friedrichsmeier
+    copyright            : (C) 2002, 2007, 2008, 2009 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -60,8 +60,10 @@
 
 	// initialize properties
 	addChild ("source", source = new RKComponentPropertyRObjects (this, false));
+	source->setInternal (true);
 	addChild ("available", available = new RKComponentPropertyRObjects (this, true));
 	addChild ("selected", selected = new RKComponentPropertyRObjects (this, false));
+	selected->setInternal (true);
 
 	// find out about options
 	if (multi = xml->getBoolAttribute (element, "multi", false, DL_INFO)) {

Modified: trunk/rkward/rkward/rbackend/rpackages/rkward/DESCRIPTION
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/DESCRIPTION	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/DESCRIPTION	2009-05-12 15:22:24 UTC (rev 2467)
@@ -1,6 +1,6 @@
 Package: rkward
 Title: Provides some helper functions for the RKWard frontend
-Version: 0.5.0
+Version: 0.5.1
 Author: Thomas Friedrichsmeier and the RKWard Team
 Description: Most of the functions in here are really only needed for the internal communication between RKWard and R. There are also a few functions, which allow access to RKWard or RKWard specifics. Most is not implemented, yet.
 Maintainer: RKWard-devel mailing list <rkward-devel at lists.sourceforge.net>

Modified: trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal.R
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal.R	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal.R	2009-05-12 15:22:24 UTC (rev 2467)
@@ -484,3 +484,11 @@
 ".rk.cat.output" <- function (x) {
 	cat (x, file = rk.get.output.html.file(), append = TRUE)
 }
+
+".rk.rerun.plugin.link" <- function (plugin, settings, label) {
+	.rk.cat.output (paste ("<a href=\"rkward://runplugin/", plugin, "/", URLencode (settings), "\">", label, "</a>", sep=""))
+}
+
+".rk.make.hr" <- function () {
+	.rk.cat.output ("<hr>\n");
+}

Modified: trunk/rkward/rkward/rbackend/rthread.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rthread.cpp	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/rbackend/rthread.cpp	2009-05-12 15:22:24 UTC (rev 2467)
@@ -162,10 +162,6 @@
 		
 		RK_DO (qDebug ("running command: %s", ccommand.toLatin1().data ()), RBACKEND, DL_DEBUG);
 	
-		if (command->type () & RCommand::DirectToOutput) {
-			runCommandInternal (".rk.cat.output (\"<hr>\\n\")", &error, false);
-			RK_ASSERT (!error);
-		}
 		command->status |= RCommand::Running;	// it is important that this happens before the Mutex is unlocked!
 		RCommandStackModel::getModel ()->itemChange (command);
 

Modified: trunk/rkward/rkward/windows/rkhtmlwindow.cpp
===================================================================
--- trunk/rkward/rkward/windows/rkhtmlwindow.cpp	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/windows/rkhtmlwindow.cpp	2009-05-12 15:22:24 UTC (rev 2467)
@@ -2,7 +2,7 @@
                           rkhtmlwindow  -  description
                              -------------------
     begin                : Wed Oct 12 2005
-    copyright            : (C) 2005, 2006, 2007 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2006, 2007, 2009 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -168,9 +168,30 @@
 	url_change_is_from_history = false;
 }
 
+bool RKHTMLWindow::handleRKWardURL (const KUrl &url) {
+	RK_TRACE (APP);
+
+	if (url.protocol () == "rkward") {
+		if (url.host () == "runplugin") {
+			QString path = url.path ();
+			if (path.startsWith ('/')) path = path.mid (1);
+			int sep = path.indexOf ('/');
+			RKComponentMap::invokeComponent (path.left (sep), path.mid (sep+1));
+#warning TODO: error handling!
+			return true;
+		} else {
+			RKWorkplace::mainWorkplace ()->openHelpWindow (url);
+			return true;
+		}
+	}
+	return false;
+}
+
 bool RKHTMLWindow::openURL (const KUrl &url) {
 	RK_TRACE (APP);
 
+	if (handleRKWardURL (url)) return true;
+
 	// asyncrhonously dealing with non-local files would be quite a task. We chose the simple answer instead...
 	if (!url.isLocalFile ()) {
 		if (KMessageBox::questionYesNo (this, i18n ("The url you are trying to open ('%1') is not a local file. Do you want to open the url in the default application?", url.prettyUrl ()), i18n ("Open in default application?")) != KMessageBox::Yes) {
@@ -301,6 +322,8 @@
 bool RKOutputWindow::openURL (const KUrl &url) {
 	RK_TRACE (APP);
 
+	if (handleRKWardURL (url)) return true;
+
 	output_url = url;
 	QFileInfo out_file (url.path ());
 	bool ok = out_file.exists();
@@ -428,11 +451,11 @@
 	khtmlpart = 0;	// in case we try to redelete in a parent class
 }
 
-bool RKHelpWindow::openURL (const KUrl &url) {
+bool RKHelpWindow::handleRKWardURL (const KUrl &url) {
 	RK_TRACE (APP);
 
-	bool ok = true;
 	if (url.protocol () == "rkward") {
+		bool ok;
 		if (url.host () == "component") {
 			ok = renderRKHelp (url);
 		} else if (url.host () == "rhelp") {
@@ -441,6 +464,8 @@
 			return true;
 		} else if (url.host () == "page") {
 			ok = renderRKHelp (url);
+		} else {
+			return RKHTMLWindow::handleRKWardURL (url);
 		}
 
 		if (!ok) {
@@ -450,9 +475,9 @@
 		}
 	
 		changeURL (url);
-		return ok;
+		return true;
 	} else {
-		return (RKHTMLWindow::openURL (url));
+		return false;
 	}
 }
 

Modified: trunk/rkward/rkward/windows/rkhtmlwindow.h
===================================================================
--- trunk/rkward/rkward/windows/rkhtmlwindow.h	2009-05-12 08:25:39 UTC (rev 2466)
+++ trunk/rkward/rkward/windows/rkhtmlwindow.h	2009-05-12 15:22:24 UTC (rev 2467)
@@ -2,7 +2,7 @@
                           rkhtmlwindow  -  description
                              -------------------
     begin                : Wed Oct 12 2005
-    copyright            : (C) 2005, 2006, 2007 by Thomas Friedrichsmeier
+    copyright            : (C) 2005, 2006, 2007, 2009 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -49,6 +49,8 @@
 public:
 /** open given URL. Returns false, if the URL is not an existing local file. Loading a non-local URL may succeed, even if this returns false! */
 	virtual bool openURL (const KUrl &url);
+/** takes care of special handling, if the url is an rkward://-url. Does nothing and returns false, otherwise. */
+	virtual bool handleRKWardURL (const KUrl &url);
 /** Reload current page.*/
 	virtual void refresh ();
 /** Add common actions to the given action collection (currently only "copy")
@@ -165,8 +167,8 @@
 	RKHelpWindow (QWidget *parent = 0);
 /** destructor */
 	~RKHelpWindow ();
-/** reimplemented to handle our special protocols component://, rhelp://, and rkhelp:// in addition to the regular protocols */
-	bool openURL (const KUrl &url);
+
+	bool handleRKWardURL (const KUrl &url);
 private:
 	bool renderRKHelp (const KUrl &url);
 	QString renderHelpFragment (QDomElement &fragment);


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