[rkward-cvs] rkward/rkward/plugin rkcomponentproperties.cpp,1.3,1.4 rkcomponentproperties.h,1.3,1.4

Thomas Friedrichsmeier tfry at users.sourceforge.net
Wed Nov 30 15:22:18 UTC 2005


Update of /cvsroot/rkward/rkward/rkward/plugin
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14617

Modified Files:
	rkcomponentproperties.cpp rkcomponentproperties.h 
Log Message:
Implemented double property. Merged and completed (mockups for) robject and robjectlist properties

Index: rkcomponentproperties.cpp
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/plugin/rkcomponentproperties.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** rkcomponentproperties.cpp	28 Nov 2005 22:14:54 -0000	1.3
--- rkcomponentproperties.cpp	30 Nov 2005 15:22:16 -0000	1.4
***************
*** 43,48 ****
  
  \section TODO TODO
! How should invalid values be handled? Currently we keep the bad value as the string value, but use a corrected default in
  the specialized properties (e.g. RKComponentPropertyInt::intValue () always returns something valid). Does this really make sense?
  */
  
--- 43,58 ----
  
  \section TODO TODO
! - How should invalid values be handled? Currently we keep the bad value as the string value, but use a corrected default in
  the specialized properties (e.g. RKComponentPropertyInt::intValue () always returns something valid). Does this really make sense?
+ 
+ - Maybe some properties could hold sub-properties of a different type to make flexibly and meaningfully connecting different properties easier (e.g. an RKComponentPropertyRObject might make dimensionality of the selected object available as an RKComponentPropertyInt). This might be a future extension to consider. Properties containing sub-properties would parse the modifier to pass down requests, if applicable.
+ 
+ - Maybe Int and Double properties could be joined to a numeric property?
+ 
+ - Add something like RKComponentPropertySelect for a property that accepts one or more of a set of predefined strings (like e.g. for a radio-box)
+ 
+ - Carefully check whether all API-elements are really needed once the implementation is complete
+ 
+ - All these TODOs should be delayed until there is at least a rudimentary implementation of components to play with
  */
  
***************
*** 377,379 ****
--- 387,553 ----
  ///////////////////////////////////////////// Double //////////////////////////////////////////
  
+ RKComponentPropertyDouble::RKComponentPropertyDouble (QObject *parent, bool required, double default_value) : RKComponentPropertyBase (parent, required) {
+ 	RK_TRACE (PLUGIN);
+ 
+ 	validator = new QDoubleValidator (this);		// accepts all ints initially
+ 	RKComponentPropertyDouble::default_value = default_value;
+ 	internalSetValue (default_value);
+ }
+ 
+ RKComponentPropertyDouble::~RKComponentPropertyDouble () {
+ 	RK_TRACE (PLUGIN);
+ }
+ 
+ bool RKComponentPropertyDouble::setDoubleValue (double new_value) {
+ 	RK_TRACE (PLUGIN);
+ 
+ 	internalSetValue (new_value);
+ 	emit (valueChanged (this));
+ 	return (isValid ());
+ }
+ 
+ bool RKComponentPropertyDouble::setValue (const QString &string) {
+ 	RK_TRACE (PLUGIN);
+ 
+ 	internalSetValue (string);
+ 	emit (valueChanged (this));
+ 	return (isValid ());
+ }
+ 
+ void RKComponentPropertyDouble::setMin (double lower) {
+ 	RK_TRACE (PLUGIN);
+ 
+ 	validator->setBottom (lower);
+ 	if (default_value < lower) {
+ 		RK_DO (qDebug ("default value in double property is lower than lower boundary"), PLUGIN, DL_WARNING);
+ 		default_value = lower;
+ 	}
+ 	if (current_value < lower) {
+ 		setDoubleValue (lower);
+ 	}
+ }
+ 
+ void RKComponentPropertyDouble::setMax (double upper) {
+ 	RK_TRACE (PLUGIN);
+ 
+ 	validator->setTop (upper);
+ 	if (default_value > upper) {
+ 		RK_DO (qDebug ("default value in double property is larger than upper boundary"), PLUGIN, DL_WARNING);
+ 		default_value = upper;
+ 	}
+ 	if (current_value > upper) {
+ 		setDoubleValue (upper);
+ 	}
+ }
+ 
+ double RKComponentPropertyDouble::minValue () {
+ 	RK_TRACE (PLUGIN);
+ 	RK_ASSERT (validator);
+ 
+ 	return (validator->bottom ());
+ }
+ 
+ double RKComponentPropertyDouble::maxValue () {
+ 	RK_TRACE (PLUGIN);
+ 	RK_ASSERT (validator);
+ 
+ 	return (validator->top ());
+ }
+ 
+ double RKComponentPropertyDouble::doubleValue () {
+ 	RK_TRACE (PLUGIN);
+ 
+ 	return current_value;
+ }
+ 
+ QString RKComponentPropertyDouble::value (const QString &modifier) {
+ 	RK_TRACE (PLUGIN);
+ 
+ 	if (!modifier.isEmpty ()) {
+ 		warnModifierNotRecognized (modifier);
+ 		return QString::null;
+ 	}
+ 	return _value;
+ }
+ 
+ bool RKComponentPropertyDouble::isStringValid (const QString &string) {
+ 	RK_TRACE (PLUGIN);
+ 
+ 	int dummy = 0;
+ 	QString string_copy = string;
+ 	return (validator->validate (string_copy, dummy) == QValidator::Acceptable);
+ }
+ 
+ void RKComponentPropertyDouble::connectToGovernor (RKComponentPropertyBase *governor, const QString &modifier, bool reconcile_requirements) {
+ 	RK_TRACE (PLUGIN);
+ 
+ 	RK_ASSERT (governor);
+ 	connect (governor, SIGNAL (valueChanged (RKComponentPropertyBase *)), this, SLOT (governorValueChanged (RKComponentPropertyBase *)));
+ 	governor_modifier = modifier;
+ 
+ 	// reconcile requirements if applicable
+ 	if (reconcile_requirements && governor_modifier.isEmpty ()) {
+ 		if (governor->type () == PropertyInt) {
+ 			RKComponentPropertyInt *igov = static_cast<RKComponentPropertyInt *> (governor); 	// convenience pointer
+ 			if (validator->bottom () > igov->minValue ()) {
+ 				igov->setMin ((int) validator->bottom ());			// no (real) need to worry about integer overflow, as we only do this if the integers bottom limit is lower. Bad things could happen, if the bottom limit of this double property is extremely large (> INT_MAX), but this should rarely happen.
+ 			}
+ 			if (validator->top () < igov->maxValue ()) {
+ 				igov->setMax ((int) validator->top ());			// see above comment
+ 			}
+ 		} else if (governor->type () == PropertyDouble) {
+ 			RKComponentPropertyDouble *dgov = static_cast<RKComponentPropertyDouble *> (governor); 	// convenience pointer
+ 			if (validator->bottom () > dgov->minValue ()) {
+ 				dgov->setMin (validator->bottom ());
+ 			}
+ 			if (validator->top () < dgov->maxValue ()) {
+ 				dgov->setMax (validator->top ());
+ 			}
+ 		}
+ 	}
+ 
+ 	// fetch current value
+ 	governorValueChanged (governor);
+ }
+ 
+ void RKComponentPropertyDouble::governorValueChanged (RKComponentPropertyBase *property) {
+ 	RK_TRACE (PLUGIN);
+ 
+ 	if (governor_modifier.isEmpty ()) {
+ 		if (property->type () == PropertyInt) {
+ 			internalSetValue ((double) (static_cast<RKComponentPropertyInt *>(property)->intValue ()));
+ 		} else if (property->type () == PropertyDouble) {
+ 			internalSetValue (static_cast<RKComponentPropertyDouble *>(property)->doubleValue ());
+ 		} else {
+ 			internalSetValue (property->value (QString::null));
+ 		}
+ 	} else {
+ 		internalSetValue (property->value (governor_modifier));
+ 	}
+ 	emit (valueChanged (this));
+ }
+ 
+ QDoubleValidator *RKComponentPropertyDouble::getValidator () {
+ 	RK_TRACE (PLUGIN);
+ 	RK_ASSERT (validator);
+ 	return validator;
+ }
+ 
+ void RKComponentPropertyDouble::internalSetValue (double new_value) {
+ 	current_value = new_value;
+ 	_value = QString::number (current_value);
+ 	is_valid = ((new_value >= validator->bottom ()) && (new_value <= validator->top ()));
+ 	if (!is_valid) current_value = default_value;
+ }
+ 
+ void RKComponentPropertyDouble::internalSetValue (QString new_value) {
+ 	current_value = new_value.toDouble (&is_valid);
+ 	if (!is_valid) {
+ 		_value = new_value;
+ 		current_value = default_value;
+ 		return;
+ 	}
+ 	internalSetValue (current_value);		// will check range and prettify _value
+ }
+ 
  #include "rkcomponentproperties.moc"

Index: rkcomponentproperties.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/plugin/rkcomponentproperties.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** rkcomponentproperties.h	28 Nov 2005 22:14:54 -0000	1.3
--- rkcomponentproperties.h	30 Nov 2005 15:22:16 -0000	1.4
***************
*** 38,44 ****
  		PropertyInt = 3,
  		PropertyDouble = 4,
! 		PropertyRObject = 5,
! 		PropertyRObjectList = 6,
! 		PropertyCode = 7,
  		PropertyUser = 1000		/**< for user expansion */
  	};
--- 38,43 ----
  		PropertyInt = 3,
  		PropertyDouble = 4,
! 		PropertyRObjects = 5,
! 		PropertyCode = 6,
  		PropertyUser = 1000		/**< for user expansion */
  	};
***************
*** 175,178 ****
--- 174,179 ----
  /** sets the int value. Also takes care of notifying dependent components */
  	bool setDoubleValue (double new_value);
+ /** reimplemented from RKComponentPropertyBase to convert to int value according to current settings */
+ 	bool setValue (const QString &string);
  /** set lower boundary. Default parameter will effectively remove the boundary. You should call this *before* connecting to any other properties, so limits can be reconciled */
  	void setMin (double lower=FLT_MIN);
***************
*** 187,192 ****
  /** reimplemented from RKComponentPropertyBase. Return current value as a string. In the future, modifier might be used for format. */
  	QString value (const QString &modifier=QString::null);
- /** reimplemented from RKComponentPropertyBase to convert to int value according to current settings */
- 	bool setValue (const QString &string);
  /** reimplemented from RKComponentPropertyBase to test whether conversion to int value is possible according to current settings (is a number, and within limits min and max) */
  	bool isStringValid (const QString &string);
--- 188,191 ----
***************
*** 212,254 ****
  ///////////////////////////////////////////////// RObject ////////////////////////////////////////////////////////
  class RObject;
  
  /** special type of RKComponentProperty, that prepresents an RObject
  //TODO: this property should auto-connect to RKModificationTracker, to be safe when the object gets deleted/changed */
! class RKComponentPropertyRObject : public RKComponentPropertyBase {
! public:
! 	void setClassFilter (const QString &classes);
! 	void setTypeFilter (const QString &types);
! 	void setDimensionFilter (int dimensionality, int min_length=-1, int max_length=-1);
! 	bool setValue (RObject *object);
! 	bool isObjectValid (RObject *object);
! 	RObject *objectValue ();
! /** reimplemented from RKComponentPropertyBase. Modifier "label" returns label. Modifier "shortname" returns short name. Modifier QString::null returns full name. */
! 	QString value (const QString &modifier=QString::null);
! /** reimplemented from RKComponentPropertyBase to convert to RObject, if possible with current constraints */
! 	bool setValue (const QString &value);
! /** reimplemented from RKComponentPropertyBase to test whether conversion to RObject, is possible with current constraints */
! 	bool isValid (const QString &value);
! };
! 
! ///////////////////////////////////////////////// RObjectList ////////////////////////////////////////////////////////
! 
! #include <qvaluelist.h>
! 
! /** extension of RKComponentPropertyRObject, allowing to hold several RObjects at once. */
! class RKComponentPropertyRObjectList : public RKComponentPropertyRObject {
  public:
! 	void setListLength (int min_length, int min_length_if_any=-1, int max_length=-1);
! 	bool addValue (RObject *object);
! 	void removeValue (RObject *object);
  	bool isObjectValid (RObject *object);
! /** reimplemented from RKComponentPropertyBase to return the first RObject in the list */
  	RObject *objectValue ();
  	QValueList<RObject *> objectList ();
! /** reimplemented from RKComponentPropertyBase. Modifier "label" returns label. Modifier "shortname" returns short name. Modifier QString::null returns full name. */
  	QString value (const QString &modifier=QString::null);
! /** reimplemented from RKComponentPropertyBase to convert to list of RObject, if possible with current constraints */
  	bool setValue (const QString &value);
! /** reimplemented from RKComponentPropertyBase to test whether conversion to list of RObject, is possible with current constraints */
! 	bool isValid (const QString &value);
  };
  
--- 211,280 ----
  ///////////////////////////////////////////////// RObject ////////////////////////////////////////////////////////
  class RObject;
+ #include <qstringlist.h>
+ #include <qvaluelist.h>
  
  /** special type of RKComponentProperty, that prepresents an RObject
  //TODO: this property should auto-connect to RKModificationTracker, to be safe when the object gets deleted/changed */
! class RKComponentPropertyRObjects : public RKComponentPropertyBase {
! 	Q_OBJECT
  public:
! /** how many objects can this property hold? Use default values (-1) to remove constraints
! @param min_num_objects Minimum number of objects for this property to be valid
! @param min_num_objects_if_any Some properties may be valid, if they hold either no objects at all, or at least a certain number of objects
! @param max_num_objects Maximum number of objects for this property to be valid */
! 	void setListLength (int min_num_objects=-1, int min_num_objects_if_any=-1, int max_num_objects=-1);
! /** add an object value */
! 	bool addObjectValue (RObject *object);
! /** remove an object value */
! 	void removeObjectValue (RObject *object);
! /** Set property to only accept certain classes. If you provide an empty list, all classes will be accepted*/
! 	void setClassFilter (const QStringList &classes);
! /** Set property to only accept certain object types. If you provide an empty list, all types will be accepted */
! 	void setTypeFilter (const QStringList &types);
! /** Set property to only accept objects of certain dimensions. If you provide default parameters (-1), all objects will be accepted
! @param dimensionality Number of dimensions the object must have. -1 will accept objects of all dimensions
! @param min_length Minimum length of first dimension. -1 will accept objects of all lenghts
! @param max_length Maximum length of first dimension. -1 will accept objects of all lengths */
! 	void setDimensionFilter (int dimensionality=-1, int min_length=-1, int max_length=-1);
! /** Directly set an RObject.
! @returns false if the object does not qualify as a valid selection according to current settings (class/type/dimensions), true otherwise */
! 	bool setObjectValue (RObject *object);
! /** Check whether an object is valid for this property.
! @returns false if the object does not qualify as a valid selection according to current settings (class/type/dimensions), true otherwise */
  	bool isObjectValid (RObject *object);
! /** Get current object. If the property can hold several objects, only the first is returned. See objectList ().
! @returns 0 if no valid object is selected */
  	RObject *objectValue ();
+ /** Get current list of objects.
+ @returns an empty list if no valid object is selected */
  	QValueList<RObject *> objectList ();
! /** reimplemented from RKComponentPropertyBase. Modifier "label" returns label. Modifier "shortname" returns short name. Modifier QString::null returns full name. If no object is set, returns an empty string */
  	QString value (const QString &modifier=QString::null);
! /** reimplemented from RKComponentPropertyBase to convert to RObject with current constraints
! @returns 0 if no such object could be found or the object is invalid */
  	bool setValue (const QString &value);
! /** reimplemented from RKComponentPropertyBase to test whether conversion to RObject, is possible with current constraints */
! 	bool isStringValid (const QString &value);
! /** RTTI */
! 	int type () { return PropertyRObjects; };
! /** reimplemented from RKComponentPropertyBase to actually reconcile requirements with other object properties */
! 	void connectToGovernor (RKComponentPropertyBase *governor, const QString &modifier=QString::null, bool reconcile_requirements=true);
! /** reimplemented from RKComponentPropertyBase to use special handling for object properties */
! 	void governorValueChanged (RKComponentPropertyBase *property);
! public slots:
! /** to be connected to RKModificationTracker::objectRemoved (). This is so we get notified if the object currently selected is removed */
! 	void objectRemoved (RObject *object);
! /** to be connected to RKModificationTracker::objectPropertiesChanged (). This is so we get notified if the object currently selected is changed */
! 	void objectPropertiesChanged (RObject *object);
! protected:
! 	QValueList<RObject *> object_list;
! 	int dims;
! 	int min_length;
! 	int max_length;
! 	int min_num_objects;
! 	int min_num_objects_if_any;
! 	int max_num_objects;
! 	QStringList classes;
! 	QStringList types;
  };
  





More information about the rkward-tracker mailing list