[rkward-cvs] rkward component-draft,1.4,1.5
Thomas Friedrichsmeier
tfry at users.sourceforge.net
Mon Nov 21 22:22:53 UTC 2005
Update of /cvsroot/rkward/rkward
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31157
Modified Files:
component-draft
Log Message:
component-draft about ready for first real work
Index: component-draft
===================================================================
RCS file: /cvsroot/rkward/rkward/component-draft,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** component-draft 18 Nov 2005 17:13:28 -0000 1.4
--- component-draft 21 Nov 2005 22:22:51 -0000 1.5
***************
*** 3,31 ****
Key classes:
! RKComponentSlot
! something used as input, and output. Several types of this may exist, each offering different values. The more interesting application is using them as input-suppliers for components. RKComponentSlot should probably also do input verification. Basically, an RKComponentSlot is the GUI-independent portion of a GUI-settable value. Mockups:
! class RKComponentSlotBase : public QObject {
public signals:
! /** slot has changed its value. Any connected RKComponentSlots/RKComponents should update their state
! @param slot A pointer to the changed slot for easy reference */
! void valueChanged (RKComponentSlotBase *slot);
public slots:
! /** the (Qt-)slot in which (by default) the (RKComponent-)slot is notified, when a slot it depends on has changed. Generally you should reimplement this function to add special handling for the slots you know about. */
! virtual void governorValueChanged (RKComponentSlotBase *slot);
public:
! enum RKComponentSlotTypes {
! 0: RKComponentSlotBase,
! 1: RKComponentSlotBool,
! 2: RKComponentSlotInt,
! 3: RKComponentSlotDouble,
! 4: RKComponentSlotRObject,
! 5: RKComponentSlotRObjectList,
! 1000: RKComponentSlotUser /**< for user expansion */
};
! /** constructor. Pass a valid QObject as parent so the slot will be auto-destructed when no longer needed */
! RKComponentSlotBase (QObject *parent);
/** destructor */
! virtual ~RKComponentSlotBase ();
/** supplies the current value. Since more than one value may be supplied, modifier can be used to select a value. Default implementation only has a single string, however. */
virtual QString value (const QString &modifier=QString::null);
--- 3,31 ----
Key classes:
! RKComponentProperty
! something used as input, and output. Several types of this may exist, each offering different values. The more interesting application is using them as input-suppliers for components. RKComponentProperty should probably also do input verification. Basically, an RKComponentProperty is the GUI-independent portion of a GUI-settable value. Mockups:
! class RKComponentPropertyBase : public QObject {
public signals:
! /** property has changed its value. Any connected RKComponentPropertys/RKComponents should update their state
! @param property A pointer to the changed property for easy reference */
! void valueChanged (RKComponentPropertyBase *property);
public slots:
! /** the (Qt-)slot in which (by default) the (RKComponent-)property is notified, when a property it depends on has changed. Generally you should reimplement this function to add special handling for the properties you know about. */
! virtual void governorValueChanged (RKComponentPropertyBase *property);
public:
! enum RKComponentPropertyTypes {
! 0: RKComponentPropertyBase,
! 1: RKComponentPropertyBool,
! 2: RKComponentPropertyInt,
! 3: RKComponentPropertyDouble,
! 4: RKComponentPropertyRObject,
! 5: RKComponentPropertyRObjectList,
! 1000: RKComponentPropertyUser /**< for user expansion */
};
! /** constructor. Pass a valid QObject as parent so the property will be auto-destructed when no longer needed */
! RKComponentPropertyBase (QObject *parent);
/** destructor */
! virtual ~RKComponentPropertyBase ();
/** supplies the current value. Since more than one value may be supplied, modifier can be used to select a value. Default implementation only has a single string, however. */
virtual QString value (const QString &modifier=QString::null);
***************
*** 41,82 ****
/** see setRequired () */
bool isSatisfied ();
! /** for RTTI. see RKComponentSlotTypes */
virtual int type ();
! /** connect this slot to a governor slot (given as argument). If reconcile_requirements, the requirements of both slots are reconciled to the least common denominator. The dependent slot will be notified on all changes made in the governing slot, so it can update its value.
! Generally with few exceptions, you can only connect to slots that are either of the same class as this slot, or of an extended class. Maybe in the future we will add some sophisticated converters allowing to connect vastly different types of slots in a meaningful way.
! If you specify a modifier, only the sub-value indicated by the modifier will be retrieved from the governing slot on governorValueChanged. In this case reconcile_requirements is ignored. */
! virtual void connectGovernor (RKComponentSlotBase *governor, const QString &modifier=QString::null, bool reconcile_requirements=true);
private:
bool valid;
bool required;
! /** if we're only interested in a specific sub-information of the governor-slot, we need to remember the corresponding modifier */
QString governor_modifier;
};
! /** special type of RKComponentSlot, that is based on a bool setting */
! class RKComponentSlotBool : public RKComponentSlotBase {
public:
/** param value_true string value if true/on
param value_false string value if false/off
param default value to use, if invalid string value was set */
! RKComponentSlotBool (const QString &value_true, const QString &value_false, bool default);
/** sets the bool value. Also takes care of notifying dependent components */
void setValue (bool value);
/** current value as bool */
bool boolValue ();
! /** reimplemented from RKComponentSlotBase. Modifier "true" returns value if true. Modifier "false" returns value if false. Modifier QString::null returns current value. */
QString value (const QString &modifier=QString::null);
! /** reimplemented from RKComponentSlotBase to convert to bool value according to current settings */
bool setValue (const QString &value);
! /** reimplemented from RKComponentSlotBase to test whether conversion to bool value is possible according to current settings */
bool isValid (const QString &value);
};
! class RKComponentSlotInt; // min, max
! class RKComponentSlotDouble; // min, max
! /** special type of RKComponentSlot, that prepresents an RObject
! //TODO: this slot should auto-connect to RKModificationTracker, to be safe when the object gets deleted/changed
! class RKComponentSlotRObject : public RKComponentSlotBase {
public:
void setClassFilter (const QString &classes);
--- 41,82 ----
/** see setRequired () */
bool isSatisfied ();
! /** for RTTI. see RKComponentPropertyTypes */
virtual int type ();
! /** connect this property to a governor property (given as argument). If reconcile_requirements, the requirements of both properties are reconciled to the least common denominator. The dependent property will be notified on all changes made in the governing property, so it can update its value.
! Generally with few exceptions, you can only connect to properties that are either of the same class as this property, or of an extended class. Maybe in the future we will add some sophisticated converters allowing to connect vastly different types of properties in a meaningful way.
! If you specify a modifier, only the sub-value indicated by the modifier will be retrieved from the governing property on governorValueChanged. In this case reconcile_requirements is ignored. */
! virtual void connectGovernor (RKComponentPropertyBase *governor, const QString &modifier=QString::null, bool reconcile_requirements=true);
private:
bool valid;
bool required;
! /** if we're only interested in a specific sub-information of the governor-property, we need to remember the corresponding modifier */
QString governor_modifier;
};
! /** special type of RKComponentProperty, that is based on a bool setting */
! class RKComponentPropertyBool : public RKComponentPropertyBase {
public:
/** param value_true string value if true/on
param value_false string value if false/off
param default value to use, if invalid string value was set */
! RKComponentPropertyBool (const QString &value_true, const QString &value_false, bool default);
/** sets the bool value. Also takes care of notifying dependent components */
void setValue (bool value);
/** current value as bool */
bool boolValue ();
! /** reimplemented from RKComponentPropertyBase. Modifier "true" returns value if true. Modifier "false" returns value if false. Modifier QString::null returns current value. */
QString value (const QString &modifier=QString::null);
! /** reimplemented from RKComponentPropertyBase to convert to bool value according to current settings */
bool setValue (const QString &value);
! /** reimplemented from RKComponentPropertyBase to test whether conversion to bool value is possible according to current settings */
bool isValid (const QString &value);
};
! class RKComponentPropertyInt; // min, max
! class RKComponentPropertyDouble; // min, max
! /** 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);
***************
*** 86,99 ****
bool isValid (RObject *object);
RObject *objectValue ();
! /** reimplemented from RKComponentSlotBase. Modifier "label" returns label. Modifier "shortname" returns short name. Modifier QString::null returns full name. */
QString value (const QString &modifier=QString::null);
! /** reimplemented from RKComponentSlotBase to convert to RObject, if possible with current constraints */
bool setValue (const QString &value);
! /** reimplemented from RKComponentSlotBase to test whether conversion to RObject, is possible with current constraints */
bool isValid (const QString &value);
};
! /** extension of RKComponentSlotRObject, allowing to hold several RObjects at once. */
! class RKComponentSlotRObjectList : public RKComponentSlotRObject {
public:
void setListLength (int min_length, int min_length_if_any=-1, int max_length=-1);
--- 86,99 ----
bool isValid (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);
};
! /** 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);
***************
*** 101,117 ****
void removeValue (RObject *object);
bool isValid (RObject *object);
! /** reimplemented from RKComponentSlotBase to return the first RObject in the list */
RObject *objectValue ();
QValueList<RObject *> objectList ();
! /** reimplemented from RKComponentSlotBase. Modifier "label" returns label. Modifier "shortname" returns short name. Modifier QString::null returns full name. */
QString value (const QString &modifier=QString::null);
! /** reimplemented from RKComponentSlotBase to convert to list of RObject, if possible with current constraints */
bool setValue (const QString &value);
! /** reimplemented from RKComponentSlotBase to test whether conversion to list of RObject, is possible with current constraints */
bool isValid (const QString &value);
};
! /** special type of RKComponentSlot used to contain R code. All stand-alone RKComponents have this. The great thing about this, is that code can be made available to embedding RKComponents by just fetching the component.code.preprocess (or .calculate, .printout, .cleanup) value */
! class RKComponentSlotCode : public RKComponentSlotBase {
public:
/** the preprocess code */
--- 101,117 ----
void removeValue (RObject *object);
bool isValid (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);
};
! /** special type of RKComponentProperty used to contain R code. All stand-alone RKComponents have this. The great thing about this, is that code can be made available to embedding RKComponents by just fetching the component.code.preprocess (or .calculate, .printout, .cleanup) value */
! class RKComponentPropertyCode : public RKComponentPropertyBase {
public:
/** the preprocess code */
***************
*** 125,142 ****
};
! RKComponentSlots are attached to and owned by RKComponents (those that use it as output)
/** abstract base class of all RKComponents, including component widgets */
class RKComponent : public QWidget {
public slots:
! /** generally the valueChanged () signal of all RKComponentSlots directly owned by this component should be connected to this (Qt-)slot, so the component can update itself accordingly */
! void slotValueChanged (RKComponentSlotBase *slot);
public:
! /** standard slot controlling visibility */
! RKComponentSlotBool *visibilitySlot ();
! /** standard slot controlling enabledness */
! RKComponentSlotBool *enablednessSlot ();
! /** standard slot controlling requiredness */
! RKComponentSlotBool *requirednessSlot ();
/** The parent of this component. Should be notified, whenever isSatisfied () or isReady ()-state changed. */
--- 125,142 ----
};
! RKComponentPropertys are attached to and owned by RKComponents (those that use it as output)
/** abstract base class of all RKComponents, including component widgets */
class RKComponent : public QWidget {
public slots:
! /** generally the valueChanged () signal of all RKComponentPropertys directly owned by this component should be connected to this (Qt-)slot, so the component can update itself accordingly */
! void propertyValueChanged (RKComponentPropertyBase *property);
public:
! /** standard property controlling visibility */
! RKComponentPropertyBool *visibilityProperty ();
! /** standard property controlling enabledness */
! RKComponentPropertyBool *enablednessProperty ();
! /** standard property controlling requiredness */
! RKComponentPropertyBool *requirednessProperty ();
/** The parent of this component. Should be notified, whenever isSatisfied () or isReady ()-state changed. */
***************
*** 144,148 ****
bool isSatisfied ();
bool isReady ();
! /** Locate the component.subcomponent.slot.value described by modifier and return its value as a string. Especially useful as a callback in code templates! Recursively walks subcomponents/slots until the requested value is found. */
QString fetchStringValue (const QString &modifier);
private:
--- 144,148 ----
bool isSatisfied ();
bool isReady ();
! /** Locate the component.subcomponent.property.value described by modifier and return its value as a string. Especially useful as a callback in code templates! Recursively walks subcomponents/properties until the requested value is found. */
QString fetchStringValue (const QString &modifier);
private:
***************
*** 160,169 ****
};
! /** (long-term): A special RKComponent doing some sort of logic conversion. It's used to connect to one or more governing slots, process/convert the value of those slots in some way, and provide one (or more) output slots.
//TODO: how will these be programmed? Hopefully we will soon have a better picture on what logic elements are actually commonly needed */
class RKLogicComponent;
// TODO: do we need this at all?
! /** describes the external interface provided by an RKComponent. This means a list of all slots that can be used as input for this component. Used for matching/mapping external RKComponentSlots to RKComponentSlots inside this component */
class RKComponentInterface {
};
--- 160,169 ----
};
! /** (long-term): A special RKComponent doing some sort of logic conversion. It's used to connect to one or more governing properties, process/convert the value of those properties in some way, and provide one (or more) output properties.
//TODO: how will these be programmed? Hopefully we will soon have a better picture on what logic elements are actually commonly needed */
class RKLogicComponent;
// TODO: do we need this at all?
! /** describes the external interface provided by an RKComponent. This means a list of all properties that can be used as input for this component. Used for matching/mapping external RKComponentPropertys to RKComponentPropertys inside this component */
class RKComponentInterface {
};
***************
*** 175,188 ****
- create Subcomponents (depth first is important!)
- ...
! - create RKComponentSlots
! - connect RKComponentSlots within this component and to subcomponents (those are already fully connected!)
- initialize
! - set initial values in RKComponentSlots
(- updates GUI)
(- may trigger changes in subcomponents)
! - connect RKComponentSlots within this component and to subcomponents (those are already fully connected!)
- connect
! - retrieve values from governing slots
(- may trigger further changes in this, and subcomponents)
- return to parent
On top level: probably a call to setUpdatesEnabled (true); update () should be done!
--- 175,213 ----
- create Subcomponents (depth first is important!)
- ...
! - create RKComponentProperty's
- initialize
! - set initial values in RKComponentProperty's
(- updates GUI)
(- may trigger changes in subcomponents)
! - connect RKComponentPropertys within this component and to subcomponents (those are already fully connected!)
- connect
! - retrieve values from governing properties
(- may trigger further changes in this, and subcomponents)
- return to parent
On top level: probably a call to setUpdatesEnabled (true); update () should be done!
+
+ /** A helper class used to build and initialize an RKComponent. Most importantly this will keep track of the properties yet to be connected. Used at least by RKStandardComponent. */
+ class RKComponentBuilder {
+ public:
+ RKComponentBuilder (RKComponent *parent);
+ ~RKComponentBuilder ();
+ void buildElement (const QDomElement &element);
+ void makeConnections ();
+ private:
+ RKComponent *parent;
+ struct RKComponentPropertyConnection {
+ QString governor_property;
+ QString client_property;
+ bool reconcile;
+ };
+ QValueList <RKComponentPropertyConnection *> connection_list;
+ };
+
+
+ Implementation plan:
+ 0) Create new directory component. Most of what's in plugin now will be migrated there.
+ 1) Create main RKComponentProperty classes (full API, basic implementation)
+ 2) Create an initial implementation of RKStandardComponent, copying heavily from RKPlugin (little code will remain in RKPlugin at the end)
+ 3) Create a few first RKComponentWidgets, copying from RKPluginWidgets, but using RKComponentProperty's internally, and deriving from RKComponent
+ 4) Test and get basic functionality working
+ 5) Finish migration
More information about the rkward-tracker
mailing list