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

tfry at users.sourceforge.net tfry at users.sourceforge.net
Fri Nov 23 18:50:57 UTC 2012


Revision: 4446
          http://rkward.svn.sourceforge.net/rkward/?rev=4446&view=rev
Author:   tfry
Date:     2012-11-23 18:50:57 +0000 (Fri, 23 Nov 2012)
Log Message:
-----------
Getting closer to proper de-serialization of driven sets. Still buggy, though

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

Modified: trunk/rkward/rkward/plugin/rkcomponent.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponent.cpp	2012-11-23 17:02:02 UTC (rev 4445)
+++ trunk/rkward/rkward/plugin/rkcomponent.cpp	2012-11-23 18:50:57 UTC (rev 4446)
@@ -46,7 +46,7 @@
 	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) const {
+void RKComponentBase::fetchPropertyValuesRecursive (PropertyValueMap *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) {
@@ -65,11 +65,11 @@
 	}
 }
 
-void RKComponentBase::setPropertyValues (QMap<QString, QString> *list, bool warn_internal) {
+void RKComponentBase::setPropertyValues (PropertyValueMap *list, bool warn_internal) {
 	RK_TRACE (PLUGIN);
 	// TODO: visibility enabledness and requiredness should be excluded, as those are not directly user settable. Perhaps even mark up all properties as user settable or not.
 
-	for (QMap<QString, QString>::const_iterator it = list->constBegin (); it != list->constEnd (); ++it) {
+	for (PropertyValueMap::const_iterator it = list->constBegin (); it != list->constEnd (); ++it) {
 		QString mod;
 		RKComponentBase *prop = lookupComponent (it.key (), &mod);
 		if (mod.isEmpty () && prop->isProperty ()) {		// found a property
@@ -83,11 +83,11 @@
 QString RKComponentBase::serializeState () const {
 	RK_TRACE (PLUGIN);
 
-	QMap<QString, QString> props;
+	PropertyValueMap props;
 	fetchPropertyValuesRecursive (&props, true);
 
 	QString out;
-	for (QMap<QString, QString>::const_iterator it = props.constBegin (); it != props.constEnd (); ++it) {
+	for (PropertyValueMap::const_iterator it = props.constBegin (); it != props.constEnd (); ++it) {
 		if (!out.isEmpty ()) out.append ("\n");
 		out.append (RKCommonFunctions::escape (it.key () + "=" + it.value ()));
 	}
@@ -98,7 +98,7 @@
 RKComponent::UnserializeError RKComponentBase::unserializeState (const QStringList &state) {
 	RK_TRACE (PLUGIN);
 
-	QMap<QString, QString> props;
+	PropertyValueMap props;
 
 	for (int i = 0; i < state.count (); ++i) {
 		QString line = state[i];
@@ -111,7 +111,7 @@
 
 	// verify
 	UnserializeError error = NoError;
-	for (QMap<QString, QString>::const_iterator it = props.constBegin (); it != props.constEnd (); ++it) {
+	for (PropertyValueMap::const_iterator it = props.constBegin (); it != props.constEnd (); ++it) {
 		if (fetchStringValue (it.key ()) != it.value ()) {
 			// COMPAT: In RKWard 0.5.1, the formatting of real numbers was different. Hence we compare the numeric values, instead
 			QString dummy;

Modified: trunk/rkward/rkward/plugin/rkcomponent.h
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponent.h	2012-11-23 17:02:02 UTC (rev 4445)
+++ trunk/rkward/rkward/plugin/rkcomponent.h	2012-11-23 18:50:57 UTC (rev 4446)
@@ -116,6 +116,7 @@
 /** Some properties/components 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; };
+	typedef QMap<QString, QString> PropertyValueMap;
 protected:
 friend class RKOptionSet;
 	QHash<QString, RKComponentBase*> child_map;
@@ -124,11 +125,11 @@
 @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 */
-	virtual void fetchPropertyValuesRecursive (QMap<QString, QString> *list, bool include_top_level=false, const QString &prefix=QString ()) const;
+	virtual void fetchPropertyValuesRecursive (PropertyValueMap *list, bool include_top_level=false, const QString &prefix=QString ()) const;
 	friend class RKComponentBuilder;
 /** 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, bool warn_internal=false);
+	void setPropertyValues (PropertyValueMap *list, bool warn_internal=false);
 private:
 	bool is_internal;
 };

Modified: trunk/rkward/rkward/plugin/rkoptionset.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkoptionset.cpp	2012-11-23 17:02:02 UTC (rev 4445)
+++ trunk/rkward/rkward/plugin/rkoptionset.cpp	2012-11-23 18:50:57 UTC (rev 4446)
@@ -240,19 +240,19 @@
 	return ret;
 }
 
-QString serializeMap (const QMap<QString, QString> &map) {
+QString serializeMap (const RKComponent::PropertyValueMap &map) {
 	QString ret;
 
-	QMap<QString, QString>::const_iterator it;
+	RKComponent::PropertyValueMap::const_iterator it;
 	for (it = map.constBegin (); it != map.constEnd (); ++it) {
 		if (!ret.isEmpty ()) ret.append ('\t');
-		ret.append (RKCommonFunctions::escape (it.key ()) + '=' + RKCommonFunctions::escape (it.value ()));
+		ret.append (RKCommonFunctions::escape (it.key () + '=' + it.value ()));
 	}
 	return ret;
 }
 
-QMap<QString, QString> unserializeMap (const QString &serial) {
-	QMap<QString, QString> ret;
+RKComponent::PropertyValueMap unserializeMap (const QString &serial) {
+	RKComponent::PropertyValueMap ret;
 	QStringList l = serial.split ('\t', QString::KeepEmptyParts);
 	for (int i = 0; i < l.size (); ++i) {
 		QString &line = l[i];
@@ -262,7 +262,7 @@
 	return ret;
 }
 
-void RKOptionSet::fetchPropertyValuesRecursive (QMap<QString, QString> *list, bool include_top_level, const QString &prefix) const {
+void RKOptionSet::fetchPropertyValuesRecursive (PropertyValueMap *list, bool include_top_level, const QString &prefix) const {
 	RK_TRACE (PLUGIN);
 	RK_ASSERT (include_top_level);
 
@@ -274,7 +274,13 @@
 
 	for (int r = 0; r < rows.size (); ++r) {
 		if (!serialization.isEmpty ()) serialization.append ("\n");
-		serialization.append ("_row=" + serializeMap (rows[r].full_row_map));
+		if (r == active_row) {
+			PropertyValueMap map;	// current row may have changes which have not yet been stored to the state map
+			contents_container->fetchPropertyValuesRecursive (&map);
+			serialization.append ("_row=" + serializeMap (map));
+		} else {
+			serialization.append ("_row=" + serializeMap (rows[r].full_row_map));
+		}
 	}
 
 	list->insert (prefix + "serialized", serialization);
@@ -296,8 +302,9 @@
  * - trigger handleKeycolumnUpdate(), delayed
  * 
  */
+	bool update_key_col = false;
 	if (keycolumn && (keycolumn->value () != KEYCOLUMN_UNINITIALIZED_VALUE)) {
-		QTimer::singleShot (0, this, SLOT (handleKeycolumnUpdate ()));
+		update_key_col = true;
 	} else {
 		RK_ASSERT (rows.isEmpty ());
 	}
@@ -353,6 +360,7 @@
 	n_unfinished_rows = n_invalid_rows = row;
 	row_count->setIntValue (row);
 	updating = false;
+	if (update_key_col) handleKeycolumnUpdate ();
 
 	active_row = -1;
 	current_row->setIntValue (qMin (0, row - 1));
@@ -379,7 +387,7 @@
 
 	if (!n_unfinished_rows) {	// done
 		if (switcher->currentWidget () != updating_notice) return;
-		current_row->setIntValue (active_row = return_to_row);
+		current_row->setIntValue (return_to_row);
 		switcher->setCurrentWidget (user_area);
 		return;
 	}
@@ -568,14 +576,16 @@
 	int activate_row = activate_row;
 	QStringList new_keys = keycolumn->values ();
 	QMap<int, int> position_changes;
+	QSet<int> found_rows;
 
-	int pos;
-	for (pos = 0; pos < new_keys.size (); ++pos) {
+	for (int pos = 0; pos < new_keys.size (); ++pos) {
 		QString key = new_keys[pos];
 		if (old_keys.value (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
+			int old_pos = old_keys.indexOf (key);	// NOTE: -1 for new keys
+			if (old_pos == active_row) activate_row = pos;
 			position_changes.insert (pos, old_pos);
-		}
+			if (old_pos >= 0) found_rows.insert (old_pos);
+		} else found_rows.insert (pos);
 	}
 
 	if (position_changes.isEmpty () && (old_keys.size () == new_keys.size ())) {
@@ -586,6 +596,13 @@
 	storeRowSerialization (active_row);
 	updating = true;
 
+	// as a first step, take a backup of any rows that have been removed.
+	for (int i = old_keys.size () - 1; i >= 0; --i) {
+		if (!found_rows.contains (i)) {
+			former_row_states.insert (old_keys[i], rows[i].full_row_map);
+		}
+	}
+
 	// update all columns
 	QMap<RKComponentPropertyStringList *, ColumnInfo>::iterator it = column_map.begin ();
 	for (; it != column_map.end (); ++it) {
@@ -625,13 +642,12 @@
 		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_row_info.insert (pos, RowInfo (default_row_state));
+			if (old_pos < 0) {	// a new key (but it might have been known, formerly)
+				new_row_info.insert (pos, RowInfo (former_row_states.value (new_keys[pos], default_row_state)));
 			} else {	// old key changed position
 				new_row_info[pos] = rows[old_pos];
 			} // NOTE: not visible: old key is gone without replacement
 		}
-#warning --------------- TODO: keep and match against row info for keys that were formerly present -----------------------
 	}
 	rows = new_row_info.mid (0, new_keys.size ());
 	n_invalid_rows = n_unfinished_rows = 0;
@@ -645,9 +661,9 @@
 	int nrows = new_keys.size ();
 	row_count->setIntValue (nrows);
 	activate_row = qMin (nrows - 1, activate_row);
-	current_row->setIntValue (active_row = activate_row);
+	setContentsForRow (active_row = activate_row);
+	current_row->setIntValue (active_row);
 	if (model) model->triggerReset ();
-	setContentsForRow (active_row);
 	updating = false;
 	changed ();
 }

Modified: trunk/rkward/rkward/plugin/rkoptionset.h
===================================================================
--- trunk/rkward/rkward/plugin/rkoptionset.h	2012-11-23 17:02:02 UTC (rev 4445)
+++ trunk/rkward/rkward/plugin/rkoptionset.h	2012-11-23 18:50:57 UTC (rev 4446)
@@ -99,15 +99,17 @@
 	QMap<RKComponentPropertyStringList *, ColumnInfo> column_map;
 	QList<RKComponentPropertyStringList*> visible_columns;
 	struct RowInfo {
-		RowInfo (QMap<QString, QString> initial_values) : valid (false), finished (false), full_row_map (initial_values) {};
+		RowInfo (PropertyValueMap initial_values) : valid (false), finished (false), full_row_map (initial_values) {};
 		bool valid;		/**< has finished processing and is known to be valid */
 		bool finished;	/**< has finished processing */
-		QMap<QString, QString> full_row_map;	/**< complete status representation of this row, (see RKComponent::fetchPropertyValuesRecursive()) */
+		PropertyValueMap full_row_map;	/**< complete status representation of this row, (see RKComponent::fetchPropertyValuesRecursive()) */
 	};
 	QList<RowInfo> rows;
-	QMap<QString, QString> default_row_state;
+	PropertyValueMap default_row_state;
 	int n_unfinished_rows, n_invalid_rows;
 	int active_row;
+	/** backup of row state info for rows corresponding to keys which have been removed (in a driven set). These might get re-inserted, later. */
+	QHash<QString, PropertyValueMap> former_row_states;
 
 	RKComponent *contents_container;
 	QWidget *display_buttons;

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