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

tfry at users.sf.net tfry at users.sf.net
Fri May 3 16:15:15 UTC 2013


Revision: 4740
          http://sourceforge.net/p/rkward/code/4740
Author:   tfry
Date:     2013-05-03 16:15:11 +0000 (Fri, 03 May 2013)
Log Message:
-----------
Extend <varslot> to act as a <valueslot>, alternatively.
This requires a bunch of ugly casts, but it's still much easier than implementing a separate control.

Note that the <valueslot> is fairly pointless without the <valueselector>, which I plan to implement after this.

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/rkvarslot.cpp
    trunk/rkward/rkward/plugin/rkvarslot.h

Modified: trunk/rkward/ChangeLog
===================================================================
--- trunk/rkward/ChangeLog	2013-05-03 14:49:21 UTC (rev 4739)
+++ trunk/rkward/ChangeLog	2013-05-03 16:15:11 UTC (rev 4740)
@@ -1,3 +1,5 @@
+- New plugin element <valueslot> for selecting arbitrary string values (otherwise almost identical to <varslot>)
+	TODO: document, complement with valueselector (sort of pointless without)
 - <varslots> can be set to accept the same object several times. Used in scatterplot plugin.
 - New R function rk.embed.device() for manually embedding graphics devices in RKWard
 - Fixed: R backend would exit immediately, without meaningful error message, if there is an error in .Rprofile (or Rprofile.site)

Modified: trunk/rkward/rkward/plugin/rkcomponentproperties.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentproperties.cpp	2013-05-03 14:49:21 UTC (rev 4739)
+++ trunk/rkward/rkward/plugin/rkcomponentproperties.cpp	2013-05-03 16:15:11 UTC (rev 4740)
@@ -239,13 +239,13 @@
 
 bool RKComponentPropertyStringList::setValue (const QString &string) {
 	if (string.isNull ()) {
-		setValues (QStringList ());
+		setValueList (QStringList ());
 	} else {
 		QStringList list = string.split (sep);
 		for (int i = 0; i < list.size (); ++i) {
 			list[i] = RKCommonFunctions::unescape (list[i]);
 		}
-		setValues (list);
+		setValueList (list);
 	}
 	return true;
 }
@@ -263,7 +263,7 @@
 void RKComponentPropertyStringList::governorValueChanged (RKComponentPropertyBase *property) {
 	QVariant value = property->value (governor_modifier);
 	if (value.type () == QVariant::StringList) {
-		setValues (value.toStringList ());
+		setValueList (value.toStringList ());
 	} else {
 		setValue (value.toString ());
 	}
@@ -290,6 +290,13 @@
 	doChange ();
 }
 
+void RKComponentPropertyStringList::doChange () {
+	RK_TRACE (PLUGIN);
+	is_valid = checkListLength ();
+	_value.clear ();
+	emit (valueChanged (this));
+}
+
 ///////////////////////////////////////////// Bool //////////////////////////////////////////
 
 RKComponentPropertyBool::RKComponentPropertyBool (QObject *parent, bool required, bool default_state, const QString &value_true, const QString &value_false) : RKComponentPropertyBase (parent, required) {
@@ -970,7 +977,7 @@
 	return ret;
 }
 
-bool RKComponentPropertyRObjects::setValue (const QStringList& values) {
+bool RKComponentPropertyRObjects::setValueList (const QStringList& values) {
 	RK_TRACE (PLUGIN);
 
 	setObjectValue (0);
@@ -978,7 +985,7 @@
 	bool ok = true;
 	for (int i = 0; i < values.size (); ++i) {
 		RObject *obj = RObjectList::getObjectList ()->findObject (values[i]);
-		ok = ok && addObjectValueSilent (obj);
+		ok &= addObjectValueSilent (obj);
 	}
 
 	updateValidity ();
@@ -989,7 +996,7 @@
 bool RKComponentPropertyRObjects::setValue (const QString &value) {
 	RK_TRACE (PLUGIN);
 
-	return setValue (value.split (sep, QString::SkipEmptyParts));
+	return setValueList (value.split (sep, QString::SkipEmptyParts));
 }
 
 bool RKComponentPropertyRObjects::isStringValid (const QString &value) {
@@ -1089,7 +1096,7 @@
 	} else {
 		QVariant value = property->value ();
 		if (value.type () == QVariant::StringList) {
-			setValue (value.toStringList ());
+			setValueList (value.toStringList ());
 		} else {
 			setValue (value.toString ());
 		}
@@ -1344,7 +1351,7 @@
 	RK_DEBUG (PLUGIN, DL_ERROR, "Cannot connect a <switch> property to a governor");
 }
 
-bool RKComponentPropertySwitch::setValue (const QString& value) {
+bool RKComponentPropertySwitch::setValue (const QString&) {
 	RK_DEBUG (PLUGIN, DL_ERROR, "Cannot set value for a <switch> property");
 	return false;
 }

Modified: trunk/rkward/rkward/plugin/rkcomponentproperties.h
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentproperties.h	2013-05-03 14:49:21 UTC (rev 4739)
+++ trunk/rkward/rkward/plugin/rkcomponentproperties.h	2013-05-03 16:15:11 UTC (rev 4740)
@@ -88,10 +88,11 @@
 /** If set to true, duplicate values are dropped, silently */
 	void setStripDuplicates (bool strip) { strip_duplicates = strip; };
 	virtual void removeAt (int index) = 0;
+	virtual int listLength () const = 0;
+	virtual bool setValueList (const QStringList &new_values) = 0;
 protected:
 	bool getStripDuplicates () const { return strip_duplicates; };
 	bool checkListLength ();
-	virtual int listLength () const = 0;
 	void reconcileLengthRequirements (RKComponentPropertyAbstractList *governor);
 	static QString sep;
 private:
@@ -122,13 +123,13 @@
 /** get all current strings as a QStringList */
 	const QStringList& values () const { return storage; };
 /** set current strings as a QStringList */
-	void setValues (const QStringList &new_values) { storage = new_values; checkStripDuplicates (); doChange (); };
+	bool setValueList (const QStringList &new_values) { storage = new_values; checkStripDuplicates (); doChange (); return true; };
 /** reimplemented from RKComponentPropertyBase to use special handling for list properties */
 	void governorValueChanged (RKComponentPropertyBase *property);
 	int listLength () const { return (storage.size ()); };
 	void removeAt (int index);
 private:
-	void doChange () { _value.clear (); emit (valueChanged (this)); };
+	void doChange ();
 	void checkStripDuplicates ();
 	QStringList storage;
 };
@@ -321,7 +322,7 @@
 	bool setValue (const QString &value);
 /** overload of setValue() which accepts a list of names of RObjects
 @returns false if no such object(s) could be found or the object(s) are invalid */
-	bool setValue (const QStringList &values);
+	bool setValueList (const QStringList &values);
 /** reimplemented from RKComponentPropertyBase to test whether conversion to RObject is possible with current constraints */
 	bool isStringValid (const QString &value);
 /** RTTI */
@@ -331,6 +332,7 @@
 /** reimplemented from RKComponentPropertyBase to use special handling for object properties */
 	void governorValueChanged (RKComponentPropertyBase *property);
 	void removeAt (int index);
+	RObject* objectAt (int index) const { return object_list.value (index); };
 	int listLength () const { return (object_list.size ()); };
 protected:
 /** remove an object value. reimplemented from RObjectListener::objectRemoved (). This is so we get notified if the object currently selected is removed TODO: is this effectively a duplication of setFromList? */

Modified: trunk/rkward/rkward/plugin/rkoptionset.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkoptionset.cpp	2013-05-03 14:49:21 UTC (rev 4739)
+++ trunk/rkward/rkward/plugin/rkoptionset.cpp	2013-05-03 16:15:11 UTC (rev 4740)
@@ -353,7 +353,7 @@
 		for (int i = 0; i < row; ++i) {
 			def.append (getDefaultValue (col, i));
 		}
-		it.key ()->setValues (def);
+		it.key ()->setValueList (def);
 	}
 
 	rows = new_rows;
@@ -424,7 +424,7 @@
 		ColumnInfo &column = it.value ();
 		QStringList values = col->values ();
 		values.insert (row, getDefaultValue (column, row));
-		col->setValues (values);
+		col->setValueList (values);
 	}
 	updating = false;
 
@@ -463,7 +463,7 @@
 		RKComponentPropertyStringList* col = it.key ();
 		QStringList values = col->values ();
 		values.removeAt (row);
-		col->setValues (values);
+		col->setValueList (values);
 	}
 	updating = false;
 
@@ -631,7 +631,7 @@
 
 		// strip excess length (if any), and apply
 		new_values = new_values.mid (0, new_keys.size ());
-		col->setValues (new_values);
+		col->setValueList (new_values);
 	}
 
 	// update status info

Modified: trunk/rkward/rkward/plugin/rkstandardcomponent.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponent.cpp	2013-05-03 14:49:21 UTC (rev 4739)
+++ trunk/rkward/rkward/plugin/rkstandardcomponent.cpp	2013-05-03 16:15:11 UTC (rev 4740)
@@ -612,7 +612,7 @@
 			}
 		} else if (e.tagName () == QLatin1String ("varselector")) {
 			widget = new RKVarSelector (e, component (), parent_widget);
-		} else if (e.tagName () == QLatin1String ("varslot")) {
+		} else if ((e.tagName () == QLatin1String ("varslot")) || (e.tagName () == QLatin1String ("valueslot"))) {
 			widget = new RKVarSlot (e, component (), parent_widget);
 			addConnection (id, "source", xml->getStringAttribute (e, "source", "#noid#", DL_INFO), "selected", false, e);
 		} else if (e.tagName () == QLatin1String ("formula")) {

Modified: trunk/rkward/rkward/plugin/rkvarslot.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkvarslot.cpp	2013-05-03 14:49:21 UTC (rev 4739)
+++ trunk/rkward/rkward/plugin/rkvarslot.cpp	2013-05-03 16:15:11 UTC (rev 4740)
@@ -2,7 +2,7 @@
                           rkvarslot.cpp  -  description
                              -------------------
     begin                : Thu Nov 7 2002
-    copyright            : (C) 2002, 2007, 2008, 2009, 2011, 2012 by Thomas Friedrichsmeier
+    copyright            : (C) 2002-2013 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -59,11 +59,19 @@
 	list->setRootIsDecorated (false);
 	g_layout->addWidget (list, 1, 2);
 
+	mode = (element.tagName () == "valueslot") ? Valueslot : Varslot;
+
 	// initialize properties
-	addChild ("source", source = new RKComponentPropertyRObjects (this, false));
+	if (mode == Valueslot) {
+		addChild ("source", source = new RKComponentPropertyStringList (this, false));
+		addChild ("available", available = new RKComponentPropertyStringList (this, true));
+		addChild ("selected", selected = new RKComponentPropertyStringList (this, false));
+	} else {
+		addChild ("source", source = new RKComponentPropertyRObjects (this, false));
+		addChild ("available", available = new RKComponentPropertyRObjects (this, true));
+		addChild ("selected", selected = 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
@@ -87,12 +95,14 @@
 		g_layout->setRowStretch (3, 1);		// so the label does not get separated from the view
 	}
 
-	// initialize filters
-	available->setClassFilter (xml->getStringAttribute (element, "classes", QString (), DL_INFO).split (" ", QString::SkipEmptyParts));
-	setRequired (xml->getBoolAttribute (element, "required", false, DL_INFO));
-	available->setTypeFilter (xml->getStringAttribute (element, "types", QString::null, DL_INFO).split (" ", QString::SkipEmptyParts));
-	available->setDimensionFilter (xml->getIntAttribute (element, "num_dimensions", 0, DL_INFO), xml->getIntAttribute (element, "min_length", 0, DL_INFO), xml->getIntAttribute (element, "max_length", INT_MAX, DL_INFO));
-	available->setStripDuplicates (!xml->getBoolAttribute (element, "allow_duplicates", false, DL_INFO));
+	if (mode == Varslot) {
+		// initialize filters
+		static_cast<RKComponentPropertyRObjects*> (available)->setClassFilter (xml->getStringAttribute (element, "classes", QString (), DL_INFO).split (" ", QString::SkipEmptyParts));
+		setRequired (xml->getBoolAttribute (element, "required", false, DL_INFO));
+		static_cast<RKComponentPropertyRObjects*> (available)->setTypeFilter (xml->getStringAttribute (element, "types", QString::null, DL_INFO).split (" ", QString::SkipEmptyParts));
+		static_cast<RKComponentPropertyRObjects*> (available)->setDimensionFilter (xml->getIntAttribute (element, "num_dimensions", 0, DL_INFO), xml->getIntAttribute (element, "min_length", 0, DL_INFO), xml->getIntAttribute (element, "max_length", INT_MAX, DL_INFO));
+	}
+	available->setStripDuplicates (!xml->getBoolAttribute (element, "allow_duplicates", mode == Valueslot, DL_INFO));
 
 	connect (available, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (availablePropertyChanged (RKComponentPropertyBase *)));
 	availablePropertyChanged (available);		// initialize
@@ -115,13 +125,18 @@
 void RKVarSlot::listSelectionChanged () {
 	RK_TRACE (PLUGIN);
 
-	RObject::ObjectList sellist;
-	QList<QTreeWidgetItem*> selitems = list->selectedItems ();
-	for (int i = 0; i < selitems.count (); ++i) sellist.append (item_map.value (selitems[i]));
+	QModelIndexList selrows = list->selectionModel ()->selectedRows (0);
+	if (mode == Valueslot) {
+		QStringList sellist;
+		for (int i = 0; i < selrows.count (); ++i) sellist.append (static_cast<RKComponentPropertyStringList*> (available)->valueAt (selrows[i].row ()));
+		static_cast<RKComponentPropertyStringList*> (selected)->setValueList (sellist);
+	} else {
+		RObject::ObjectList sellist;
+		for (int i = 0; i < selrows.count (); ++i) sellist.append (static_cast<RKComponentPropertyRObjects*> (available)->objectAt (selrows[i].row ()));
+		static_cast<RKComponentPropertyRObjects*> (selected)->setObjectList (sellist);
+	}
 
-	selected->setObjectList (sellist);
-
-	setSelectButton (((!multi) || (selitems.isEmpty ())) && (!available->atMaxLength ()));
+	setSelectButton (((!multi) || (selrows.isEmpty ())) && (!available->atMaxLength ()));
 }
 
 void RKVarSlot::availablePropertyChanged (RKComponentPropertyBase *) {
@@ -130,23 +145,25 @@
 	if (updating) return;
 
 	list->clear ();
-	item_map.clear ();
 
 	RK_DEBUG (PLUGIN, DL_DEBUG, "contained in varslot: %s", qPrintable (fetchStringValue (available)));
 
-	RObject::ObjectList objlist = available->objectList ();
-	for (int i = 0; i < objlist.count (); ++i) {
-		RObject *object = objlist[i];
-
+	int len = available->listLength ();
+	for (int i = 0; i < len; ++i) {
 		QTreeWidgetItem *new_item = new QTreeWidgetItem (list);
 		new_item->setText (0, QString::number (i + 1));
-		new_item->setText (1, object->getShortName ());
-		QString probs = available->objectProblems (i);
-		if (!probs.isEmpty ()) {
-			new_item->setToolTip (1, i18n ("<p>This object is not allowed, here, for the following reason(s):</p>") + probs);
-			new_item->setIcon (1, RKStandardIcons::getIcon (RKStandardIcons::ActionDeleteVar));
+
+		if (mode == Valueslot) {
+			new_item->setText (1, static_cast<RKComponentPropertyStringList*> (available)->valueAt (i));
+		} else {
+			RObject *object = static_cast<RKComponentPropertyRObjects*> (available)->objectAt (i);
+			new_item->setText (1, object->getShortName ());
+			QString probs = static_cast<RKComponentPropertyRObjects*> (available)->objectProblems (i);
+			if (!probs.isEmpty ()) {
+				new_item->setToolTip (1, i18n ("<p>This object is not allowed, here, for the following reason(s):</p>") + probs);
+				new_item->setIcon (1, RKStandardIcons::getIcon (RKStandardIcons::ActionDeleteVar));
+			}
 		}
-		item_map.insert (new_item, object);
 	}
 	if (multi) list->resizeColumnToContents (0);
 
@@ -180,15 +197,14 @@
 	updating = true;
 	// first update the properties
 	if (add_mode) {
-		if (multi) {
-			RObject::ObjectList objlist = source->objectList ();
-			RObject::ObjectList::const_iterator it = objlist.constBegin ();
-			while (it != objlist.constEnd ()) {
-				available->addObjectValue (*it);
-				++it;
+		if (!multi) available->setValueList (QStringList ());  // replace
+		int len = source->listLength ();
+		for (int i = 0; i < len; ++i) {
+			if (mode == Valueslot) {
+				static_cast<RKComponentPropertyStringList*> (available)->setValueAt (i, static_cast<RKComponentPropertyStringList*> (source)->valueAt (i));
+			} else {
+				static_cast<RKComponentPropertyRObjects*> (available)->addObjectValue (static_cast<RKComponentPropertyRObjects*> (source)->objectAt (i));
 			}
-		} else {
-			if (source->objectValue ()) available->setObjectValue (source->objectValue ());
 		}
 	} else {		// remove-mode
 		QModelIndexList removed = list->selectionModel ()->selectedRows (0);       // Note: list contains no dupes, but is unsorted.
@@ -197,10 +213,11 @@
 			removed_rows.append (removed[i].row ());
 		}
 		qSort (removed_rows);
+		if (!multi && removed_rows.isEmpty ()) removed_rows.append (0);
 		for (int i = removed_rows.size () - 1; i >= 0; --i) {
 			available->removeAt (removed_rows[i]);
 		}
-		selected->setObjectValue (0);
+		selected->setValueList (QStringList ());
 	}
 	updating = false;
 	availablePropertyChanged (available);

Modified: trunk/rkward/rkward/plugin/rkvarslot.h
===================================================================
--- trunk/rkward/rkward/plugin/rkvarslot.h	2013-05-03 14:49:21 UTC (rev 4739)
+++ trunk/rkward/rkward/plugin/rkvarslot.h	2013-05-03 16:15:11 UTC (rev 4740)
@@ -2,7 +2,7 @@
                           rkvarslot.h  -  description
                              -------------------
     begin                : Thu Nov 7 2002
-    copyright            : (C) 2002, 2006, 2007, 2012 by Thomas Friedrichsmeier
+    copyright            : (C) 2002 - 2013 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -54,6 +54,10 @@
 /** Calls updateLook (), when enabledness changes */
 	void enabledChange (bool old) { updateLook (); QWidget::enabledChange (old); };
 private:
+	enum {
+		Varslot,
+		Valueslot
+	} mode;
 /** change the select button to left/right / add/remove
 @param add if true, button shows arrow right, or signifies more values would be added. Else the other way around */
 	void setSelectButton (bool add);
@@ -62,16 +66,14 @@
 	bool updating;
 
 /** the available objects (typically a copy of the property of the varselector) */
-	RKComponentPropertyRObjects *source;
+	RKComponentPropertyAbstractList *source;
 /** the objects in the varslot */
-	RKComponentPropertyRObjects *available;
+	RKComponentPropertyAbstractList *available;
 /** of the objects in the varslot, those that are marked */
-	RKComponentPropertyRObjects *selected;
+	RKComponentPropertyAbstractList *selected;
 
 	QTreeWidget *list;
 	QPushButton *select;
-	typedef QMap<QTreeWidgetItem*, RObject*> ItemMap;
-	ItemMap item_map;
 };
 
 #endif





More information about the rkward-tracker mailing list