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

tfry at users.sourceforge.net tfry at users.sourceforge.net
Fri Nov 9 11:34:34 UTC 2012


Revision: 4425
          http://rkward.svn.sourceforge.net/rkward/?rev=4425&view=rev
Author:   tfry
Date:     2012-11-09 11:34:34 +0000 (Fri, 09 Nov 2012)
Log Message:
-----------
Continuing to struggle with 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-11-08 21:31:33 UTC (rev 4424)
+++ trunk/rkward/rkward/plugin/rkoptionset.cpp	2012-11-09 11:34:34 UTC (rev 4425)
@@ -46,6 +46,7 @@
 	max_rows = xml->getIntAttribute (element, "max", INT_MAX, DL_INFO);
 
 	// create some meta properties
+	active_row = -1;
 	current_row = new RKComponentPropertyInt (this, false, -1);
 	current_row->setInternal (true);
 	addChild ("current_row", current_row);		// NOTE: read-write
@@ -77,7 +78,7 @@
 		QString governor = xml->getStringAttribute (e, "connect", QString (), DL_INFO);
 		bool restorable = xml->getBoolAttribute (e, "restorable", true, DL_INFO);
 
-		while (child_map.contains (id)) {
+		while (child_map.contains (id) || (id.startsWith ("_row"))) {
 			RK_DO (qDebug ("optionset already contains a property named %s. Renaming to _%s", qPrintable (id), qPrintable (id)), PLUGIN, DL_ERROR);
 			id = "_" + id;
 		}
@@ -155,12 +156,12 @@
 		}
 	}
 
+	n_invalid_rows = n_unfinished_rows = 0;
 	update_timer.start ();
 }
 
 RKOptionSet::~RKOptionSet () {
 	RK_TRACE (PLUGIN);
-qDebug ("Optionset deleted");
 }
 
 RKComponent *RKOptionSet::createDisplay (bool show_index, QWidget *parent) {
@@ -192,8 +193,8 @@
 void RKOptionSet::addRow () {
 	RK_TRACE (PLUGIN);
 
-	int row = current_row->intValue () + 1;	// append feels more natural than insert, here
-	int nrows = row_count->intValue ();
+	int row = active_row + 1;	// append feels more natural than insert, here
+	int nrows = rowCount ();
 	if (row <= 0) row = nrows;
 
 	// adjust values
@@ -207,20 +208,22 @@
 		column.old_values = values;
 	}
 	// adjust status info
-	for (int i = nrows - 1; i > row; --i) {
-		if (unfinished_rows.remove (i)) unfinished_rows.insert (i+1);
-		if (invalid_rows.remove (i)) invalid_rows.insert (i+1);
-	}
-	unfinished_rows.insert (row);
+	RowInfo ri;
+	ri.valid = false;
+	ri.finished = false;
+	rows.insert (row, ri);
+	++n_unfinished_rows;
+	++n_invalid_rows;
 
-	current_row->setIntValue (row);
+	row_count->setIntValue (nrows + 1);
+	current_row->setIntValue (active_row = row);
 }
 
 void RKOptionSet::removeRow () {
 	RK_TRACE (PLUGIN);
 
-	int row = current_row->intValue ();
-	int nrows = row_count->intValue ();
+	int row = active_row;
+	int nrows = rowCount ();
 	if (row < 0) {
 		RK_ASSERT (false);
 		return;
@@ -236,17 +239,16 @@
 		col->setValues (values);
 		column.old_values = values;
 	}
+
 	// adjust status info
-	invalid_rows.remove (row);
-	unfinished_rows.remove (row);
-	for (int i = row + 1; i < nrows; ++i) {
-		if (unfinished_rows.remove (i)) unfinished_rows.insert (i-1);
-		if (invalid_rows.remove (i)) invalid_rows.insert (i-1);
-	}
+	if (!rows[row].valid) --n_invalid_rows;
+	if (!rows[row].finished) --n_unfinished_rows;
+	rows.removeAt (row);
 
 	--row;
 	if ((row < 0) && (nrows > 1)) row = 0;
-	current_row->setIntValue (row);
+	row_count->setIntValue (nrows - 1);
+	current_row->setIntValue (active_row = row);
 }
 
 QString getDefaultValue (const RKOptionSet::ColumnInfo& ci, int row) {
@@ -256,6 +258,28 @@
 	return ci.default_value;
 }
 
+void RKOptionSet::setRowState (int row, bool finished, bool valid) {
+	RK_ASSERT (row < rows.size ());
+	if (rows[row].finished != finished) {
+		rows[row].finished = finished;
+		finished ? --n_unfinished_rows : ++n_unfinished_rows;
+	}
+	if (rows[row].valid != valid) {
+		rows[row].valid = valid;
+		valid ? --n_invalid_rows : ++n_invalid_rows;
+	}
+}
+
+void RKOptionSet::changed () {
+	int row = active_row;
+
+	rows[row].full_row_serialization.clear ();
+	ComponentStatus s = RKComponent::recursiveStatus ();
+	setRowState (row, s != Processing, s == Satisfied);
+
+	RKComponent::changed ();
+}
+
 // This function is called when a property of the current row of the optionset changes
 void RKOptionSet::governingPropertyChanged (RKComponentPropertyBase *property) {
 	RK_TRACE (PLUGIN);
@@ -263,12 +287,11 @@
 	if (updating_from_storage) return;
 	updating_from_contents = true;
 
-	int row = current_row->intValue ();
+	int row = active_row;
 	if (row < 0) {
 		RK_ASSERT (false);
 		return;
 	}
-	unfinished_rows.insert (row);
 
 	QList<RKComponentPropertyStringList *> cols = columns_to_update.values (property);
 	QTreeWidgetItem *display_item = 0;
@@ -309,7 +332,7 @@
 void RKOptionSet::handleKeycolumnUpdate () {
 	RK_TRACE (PLUGIN);
 
-	int activate_row = current_row->intValue ();
+	int activate_row = activate_row;
 	QStringList new_keys = keycolumn->values ();
 	QStringList old_keys = column_map[keycolumn].old_values;
 	QMap<int, int> position_changes;
@@ -322,10 +345,6 @@
 			position_changes.insert (pos, old_pos);
 		}
 	}
-	for (; pos < old_keys.size (); ++pos) {
-		invalid_rows.remove (pos);
-		unfinished_rows.remove (pos);
-	}
 
 	if (position_changes.isEmpty () && (old_keys.size () == new_keys.size ())) {
 		columns_which_have_been_updated_externally.clear ();
@@ -366,22 +385,25 @@
 	}
 
 	// update status info
-	QSet<int> new_unfinished_rows;
-	QSet<int> new_invalid_rows;
+	QList<RowInfo> new_row_info = rows;
+	for (int i = (new_keys.size () - new_row_info.size ()); i > 0; --i) new_row_info.append (RowInfo ());
 	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_unfinished_rows.insert (pos);
+				new_row_info.insert (pos, RowInfo ());
 			} else {	// old key changed position
-				if (unfinished_rows.contains (old_pos)) new_unfinished_rows.insert (pos);
-				if (invalid_rows.contains (old_pos)) new_invalid_rows.insert (pos);
+				new_row_info[pos] = rows[old_pos];
 			} // NOTE: not visible: old key is gone without replacement
 		}
 	}
-	unfinished_rows = new_unfinished_rows;
-	invalid_rows = new_invalid_rows;
+	rows = new_row_info.mid (0, new_keys.size ());
+	n_invalid_rows = n_unfinished_rows = 0;
+	for (int i = 0; i < rows.size (); ++i) {
+		if (!rows[i].finished) ++n_unfinished_rows;
+		if (!rows[i].valid) ++n_invalid_rows;
+	}
 
 	columns_which_have_been_updated_externally.clear ();
 	column_map[keycolumn].old_values = new_keys;
@@ -389,12 +411,15 @@
 	int nrows = new_keys.size ();
 	row_count->setIntValue (nrows);
 	activate_row = qMax (new_keys.size () - 1, activate_row);
-	current_row->setIntValue (activate_row);
+	current_row->setIntValue (active_row = activate_row);
 }
 
 void RKOptionSet::setContentsForRow (int row) {
 	RK_TRACE (PLUGIN);
 
+#warning ------------ TODO: If needed, initialize serialization to default values, first! ----------------
+#warning ------------ TODO: Then initialize from serialization ----------------
+#warning ------------ then apply column values as below ----------------
 	QMap<RKComponentPropertyStringList *, ColumnInfo>::const_iterator it = column_map.constBegin ();
 	for (; it != column_map.constEnd (); ++it) {
 		RKComponentPropertyStringList* col = it.key ();
@@ -429,7 +454,7 @@
 	updating_from_storage = true;
 
 	int count = -1;
-	int activate_row = current_row->intValue ();
+	int activate_row = active_row;
 	QMap<RKComponentPropertyStringList *, ColumnInfo>::iterator it = column_map.begin ();
 
 	// first make sure the display has correct number of rows
@@ -459,14 +484,14 @@
 
 			// NOTE: However, internal status info should have been adjusted to the new indices, already
 			if (values[row] != ci.old_values.value (row)) {
-				unfinished_rows.insert (row);
+				setRowState (row, false, false);
 			}
 		}
 		ci.old_values = values;
 	}
 
 #warning TODO: duplicate update
-	current_row->setIntValue (activate_row);
+	current_row->setIntValue (active_row = activate_row);
 	setContentsForRow (activate_row);
 
 	row_count->setIntValue (count);
@@ -503,16 +528,28 @@
 	RK_TRACE (PLUGIN);
 
 	RK_ASSERT (property == current_row);
+	int row = current_row->intValue ();
+	if (row != active_row) {	// May or may not be the case. True, e.g. if a row was removed
+		storeRowSerialization (active_row);
+		active_row = row;
+	}
+
 	if (display) {
 		QTreeWidgetItem *item = 0;
-		int row = current_row->intValue ();
 		if (row >= 0) item = display->topLevelItem (row);
 		if (item != display->currentItem ()) display->setCurrentItem (item);
 	}
-#warning: What if the current row is invalid. Should we refuse to switch? Or simply keep track of the fact? What if it is still processing?
+
 	update_timer.start ();
 }
 
+void RKOptionSet::storeRowSerialization (int row) {
+	RK_TRACE (PLUGIN);
+
+	if (row < 0) return;	// No row was active
+#warning ---------------- TODO ----------------------
+}
+
 void RKOptionSet::currentRowChanged (QTreeWidgetItem *new_row) {
 	RK_TRACE (PLUGIN);
 
@@ -527,13 +564,13 @@
 
 	ComponentStatus s = RKComponent::recursiveStatus ();
 	if (s == Dead) return s;
-	if (!unfinished_rows.isEmpty ()) return Processing;
+	if (n_unfinished_rows > 0) return Processing;
 	if (update_timer.isActive ()) return Processing;
 	return s;
 }
 
 bool RKOptionSet::isValid () {
-	if (!invalid_rows.isEmpty ()) return false;
+	if (n_invalid_rows > n_unfinished_rows) return false;
 	int count = row_count->intValue ();
 	if (count < min_rows) return false;
 	if ((count > 0) && (count < min_rows_if_any)) return false;

Modified: trunk/rkward/rkward/plugin/rkoptionset.h
===================================================================
--- trunk/rkward/rkward/plugin/rkoptionset.h	2012-11-08 21:31:33 UTC (rev 4424)
+++ trunk/rkward/rkward/plugin/rkoptionset.h	2012-11-09 11:34:34 UTC (rev 4425)
@@ -30,6 +30,10 @@
 class QPushButton;
 
 /** An RKOptionSet provides a group of options for an arbitrary number of "rows". E.g. different line colors for each of a group of variables.
+ * 
+ * TODO
+ * - serialization / de-serialization. We will need to make RKComponentBase::fetchPropertyValuesRecursive() and RKComponent::setPropertyValues() virtual, and reimplement them.
+ * 
   *@author Thomas Friedrichsmeier
   */
 class RKOptionSet : public RKComponent {
@@ -42,6 +46,8 @@
 	bool isValid ();
 	/** reimplemented from RKComponent */
 	ComponentStatus recursiveStatus ();
+	/** reimplemented from RKComponent */
+	void changed ();
 private slots:
 	void governingPropertyChanged (RKComponentPropertyBase *property);
 	void columnPropertyChanged (RKComponentPropertyBase *property);
@@ -53,6 +59,9 @@
 private:
 	void initDisplay ();
 	void updateVisuals ();
+	int rowCount () const { return row_count->intValue (); };
+	void setRowState (int row, bool finished, bool valid);
+	void storeRowSerialization (int row);
 
 	RKComponentPropertyInt *current_row;
 	RKComponentPropertyInt *row_count;
@@ -75,10 +84,16 @@
 	};
 	/** Map of all columns to their meta info */
 	QMap<RKComponentPropertyStringList *, ColumnInfo> column_map;
-	/** Rows which have been not yet been processed, fully */
-	QSet<int> unfinished_rows;
-	/** Rows which have been fully processed but were invalid (contents component was not satisfied) */
-	QSet<int> invalid_rows;
+	struct RowInfo {
+		RowInfo () : valid (false), finished (false) {};
+		bool valid;		/**< has finished processing and is known to be valid */
+		bool finished;	/**< has finished processing */
+		QMap<QString, QString> full_row_serialization;	/**< complete serialization of this row, (see RKComponent::fetchPropertyValuesRecursive()) */
+	};
+	QList<RowInfo> rows;
+	QMap<QString, QString> default_row_state;
+	int n_unfinished_rows, n_invalid_rows;
+	int active_row;
 
 	RKComponent *contents_container;
 	QTreeWidget *display;

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