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

tfry at users.sf.net tfry at users.sf.net
Wed May 8 18:06:12 UTC 2013


Revision: 4745
          http://sourceforge.net/p/rkward/code/4745
Author:   tfry
Date:     2013-05-08 18:06:09 +0000 (Wed, 08 May 2013)
Log Message:
-----------
Add <valueselector> and <select>. Compiling, but not yet active, and / or tested.

Modified Paths:
--------------
    trunk/rkward/ChangeLog
    trunk/rkward/rkward/plugin/CMakeLists.txt
    trunk/rkward/rkward/plugin/rkcomponent.h
    trunk/rkward/rkward/plugin/rkstandardcomponent.cpp

Added Paths:
-----------
    trunk/rkward/rkward/plugin/rkvalueselector.cpp
    trunk/rkward/rkward/plugin/rkvalueselector.h

Modified: trunk/rkward/ChangeLog
===================================================================
--- trunk/rkward/ChangeLog	2013-05-07 20:12:26 UTC (rev 4744)
+++ trunk/rkward/ChangeLog	2013-05-08 18:06:09 UTC (rev 4745)
@@ -1,7 +1,10 @@
 - Fixed: potential crash when a previously installed pluginmap is not longer readable
+- Allow to connect <varslot>/<valueslot> source to any property, not just <varselectors>
+	TODO: document
+- New plugin elements <valueselector> and <select>
+	TODO: finish them, document them, allow to fill <valueselector> from R expression
 - New plugin element <valueslot> for selecting arbitrary string values (otherwise almost identical to <varslot>)
 	TODO: document, complement with valueselector (sort of pointless without)
-	      valueslot / varslot: If source-spec contains a dot, don't append "selected" -> more flexible input
 - <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/CMakeLists.txt
===================================================================
--- trunk/rkward/rkward/plugin/CMakeLists.txt	2013-05-07 20:12:26 UTC (rev 4744)
+++ trunk/rkward/rkward/plugin/CMakeLists.txt	2013-05-08 18:06:09 UTC (rev 4745)
@@ -28,6 +28,7 @@
    rkpluginframe.cpp
    rkoptionset.cpp
    rkmatrixinput.cpp
+   rkvalueselector.cpp
    )
 
 QT4_AUTOMOC(${plugin_STAT_SRCS})

Modified: trunk/rkward/rkward/plugin/rkcomponent.h
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponent.h	2013-05-07 20:12:26 UTC (rev 4744)
+++ trunk/rkward/rkward/plugin/rkcomponent.h	2013-05-08 18:06:09 UTC (rev 4745)
@@ -63,6 +63,7 @@
 		ComponentFrame = 2016,
 		ComponentOptionSet = 2017,
 		ComponentMatrixInput = 2018,
+		ComponentValueSelector = 2019,
 		ComponentStandard = 2100,
 		ComponentContextHandler = 2900,
 		ComponentUser = 3000	/**< for user expansion */

Modified: trunk/rkward/rkward/plugin/rkstandardcomponent.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponent.cpp	2013-05-07 20:12:26 UTC (rev 4744)
+++ trunk/rkward/rkward/plugin/rkstandardcomponent.cpp	2013-05-08 18:06:09 UTC (rev 4745)
@@ -614,7 +614,9 @@
 			widget = new RKVarSelector (e, component (), parent_widget);
 		} 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);
+			QString source = xml->getStringAttribute (e, "source_property", QString (), DL_INFO);
+			if (source.isEmpty ()) source = xml->getStringAttribute (e, "source", "#noid#", DL_WARNING) + ".selected";
+			addConnection (id, "source", source, QString (), false, e);
 		} else if (e.tagName () == QLatin1String ("formula")) {
 			widget = new RKFormula (e, component (), parent_widget);
 			addConnection (id, "dependent", xml->getStringAttribute (e, "dependent", "#noid#", DL_INFO), "available", false, e);

Added: trunk/rkward/rkward/plugin/rkvalueselector.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkvalueselector.cpp	                        (rev 0)
+++ trunk/rkward/rkward/plugin/rkvalueselector.cpp	2013-05-08 18:06:09 UTC (rev 4745)
@@ -0,0 +1,172 @@
+/***************************************************************************
+                          rkvalueselector  -  description
+                             -------------------
+    begin                : Weg May 8 2013
+    copyright            : (C) 2013 by Thomas Friedrichsmeier
+    email                : tfry at users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#include "rkvalueselector.h"
+
+#include <QVBoxLayout>
+#include <QLabel>
+#include <QTreeView>
+#include <QStringListModel>
+
+#include "../misc/xmlhelper.h"
+#include "../rkglobals.h"
+
+#include "../debug.h"
+
+RKValueSelector::RKValueSelector (const QDomElement &element, RKComponent *parent_component, QWidget *parent_widget) : RKComponent (parent_component, parent_widget) {
+	RK_TRACE (PLUGIN);
+
+	updating = false;
+	XMLHelper *xml = XMLHelper::getStaticHelper ();
+	standalone = element.tagName () == "select";
+
+	addChild ("selected", selected = new RKComponentPropertyStringList (this, false));
+	connect (selected, SIGNAL (valueChanged(RKComponentPropertyBase*)), this, SLOT (selectionPropertyChanged()));
+	selected->setInternal (!standalone);
+	addChild ("available", available = new RKComponentPropertyStringList (this, false));
+	connect (available, SIGNAL (valueChanged(RKComponentPropertyBase*)), this, SLOT (availablePropertyChanged()));
+	available->setInternal (true);
+	addChild ("labels", labels = new RKComponentPropertyStringList (this, false));
+	connect (labels, SIGNAL (valueChanged(RKComponentPropertyBase*)), this, SLOT (labelsPropertyChanged()));
+	labels->setInternal (true);
+
+	QVBoxLayout *vbox = new QVBoxLayout (this);
+	vbox->setContentsMargins (0, 0, 0, 0);
+
+	QString lab = xml->getStringAttribute (element, "label", QString (), DL_INFO);
+	if (!lab.isNull ()) {
+		QLabel *label = new QLabel (lab, this);
+		vbox->addWidget (label);
+	}
+
+	list_view = new QTreeView (this);
+	list_view->setSelectionMode (QAbstractItemView::ExtendedSelection);
+	connect (list_view, SIGNAL (listSelectionChanged ()), this, SLOT (listSelectionChanged ()));
+	model = new QStringListModel (this);
+	list_view->setModel (model);
+
+	vbox->addWidget (list_view);
+
+	XMLChildList options = xml->getChildElements (element, "option", DL_INFO);
+	if (!options.isEmpty ()) {
+		QStringList values_list;
+		QStringList labels_list;
+		QStringList selected_list;
+
+		for (int i = 0; i < options.size (); ++i) {
+			QString v = xml->getStringAttribute (element, "value", QString (), DL_WARNING);
+			QString l = xml->getStringAttribute (element, "label", v, DL_INFO);
+			if (xml->getBoolAttribute (element, "selected", false, DL_INFO)) selected_list.append (v);
+			labels_list.append (l);
+			values_list.append (v);
+		}
+		available->setValueList (values_list);
+		labels->setValueList (labels_list);
+		selected->setValueList (selected_list);
+	}
+}
+
+RKValueSelector::~RKValueSelector () {
+	RK_TRACE (PLUGIN);
+}
+
+void RKValueSelector::labelsPropertyChanged () {
+	RK_TRACE (PLUGIN);
+
+	model->setStringList (labels->values ());
+	selectionPropertyChanged ();   // To update selected items
+}
+
+void RKValueSelector::availablePropertyChanged () {
+	RK_TRACE (PLUGIN);
+
+	const QStringList &vals = available->values ();
+	for (int i = vals.size () - 1; i >= 1; --i) {
+		if (vals.lastIndexOf (vals[i], i - 1) >= 0) {
+			RK_DEBUG (PLUGIN, DL_WARNING, "Duplicate value index in value selector: %s", qPrintable (vals[i]));
+		}
+	}
+	if (!purged_selected_indexes.isEmpty ()) {
+		// This is to handle the case that the "selected" property was updated externally, *before* the "available" property got the corresponding change.
+		// In this case, try to re-apply any selected strings that could not be matched, before
+		purged_selected_indexes.append (selected->values ());
+		selected->setValueList (purged_selected_indexes);   // side effect updating selected items
+		purged_selected_indexes.clear ();
+	} else {
+		selectionPropertyChanged ();   // To update selected items
+	}
+}
+
+void RKValueSelector::listSelectionChanged () {
+	if (updating) return;
+	RK_TRACE (PLUGIN);
+
+	QStringList sel_list;
+	QModelIndexList selected_rows = list_view->selectionModel ()->selectedRows ();
+	for (int i = 0; i < selected_rows.size (); ++i) {
+		sel_list.append (available->valueAt (selected_rows[i].row ()));
+	}
+	updating = true;
+	selected->setValueList (sel_list);
+	updating = false;
+
+	changed ();
+}
+
+void RKValueSelector::selectionPropertyChanged () {
+	if (updating) return;
+	RK_TRACE (PLUGIN);
+
+	updating = true;
+	QSet<int> selected_rows;
+	for (int i = 0; i < selected->listLength (); ++i) {
+		const QString &val = selected->valueAt (i);
+		int index = available->values ().indexOf (val);
+		if (index < 0) {
+			if (!purged_selected_indexes.contains (val)) purged_selected_indexes.append (val);
+			selected->removeAt (i);
+			--i;
+			continue;
+		}
+		selected_rows.insert (index);
+	}
+
+	list_view->selectionModel ()->clearSelection ();
+	foreach (const int row, selected_rows) {
+		list_view->selectionModel ()->select (model->index (row), QItemSelectionModel::Select | QItemSelectionModel::Rows);
+	}
+
+	updating = false;
+}
+
+QVariant RKValueSelector::value (const QString& modifier) {
+	RK_TRACE (PLUGIN);
+
+	if (modifier == "labelled") {
+		QStringList selected_labels;
+		for (int i = 0; i < selected->listLength (); ++i) {
+			int index = available->values ().indexOf (selected->valueAt (i));
+			if (index < 0) {
+				RK_ASSERT (index >= 0);
+			} else selected_labels.append (labels->valueAt (index));
+		}
+		return QVariant (selected_labels);
+	}
+	return selected->value (modifier);
+}
+
+#include "rkvarselector.moc"

Added: trunk/rkward/rkward/plugin/rkvalueselector.h
===================================================================
--- trunk/rkward/rkward/plugin/rkvalueselector.h	                        (rev 0)
+++ trunk/rkward/rkward/plugin/rkvalueselector.h	2013-05-08 18:06:09 UTC (rev 4745)
@@ -0,0 +1,55 @@
+/***************************************************************************
+                          rkvalueselector  -  description
+                             -------------------
+    begin                : Weg May 8 2013
+    copyright            : (C) 2013 by Thomas Friedrichsmeier
+    email                : tfry at users.sourceforge.net
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef RKVALUESELECTOR_H
+#define RKVALUESELECTOR_H
+
+#include "rkcomponent.h"
+#include "rkcomponentproperties.h"
+
+class QTreeView;
+class QStringListModel;
+class QDomElement;
+
+/** Like RKVarSelector, but provides selection among an arbitrary list of strings.
+
+ at author Thomas Friedrichsmeier
+*/
+class RKValueSelector : public RKComponent {
+	Q_OBJECT
+public: 
+	RKValueSelector (const QDomElement &element, RKComponent *parent_component, QWidget *parent_widget);
+	~RKValueSelector ();
+	int type () { return ComponentValueSelector; };
+	QVariant value (const QString &modifier=QString ());
+private slots:
+	void selectionPropertyChanged ();
+	void listSelectionChanged ();
+	void labelsPropertyChanged ();
+	void availablePropertyChanged ();
+private:
+	QTreeView *list_view;
+	QStringListModel *model;
+	bool updating;
+	bool standalone;
+	RKComponentPropertyStringList *selected;
+	RKComponentPropertyStringList *labels;
+	RKComponentPropertyStringList *available;
+	QStringList purged_selected_indexes;
+};
+
+#endif





More information about the rkward-tracker mailing list