2 kopeteproperties.h - Kopete Properties
4 Copyright (c) 2004 by Richard Smith <kde@metafoo.co.uk>
5 Kopete (c) 2002-2004 by the Kopete developers <kopete-devel@kde.org>
7 *************************************************************************
9 * This library is free software; you can redistribute it and/or *
10 * modify it under the terms of the GNU Lesser General Public *
11 * License as published by the Free Software Foundation; either *
12 * version 2 of the License, or (at your option) any later version. *
14 *************************************************************************
17 #ifndef KOPETEPROPERTIES_H
18 #define KOPETEPROPERTIES_H
32 * Contains the classes forming Kopete's Properties system.
34 * @todo Explain more, give examples.
36 * @author Richard Smith <kde@metafoo.co.uk>
41 //BEGIN core functionality
44 * @brief Property-type-independent base class for properties
46 * The base class for all properties of any type which can be set or got for @p Parent
47 * objects. It is rare to need to use this class directly. Usually you will want to use
48 * the @ref Property derived class, or dynamic_cast the PropertyBase object to another interface.
50 * @see Property UserVisible XMLSerializable StringSerializable
52 * @author Richard Smith <kde@metafoo.co.uk>
54 template<class Parent
>
59 * Returns the name of the property. This name should uniquely identify this property
60 * within the type Parent, and will be used for persistently identifying this property.
62 * For core properties, the chosen name should not contain any slash characters. For
63 * properties defined in plugins kept in Kopete's CVS, the name should be of the form
64 * pluginName/propertyName. For third-party plugins, please use a URL with a host which
65 * you own, such as "http://my-host.com/kopete/properties/groupId".
67 * @return the name of this property.
69 virtual const QByteArray
&name() const = 0;
73 * @brief Property-type-dependent base class for properties
75 * This class represents a property of type @p Type applicable to @p Parent objects. Usage
76 * of this class is usually as simple as:
79 * SomeParent *propertyContainer = ...
80 * Property<SomeParent,QString> &myProperty = ...
81 * QString value = propertyContainer->property(myProperty);
82 * propertyContainer->setProperty(myProperty, "hello");
85 * You should never need to call functions in this class directly.
87 template<class Parent
, typename Type
>
88 class Property
: public PropertyBase
<Parent
>
92 * Returns the value of this property in the object @p parent.
94 virtual Type
get( const Parent
*parent
) const = 0;
96 * Sets the value of this property in the object @p parent.
98 virtual void set( Parent
*, const Type
& ) const = 0;
102 * @brief Base class for property data objects
104 * Some property objects want to store property-specific data in their parent objects.
105 * To support that, subclasses of this class are permitted to be stored. Once passed
106 * to the @ref PropertyStorage object via @ref PropertyStorage::setCustomPropertyData,
107 * the @ref PropertyStorage object owns the PropertyData, and will delete it when it
108 * is no longer needed.
112 virtual ~PropertyData() {}
116 * @brief Storage object for PropertyData objects
118 * This class is responsible for storing PropertyData-derived data objects for properties.
119 * This is the non-templated part of the @ref WithProperties class, split out into its own
120 * class to eliminate the template bloat.
122 class PropertyStorage
124 typedef QMultiHash
<QByteArray
, PropertyData
*> PropertyDict
;
125 // setCustomPropertyData can be called on a const object, allowing the
126 // guarantee that DataProperty::data() never returns 0.
127 mutable PropertyDict _storage
;
133 qDeleteAll(_storage
);
137 * Sets the stored property data with name @p name to be @p data.
139 * @note The @p name argument should usually be the name of the property which the data
140 * is being stored for. However, if properties wish to share data, they may choose to
141 * name their custom data differently. Names are bound by the same rules as are laid out
142 * for naming properties in PropertyBase<Parent>::name.
144 void setCustomPropertyData( const QByteArray
&name
, PropertyData
*data
) const { _storage
.replace( name
, data
); }
147 * Gets the stored property data with name @p name. Returns a null
148 * pointer if no data has been stored for that property.
150 PropertyData
*getCustomPropertyData( const QByteArray
&name
) const { return _storage
.value(name
); }
154 * @brief Base class for classes to which properties can be applied
156 * This class provides support for properties to another class. If you want your class
157 * to support properties, derive from this passing your class as the Parent parameter:
160 * class YourClass : public WithProperties<YourClass> { ... };
163 * You will also need to explicitly specialise the propertyCreated() member function to
164 * load property data upon creation of a new property object.
166 template<class Parent
>
167 class WithProperties
: public PropertyStorage
171 * Get the value of property @p prop in this object.
172 * @param prop the Property object representing the property to get
175 T
property( Property
<Parent
,T
> const &prop
) { return prop
.get( static_cast<Parent
*>(this) ); }
177 * Set the value of property @p prop in this object.
178 * @param prop the Property object representing the property to get
179 * @param value the value to set the property to
182 void setProperty( Property
<Parent
,T
> const &prop
, const T
&value
) { prop
.set( static_cast<Parent
*>(this), value
); }
185 * Called when a property is created; loads the Parent object's data into the property.
187 * @note Derived classes must explicitly specialize this to load the property's data into
188 * every object of this type.
190 static void propertyCreated( const PropertyBase
<Parent
> &property
);
193 //END core functionality
198 * @brief An interface for user-visible properties
201 template<class Parent
>
204 virtual QString
userText( Parent
* ) = 0;
205 virtual QString
label() = 0;
206 virtual QString
icon() = 0;
210 * @brief An interface for properties which can be serialized as XML
213 template<class Parent
>
214 struct XMLSerializable
216 virtual void fromXML( Parent
*, const QDomElement
& ) = 0;
217 virtual void toXML( const Parent
*, QDomElement
& ) = 0;
221 * @brief An interface for properties which can be serialized as strings
224 template<class Parent
>
225 struct StringSerializable
227 virtual void fromString( Parent
*, const QString
& ) = 0;
228 virtual QString
toString( const Parent
* ) = 0;
233 //BEGIN convenience classes
236 * @internal Display a warning message when the wrong type of property data is found
238 void customPropertyDataIncorrectType( const char *name
, const std::type_info
&found
, const std::type_info
&expected
);
241 * @brief Convenience implementation of a Property that stores PropertyData
243 * A property for objects of type @p Parent, that stores data in the class @p Data.
244 * @p Data must be derived from @ref PropertyBase, or your code will not compile.
246 template<class Parent
, typename Type
, class Data
>
247 class DataProperty
: public Property
<Parent
,Type
>
250 Data
*data( const Parent
*c
) const
252 PropertyData
*pd
= c
->getCustomPropertyData( this->name() );
253 Data
*data
= dynamic_cast<Data
*>(pd
);
257 customPropertyDataIncorrectType( this->name(), typeid(*pd
), typeid(Data
) );
259 c
->setCustomPropertyData( this->name(), data
);
266 * @brief Convenience implementation of a PropertyData subclass which stores a single datum
268 * If a @ref Property needs to store only a single value in an object, using this
269 * class is simpler than deriving from @ref PropertyData yourself. The value will
270 * be default-constructed (which means for numeric types and pointers it will be
274 struct SimplePropertyData
: public PropertyData
276 SimplePropertyData() : value() {}
281 * @brief Convenience implementation of a Property which stores a single datum as PropertyData
283 * This convenience class implements the @ref Property interface by simply storing and
284 * retrieving the datum from PropertyData. This class does not provide any serialization
287 * @note You will need to derive from this class to use it; the @ref name function is
288 * still pure virtual.
290 template<class Parent
, typename Type
>
291 class SimpleDataProperty
: public DataProperty
<Parent
,Type
,SimplePropertyData
<Type
> >
294 Type
get( const Parent
*p
) const { return data(p
)->value
; }
295 void set( Parent
*p
, const Type
&v
) const { data(p
)->value
= v
; }
299 * Move somewhere else
304 * Explicitly specialized for all types QVariant supports
306 template<class T
> T
variantTo(QVariant
);
308 QVariant
variantFromXML(const QDomElement
&);
309 void variantToXML(QVariant v
, QDomElement
&);
316 * @brief Convenience implementation of XMLSerializable in terms of QVariants
318 * This class provides XML serialization for data that can be stored in a QVariant. You
319 * will need to multiply-inherit from this class and (usually indirectly) from @ref Property.
321 * You can combine this class with other convenience classes such as SimpleDataProperty
325 * class ContactNickNameProperty
326 * : public SimpleDataProperty<Contact,QString>
327 * , XMLProperty<ContactNickNameProperty,Contact,QString>
330 * const char *name() const { return "nickName"; }
334 template<class Derived
, class Parent
, typename Type
>
335 class XMLProperty
: public XMLSerializable
<Parent
>
338 void fromXML( Parent
*t
, const QDomElement
&e
)
340 static_cast<Derived
*>(this)->set(t
, variantTo
<Type
>(variantFromXML(e
)));
342 void toXML( const Parent
*t
, QDomElement
&e
)
344 variantToXML(QVariant(static_cast<Derived
*>(this)->get(t
)),e
);
348 //END convenience classes
350 } // namespace Properties
352 } // namespace Kopete