[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