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

tfry at users.sourceforge.net tfry at users.sourceforge.net
Mon May 21 17:23:10 UTC 2012


Revision: 4258
          http://rkward.svn.sourceforge.net/rkward/?rev=4258&view=rev
Author:   tfry
Date:     2012-05-21 17:23:09 +0000 (Mon, 21 May 2012)
Log Message:
-----------
Add support for optionsets with manual addition / removal, and some initial bugfixing (many more bugs lefts)

Modified Paths:
--------------
    trunk/rkward/rkward/plugin/rkcomponentproperties.cpp
    trunk/rkward/rkward/plugin/rkcomponentproperties.h
    trunk/rkward/rkward/plugin/rkoptionset.cpp
    trunk/rkward/rkward/plugin/rkoptionset.h
    trunk/rkward/rkward/plugins/testing/optionset.js
    trunk/rkward/rkward/plugins/testing/optionset.xml

Modified: trunk/rkward/rkward/plugin/rkcomponentproperties.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentproperties.cpp	2012-05-21 14:08:59 UTC (rev 4257)
+++ trunk/rkward/rkward/plugin/rkcomponentproperties.cpp	2012-05-21 17:23:09 UTC (rev 4258)
@@ -172,6 +172,12 @@
 	return _value;
 }
 
+bool RKComponentPropertyStringList::setValue (const QString &string) {
+	if (string.isNull ()) setValues (QStringList ());
+	else setValues (string.split (sep));
+	return true;
+}
+
 void RKComponentPropertyStringList::setValueAt (int index, const QString& value) {
 	RK_TRACE (PLUGIN);
 	

Modified: trunk/rkward/rkward/plugin/rkcomponentproperties.h
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentproperties.h	2012-05-21 14:08:59 UTC (rev 4257)
+++ trunk/rkward/rkward/plugin/rkcomponentproperties.h	2012-05-21 17:23:09 UTC (rev 4258)
@@ -86,7 +86,7 @@
 	const QString valueAt (int index) const { return storage.value (index); };
 /** set the values in string form (values will be split by the current separator)
 @returns false if the value is illegal (in this property, all strings are legal) */
-	bool setValue (const QString &string) { setValues (string.split (sep)); return true; };
+	bool setValue (const QString &string);
 /** change only the string at the given index. List will be expanded, as necessary. */
 	void setValueAt (int index, const QString &value);
 /** get all current strings as a QStringList */

Modified: trunk/rkward/rkward/plugin/rkoptionset.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkoptionset.cpp	2012-05-21 14:08:59 UTC (rev 4257)
+++ trunk/rkward/rkward/plugin/rkoptionset.cpp	2012-05-21 17:23:09 UTC (rev 4258)
@@ -20,11 +20,13 @@
 #include <QVBoxLayout>
 #include <QTreeWidget>
 #include <QHeaderView>
+#include <QPushButton>
 
 #include <klocale.h>
 #include <kvbox.h>
 
 #include "rkstandardcomponent.h"
+#include "../misc/rkstandardicons.h"
 #include "../misc/xmlhelper.h"
 
 #include "../debug.h"
@@ -60,6 +62,7 @@
 	contents_container = new RKComponent (this, contents_box);
 	RKComponentBuilder *builder = new RKComponentBuilder (contents_container, QDomElement ());
 	builder->buildElement (xml->getChildElement (element, "content", DL_ERROR), contents_box, false);
+	builder->makeConnections ();
 #warning TOOD: do we need this? or is the per-column default good enough?
 #warning TOOD: should we wait until the (top level) plugin initial state has settled, before fetching the defaults?
 	// take a snapshot of the default state of the contents
@@ -68,12 +71,12 @@
 	// create columns
 	XMLChildList options = xml->getChildElements (element, "option", DL_WARNING);
 
-	QStringList visible_column_labels;
+	QStringList visible_column_labels ("#");	// Optionally hidden first row for index
 	for (int i = 0; i < options.size (); ++i) {
 		const QDomElement &e = options.at (i);
 		QString id = xml->getStringAttribute (e, "id", QString (), DL_ERROR);
 		QString label = xml->getStringAttribute (e, "label", QString (), DL_DEBUG);
-		QString governor = xml->getStringAttribute (e, "connect", QString (), DL_WARNING);
+		QString governor = xml->getStringAttribute (e, "connect", QString (), DL_INFO);
 		bool restorable = xml->getBoolAttribute (e, "restorable", true, DL_INFO);
 
 		while (child_map.contains (id)) {
@@ -115,7 +118,7 @@
 	QMap<RKComponentPropertyStringList *, ColumnInfo>::iterator it = column_map.begin ();
 	for (; it != column_map.end (); ++it) {
 		ColumnInfo &ci = it.value ();
-		if (!ci.governor.isEmpty ()) {		// there *can* be columns without governor. This allows to connect two option-sets, e.g. on different pages of a tabbook, manually
+		if (!ci.governor.isEmpty ()) {		// there *can* be columns without governor for driven or connected option sets
 			// Establish connections between columns and their respective governors. Since the format differs, the connection is done indirectly, through this component.
 			// So, here, we set up a map of properties to columns, and connect to the change signals.
 			RKComponentBase *governor = contents_container->lookupComponent (ci.governor, &ci.governor_modifier);
@@ -141,9 +144,17 @@
 	if (display) {		// may or may not have been created
 		display->setColumnCount (visible_column_labels.size ());
 		display->setHeaderLabels (visible_column_labels);
-#warning TODO: implement index
-//		display->verticalHeader ()->setVisible (display_show_index);
+		display->setItemsExpandable (false);
+		display->setRootIsDecorated (false);
+		if (display_show_index) display->resizeColumnToContents (0);
+		else display->setColumnHidden (0, true);
 		connect (display, SIGNAL (currentItemChanged (QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT (currentRowChanged (QTreeWidgetItem*)));
+
+		if (keycolumn) display_buttons->setVisible (false);
+		else {
+			connect (add_button, SIGNAL (clicked()), this, SLOT (addRow()));
+			connect (remove_button, SIGNAL (clicked()), this, SLOT (removeRow()));
+		}
 	}
 }
 
@@ -167,9 +178,56 @@
 		display_show_index = show_index;
 	}
 
+	display_buttons = new KHBox (dummy);
+	layout->addWidget (display_buttons);
+	add_button = new QPushButton (RKStandardIcons::getIcon (RKStandardIcons::ActionInsertRow), QString (), display_buttons);
+	remove_button = new QPushButton (RKStandardIcons::getIcon (RKStandardIcons::ActionDeleteRow), QString (), display_buttons);
+
 	return (dummy);
 }
 
+void RKOptionSet::addRow () {
+	RK_TRACE (PLUGIN);
+
+	int row = current_row->intValue () + 1;	// append feels more natural than insert, here
+	if (row <= 0) row = row_count->intValue ();
+
+	QMap<RKComponentPropertyStringList *, ColumnInfo>::const_iterator it = column_map.constBegin ();
+	for (; it != column_map.constEnd (); ++it) {
+		RKComponentPropertyStringList* col = it.key ();
+		const ColumnInfo &column = it.value ();
+		QStringList values = col->values ();
+#warning TODO: scriptable defaults?
+		values.insert (row, column.default_value);
+		col->setValues (values);
+	}
+
+	current_row->setIntValue (row);
+}
+
+void RKOptionSet::removeRow () {
+	RK_TRACE (PLUGIN);
+
+	int row = current_row->intValue ();
+	int nrow = row_count->intValue ();
+	if (row < 0) {
+		RK_ASSERT (false);
+		return;
+	}
+
+	QMap<RKComponentPropertyStringList *, ColumnInfo>::const_iterator it = column_map.constBegin ();
+	for (; it != column_map.constEnd (); ++it) {
+		RKComponentPropertyStringList* col = it.key ();
+		QStringList values = col->values ();
+		values.removeAt (row);
+		col->setValues (values);
+	}
+
+	--row;
+	if ((row < 0) && (nrow > 1)) row = 0;
+	current_row->setIntValue (row);
+}
+
 // This function is called when a property of the current row of the optionset changes
 void RKOptionSet::governingPropertyChanged (RKComponentPropertyBase *property) {
 	RK_TRACE (PLUGIN);
@@ -307,14 +365,14 @@
 
 	int count = -1;
 	int row = current_row->intValue ();
+	QMap<RKComponentPropertyStringList *, ColumnInfo>::const_iterator it = column_map.constBegin ();
+	if (it != column_map.constEnd ()) count = it.key ()->values ().size ();
 	if (row < 0) {
 		contents_container->setPropertyValues (&content_defaults);
 	} else {
-		QMap<RKComponentPropertyStringList *, ColumnInfo>::const_iterator it = column_map.constBegin ();
 		for (; it != column_map.constEnd (); ++it) {
 			RKComponentPropertyStringList* col = it.key ();
 			const ColumnInfo &ci = it.value ();
-			if (it == column_map.constBegin ()) count = col->values ().size ();
 			if (!ci.restorable) continue;
 			QString dummy;
 			RKComponentBase *governor = contents_container->lookupComponent (ci.governor, &dummy);
@@ -326,16 +384,50 @@
 			}
 		}
 	}
+
 	row_count->setIntValue (count);
- 	changed ();	// needed, for the unlikely case that no change notification was triggered above, since isValid() returns false while updating
+#warning TODO: why doesn't this have an effect?
+	contents_container->enablednessProperty ()->setBoolValue (row >= 0);
+	updateVisuals ();
+	changed ();	// needed, for the unlikely case that no change notification was triggered above, since isValid() returns false while updating
 
 	updating_from_storage = false;
 }
 
+void RKOptionSet::updateVisuals () {
+	RK_TRACE (PLUGIN);
+
+	if (!display) return;
+
+	if (display_show_index) {
+		for (int row = display->topLevelItemCount () - 1; row >= 0; --row) {
+			display->topLevelItem (row)->setText (0, QString::number (row + 1));
+		}
+	}
+
+	QPalette palette = display->header ()->palette ();
+	if (!isSatisfied ()) {		// implies that it is enabled
+		palette.setColor (QPalette::Window, QColor (255, 0, 0));
+	} else {
+		if (isEnabled ()) {
+			palette.setColor (QPalette::Window, QColor (255, 255, 255));
+		} else {
+			palette.setColor (QPalette::Window, QColor (200, 200, 200));
+		}
+	}
+	display->header ()->setPalette (palette);
+}
+
 void RKOptionSet::currentRowPropertyChanged (RKComponentPropertyBase *property) {
 	RK_TRACE (PLUGIN);
 
 	RK_ASSERT (property == current_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);
+	}
 	update_timer.start ();
 }
 
@@ -344,7 +436,7 @@
 
 	RK_ASSERT (display);
 	current_row->setIntValue (display->indexOfTopLevelItem (new_row));
-	update_timer.start ();
+	// --> currentRowPropertyChanged ()
 }
 
 bool RKOptionSet::isValid () {

Modified: trunk/rkward/rkward/plugin/rkoptionset.h
===================================================================
--- trunk/rkward/rkward/plugin/rkoptionset.h	2012-05-21 14:08:59 UTC (rev 4257)
+++ trunk/rkward/rkward/plugin/rkoptionset.h	2012-05-21 17:23:09 UTC (rev 4258)
@@ -27,6 +27,7 @@
 
 class QTreeWidget;
 class QTreeWidgetItem;
+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.
   *@author Thomas Friedrichsmeier
@@ -43,12 +44,13 @@
 	void governingPropertyChanged (RKComponentPropertyBase *property);
 	void columnPropertyChanged (RKComponentPropertyBase *property);
 	void currentRowPropertyChanged (RKComponentPropertyBase *property);
-//	void addRow ();
-//	void removeRow (int index);
+	void addRow ();
+	void removeRow ();
 	void updateContents ();
 	void currentRowChanged (QTreeWidgetItem *item);
 private:
 	void initDisplay ();
+	void updateVisuals ();
 
 	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.
@@ -68,6 +70,9 @@
 	QMap<RKComponentPropertyStringList *, ColumnInfo> column_map;
 	RKComponent *contents_container;
 	QTreeWidget *display;
+	QWidget *display_buttons;
+	QPushButton *remove_button;
+	QPushButton *add_button;
 	bool display_show_index;
 	RKComponentPropertyInt *current_row;
 	RKComponentPropertyInt *row_count;

Modified: trunk/rkward/rkward/plugins/testing/optionset.js
===================================================================
--- trunk/rkward/rkward/plugins/testing/optionset.js	2012-05-21 14:08:59 UTC (rev 4257)
+++ trunk/rkward/rkward/plugins/testing/optionset.js	2012-05-21 17:23:09 UTC (rev 4258)
@@ -1 +1,8 @@
- 
+function calculate () {
+	echo ("## Manual set: ##\n")
+	echo ("row_count <- " + getValue ("mset.row_count") + "\n");
+	echo ("current_row <- " + getValue ("mset.current_row") + "\n");
+	echo ("## Driven set: ##\n")
+	echo ("row_count <- " + getValue ("set.row_count") + "\n");
+	echo ("current_row <- " + getValue ("set.current_row") + "\n");
+}

Modified: trunk/rkward/rkward/plugins/testing/optionset.xml
===================================================================
--- trunk/rkward/rkward/plugins/testing/optionset.xml	2012-05-21 14:08:59 UTC (rev 4257)
+++ trunk/rkward/rkward/plugins/testing/optionset.xml	2012-05-21 17:23:09 UTC (rev 4258)
@@ -14,12 +14,34 @@
 			This plugin is bogus! Do not use!
 		</text>
 		<tabbook>
+			<tab label="Manual set">
+				<optionset id="mset">
+					<content>
+						<frame>
+							<optiondisplay index="true"/>
+							<row>
+								<varselector id="vars"/>
+								<column>
+									<varslot type="numeric" id="x" source="vars" required="false" label="Pick an object"/>
+									<input id="summary" label="Enter a summary" size="large"/>
+									<stretch/>
+								</column>
+							</row>
+						</frame>
+					</content>
+					<option id="object" connect="x.available" restorable="true"/>
+					<option id="objshort" label="Object" connect="x.available.shortname" restorable="false"/>
+					<option id="summary" connect="summary.text" restorable="true"/>
+				</optionset>
+			</tab>
 			<tab label="Driven set">
+				<text>First, select some objects, here (it doesn't matter, what you pick).</text>
 				<row>
-					<column>
-						<varselector id="vars"/>
-						<varslot type="numeric" id="x" source="vars" required="true" label="variables" multi="true"/>
-					</column>
+					<varselector id="vars"/>
+					<varslot type="numeric" id="x" source="vars" required="false" label="variables" multi="true"/>
+				</row>
+				<text><p> </p><p>Next, see how the controls allow you to specify "Comments" for each object.</p></text>
+				<row>
 					<optionset id="set" min_rows="1" keycolumn="var">
 						<content>
 							<frame>
@@ -29,7 +51,7 @@
 								<input id="commentb" label="Comment B"/>
 							</frame>
 						</content>
-						<option id="var" label="test" connect="dummyslot.available" restorable="true"/>
+						<option id="var" label="test" restorable="true"/>
 						<option id="varname" label="Varname" restorable="false"/>
 						<option id="ca" label="Comment A" connect="commenta.text" restorable="true"/>
 						<option id="cb" connect="commentb.text" restorable="true"/>

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