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

tfry at users.sourceforge.net tfry at users.sourceforge.net
Wed May 9 15:43:35 UTC 2012


Revision: 4249
          http://rkward.svn.sourceforge.net/rkward/?rev=4249&view=rev
Author:   tfry
Date:     2012-05-09 15:43:34 +0000 (Wed, 09 May 2012)
Log Message:
-----------
A few more bits for the optionset

Modified Paths:
--------------
    trunk/rkward/rkward/plugin/rkoptionset.cpp
    trunk/rkward/rkward/plugin/rkoptionset.h

Modified: trunk/rkward/rkward/plugin/rkoptionset.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkoptionset.cpp	2012-05-09 11:33:31 UTC (rev 4248)
+++ trunk/rkward/rkward/plugin/rkoptionset.cpp	2012-05-09 15:43:34 UTC (rev 4249)
@@ -2,7 +2,7 @@
                           rkoptionset  -  description
                              -------------------
     begin                : Mon Oct 31 2011
-    copyright            : (C) 2011 by Thomas Friedrichsmeier
+    copyright            : (C) 2011, 2012 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -54,8 +54,9 @@
 	container = new RKComponent (this, contents_box);
 	RKComponentBuilder *builder = new RKComponentBuilder (container, QDomElement ());
 	builder->buildElement (xml->getChildElement (element, "content", DL_ERROR), contents_box, false);
-	// take a snapshot of the default state
-	container->fetchPropertyValuesRecursive (&defaults);
+#warning TOOD: do we need this? or is the per-column default good enough?
+	// take a snapshot of the default state of the contents
+	container->fetchPropertyValuesRecursive (&content_defaults);
 
 	// create columns
 	XMLChildList options = xml->getChildElements (element, "option", DL_WARNING);
@@ -77,6 +78,8 @@
 		col_inf.column_name = id;
 		col_inf.restorable = restorable;
 		col_inf.governor = governor;
+#warning TODO: Do we have to wait for the parent component to settle before (re-)fetching defaults?
+		if (!governor.isEmpty ()) col_inf.default_value = fetchStringValue (governor);
 		if (!label.isEmpty ()) {
 			col_inf.display_index = visible_columns++;
 			col_inf.column_label = label;
@@ -112,10 +115,11 @@
 				if (ci.restorable) {
 					if (!modifier.isEmpty ()) {
 						RK_DO (qDebug ("Cannot connect restorable column '%s' in optionset to property with modifier (%s). Add an auxiliary non-restorable column, instead.", qPrintable (ci.column_name), qPrintable (ci.governor)), PLUGIN, DL_ERROR);
+						continue;
 					} else if (gov_prop->isInternal ()) {
 						RK_DO (qDebug ("Cannot connect restorable column '%s' in optionset to property (%s), which is marked 'internal'. Add an auxiliary non-restorable column, instead.", qPrintable (ci.column_name), qPrintable (ci.governor)), PLUGIN, DL_ERROR);
+						continue;
 					}
-					continue;
 				}
 				columns_to_update.insertMulti (gov_prop, it.key ());
 				connect (gov_prop, SIGNAL (valueChanged(RKComponentPropertyBase *)), this, SLOT (governingPropertyChanged(RKComponentPropertyBase *)));
@@ -157,6 +161,7 @@
 	return (display);
 }
 
+// This function is called when a property of the current row of the optionset changes
 void RKOptionSet::governingPropertyChanged (RKComponentPropertyBase *property) {
 	RK_TRACE (PLUGIN);
 
@@ -180,21 +185,74 @@
 			display->setItem (row, inf.display_index, new QTableWidgetItem (value));
 		}
 	}
+	if (keycolumn) old_keys = keycolumn->values ();
 
 	updating_from_contents = false;
 }
 
+// This function is called, when a column of the set is changed, typically from external logic
 void RKOptionSet::columnPropertyChanged (RKComponentPropertyBase *property) {
 	RK_TRACE (PLUGIN);
 
 	if (updating_from_contents) return;
 
+	RKComponentPropertyStringList *target = static_cast<RKComponentPropertyStringList *> (property);
 	const ColumnInfo &inf = column_map[target];
 	if (inf.display_index >= 0) {
 		QString value = property->value (inf.display_modifier);
 		display->setItem (row, inf.display_index, new QTableWidgetItem (value));
 	}
 
+	if (target == keycolumn) {
+		QStringList new_keys = property->values ();;
+		QMap<int, int> position_changes;
+
+		for (int new_pos = 0; new_pos < new_keys.size (); ++new_pos) {
+			QString key = new_keys[new_pos];
+			if (old_keys.value (new_pos) != key) {	// NOTE: old_keys could be shorter than new_keys!
+				int old_pos = old_keys.indexOf (key);	// NOTE: -1 for key no longer present
+				position_changes.insert (new_pos, old_pos);
+			}
+		}
+
+		if (position_changes.isEmpty () && (old_keys.size () == new_keys.size ())) return;	// no change
+
+		QMap<RKComponentPropertyStringList *, ColumnInfo>::const_iterator it = column_map.constBegin ();
+		for (; it != column_map.constEnd (); ++it) {
+			RKComponentPropertyStringList* col = it.key ();
+			ColumnInfo &column = it.value ();
+			if (columns_which_have_been_updated_externally.contains (col)) {
+				continue;
+			}
+
+			// Ok, we'll have to adjust this column. We start by copying the old values, and padding to the
+			// new length (if that is greater than the old).
+			QStringList old_values = col->values ();
+			QStringList new_values = old_values;
+			for (int i = (new_keys.size () - new_values.size ()); i > 0; --i) new_values.append (QString ());
+
+			// adjust all positions that have changed
+			for (int pos = 0; pos < new_keys.size (); ++pos) {
+				QMap<int, int>::const_iterator pit = position_changes.find (pos);
+				if (pit != position_changes.constEnd ()) {	// some change
+					int old_pos = pit.value ();
+					if (old_pos < 0) {	// a new key
+						new_values[pos] = column.default_value;
+#warning TODO: should also allow scripted defaults
+					} else {	// old key changed position
+						new_values[pos] = old_values (old_pos);
+					}
+				}
+			}
+
+			// strip excess length (if any), and apply
+			new_values = new_values.left (new_keys.size ());
+			col->setValues (new_values);
+		}
+	} else {
+		columns_which_have_been_updated_externally.insert (target);
+#error TODO: single shot timer to clear this list? 
+	}
 #error TODO
 }
 

Modified: trunk/rkward/rkward/plugin/rkoptionset.h
===================================================================
--- trunk/rkward/rkward/plugin/rkoptionset.h	2012-05-09 11:33:31 UTC (rev 4248)
+++ trunk/rkward/rkward/plugin/rkoptionset.h	2012-05-09 15:43:34 UTC (rev 4249)
@@ -44,16 +44,18 @@
 private:
 	void initDisplay ();
 
-	QMap<QString, QString> defaults;
+	QMap<QString, QString> content_defaults;
 /** for option sets which are "driven" (i.e. the user cannot simply add / remove rows, directly), this holds the key column, controlling addition / removal of rows in the set.
   * if this length (or order) is changed in this row, it will also be changed in the other rows. */
 	RKComponentPropertyStringList *keycolumn;
+	QStringList old_keys;
 	QMultiMap<RKComponentPropertyBase *, RKComponentPropertyStringList *> columns_to_update;
 	struct ColumnInfo {
 		QString column_name;
 		QString column_label;
 		QString governor;
 		QString governor_modifier;
+		QString default_value;
 		int display_index;
 		bool restorable;
 	};
@@ -70,7 +72,7 @@
 
 	bool updating_from_contents;
 	bool changing_row;
-	QStringList columns_which_have_been_updated_externally;
+	QSet<RKComponentPropertyStringList *> columns_which_have_been_updated_externally;
 };
 
 #endif

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