Commit ddde3581 authored by Cédric Pasteur's avatar Cédric Pasteur
Browse files

Porting to trunk:

* Improved a little bit FactoryManager doc
* Added a better fix for the group item problem: now there's a label on top of group items, so we don't have to care about repainting the item (in fact it was much easier to implement than my first solution, and it's even better...)

svn path=/trunk/koffice/; revision=545530
parent ab2ea107
......@@ -57,6 +57,8 @@ class KOPROPERTY_EXPORT CustomProperty
virtual QVariant value() const = 0;
/*! Tells whether CustomProperty should be used to get the property's value.
CustomProperty::setValue() will always be called. But if hadleValue() == true,
then the value stored in the Property won't be changed.
You should return true for child properties, and false for others. */
virtual bool handleValue() const { return false; }
......
......@@ -36,6 +36,7 @@
#include <QApplication>
#include <QEventLoop>
#include <QTimer>
#include <QLabel>
//Added by qt3to4:
#include <QByteArray>
#include <QEvent>
......@@ -235,6 +236,7 @@ Editor::fill()
setCurrentItem(firstChild());
setSelected(firstChild(), true);
slotClicked(firstChild());
updateGroupLabelsPosition();
}
setUpdatesEnabled(true);
// aaah, call this instead of update() as explained here http://lists.trolltech.com/qt-interest/2000-06/thread00337-0.html
......@@ -679,6 +681,22 @@ Editor::updateEditorGeometry(EditorItem *item, Widget* widget,
qApp->processEvents(QEventLoop::AllEvents);
}
void
Editor::updateGroupLabelsPosition()
{
if(!d->topItem || d->itemDict.isEmpty())
return;
EditorGroupItem *group = dynamic_cast<EditorGroupItem*>(d->topItem->firstChild());
while(group) {
QRect r = itemRect((QListViewItem*) group);
r.setX(20);
if(group->label())
group->label()->setGeometry(r);
group = dynamic_cast<EditorGroupItem*>(group->nextSibling());
}
}
void
Editor::hideEditor()
{
......@@ -739,6 +757,7 @@ Editor::slotExpanded(Q3ListViewItem *item)
slotClicked(selectedItem());
}
updateEditorGeometry();
updateGroupLabelsPosition();
}
void
......@@ -760,6 +779,7 @@ Editor::slotCollapsed(Q3ListViewItem *item)
}
}
updateEditorGeometry();
updateGroupLabelsPosition();
}
void
......@@ -769,11 +789,11 @@ Editor::slotColumnSizeChanged(int section, int oldSize, int newSize)
Q_UNUSED(oldSize);
Q_UNUSED(newSize);
updateEditorGeometry();
for (Q3ListViewItemIterator it(this); it.current(); ++it) {
/*for (Q3ListViewItemIterator it(this); it.current(); ++it) {
// if (section == 0 && dynamic_cast<EditorGroupItem*>(it.current())) {
// it.current()->repaint();
// }
}
}*/
/*
if(d->currentWidget) {
if(section == 0)
......@@ -851,6 +871,7 @@ Editor::resizeEvent(QResizeEvent *ev)
if(d->undoButton->isVisible())
showUndoButton(true);
update();
updateGroupLabelsPosition();
}
bool
......@@ -930,6 +951,7 @@ Editor::updateFont()
showUndoButton(d->undoButton->isVisible());
updateEditorGeometry();
}
updateGroupLabelsPosition();
}
bool
......
......@@ -134,6 +134,7 @@ class KOPROPERTY_EXPORT Editor : public K3ListView
void updateEditorGeometry(bool forceUndoButtonSettings = false, bool undoButtonVisible = false);
void updateEditorGeometry(EditorItem *item, Widget* widget, bool forceUndoButtonSettings = false, bool undoButtonVisible = false);
void updateGroupLabelsPosition();
void hideEditor();
......
......@@ -29,6 +29,7 @@
#include <QPixmap>
#include <q3header.h>
#include <QStyle>
#include <QLabel>
#include <qstyleoption.h>
#ifdef QT_ONLY
......@@ -346,21 +347,27 @@ EditorItem::setHeight( int height )
//////////////////////////////////////////////////////
EditorGroupItem::EditorGroupItem(EditorItem *parent, const QString &text)
: EditorItem(parent, text)
: EditorItem(parent, text), m_label(0)
{
setOpen(true);
setSelectable(false);
m_label = new QLabel("<b>"+text+"</b>", listView()->viewport());
m_label->setBackgroundMode(Qt::PaletteBase);
m_label->show();
}
EditorGroupItem::~EditorGroupItem()
{}
{
delete m_label;
}
void
EditorGroupItem::paintCell(QPainter *p, const QColorGroup & cg, int column, int width, int /*align*/)
EditorGroupItem::paintCell(QPainter *p, const QColorGroup & cg, int column, int /*width*/, int /*align*/)
{
//no need to draw anything since there's a label on top of it
//if(column == 1)
// return;
p->setPen( KPROPEDITOR_ITEM_BORDER_COLOR ); //! \todo custom color?
/*p->setPen( KPROPEDITOR_ITEM_BORDER_COLOR ); //! \todo custom color?
p->setClipRect(listView()->itemRect(this));
if(column == 1)
......@@ -379,10 +386,10 @@ EditorGroupItem::paintCell(QPainter *p, const QColorGroup & cg, int column, int
QListViewItem::paintCell(p, cg, column, width, align);
#else
K3ListViewItem::paintCell(p, cg, column, width, align);
#endif*/
#endif
p->setPen(cg.text());
p->drawText(QRect(0,0, totalWidth, height()),
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, text(0));
+ Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, text(0));*/
}
void
......
......@@ -34,7 +34,7 @@
#define KPROPEDITOR_ITEM_BORDER_COLOR QColor(200,200,200) //! \todo custom color?
template<class U> class Q3AsciiDict;
class QLabel;
namespace KoProperty {
......@@ -96,10 +96,15 @@ class EditorGroupItem : public EditorItem
EditorGroupItem(EditorItem *parent, const QString &text);
virtual ~EditorGroupItem();
void setLabel(QLabel *label) { m_label = label; }
QLabel* label() { return m_label; }
protected:
/*! Reimplemented from K3ListViewItem to draw custom contents. */
virtual void paintCell(QPainter *p, const QColorGroup & cg, int column, int width, int align);
virtual void setup();
QLabel *m_label;
};
//! @internal
......
......@@ -23,8 +23,8 @@
#define KPROPERTY_FACTORY_H
#include "koproperty_global.h"
#include <kstaticdeleter.h>
#include <QObject>
#include <kstaticdeleter.h>
#include <QObject>
//Added by qt3to4:
#include <Q3ValueList>
......@@ -48,13 +48,13 @@ class KOPROPERTY_EXPORT CustomPropertyFactory : public QObject
CustomPropertyFactory(QObject *parent);
virtual ~CustomPropertyFactory();
/*! \return a new instance of custom property for \a parent.
Implement this for property types you want to support.
/*! \return a new instance of custom property for \a parent.
Implement this for property types you want to support.
Use parent->type() to get type of the property. */
virtual CustomProperty* createCustomProperty(Property *parent) = 0;
/*! \return a new instance of custom property for \a property.
Implement this for property editor types you want to support.
/*! \return a new instance of custom property for \a property.
Implement this for property editor types you want to support.
Use parent->type() to get type of the property. */
virtual Widget* createCustomWidget(Property *property) = 0;
};
......@@ -72,26 +72,42 @@ class KOPROPERTY_EXPORT CustomPropertyFactory : public QObject
\section custom_prop Using Custom Properties
To create a custom property, create a subclass of \ref CustomProperty class. You need to implement
some virtual functions, to customise the behaviour of your property
(see \ref CustomProperty api doc).
If you create a composed property, both parent and children properties must have custom
(different) types. \n
Then, you need to register the new created type, using \ref registerFactoryForProperty().
The second parameter is an instance of CustomPropertyFactory-derived class
implementing createCustomProperty() method.\n
To create a property of this type, just use the normal constructor, overriding
some virtual functions, to customise the behaviour of your property
(see \ref CustomProperty api doc).\n
Then, you need to register the new created type, using \ref registerFactoryForProperty().
The second parameter is an instance of CustomPropertyFactory-derived class
implementing CustomPropertyFactory::createCustomProperty() method.\n
To create a property of this type, just use the normal constructor, overriding
the type parameter with the type you registered.
\section custom_prop_composed Using Custom Properties to create composed properties
Use a composed property when you need more than one editor for a property. Examples
are rect, size or point properties.
If you create a composed property, both parent and children properties must have custom
(different) types.
Child properties are created in CustomProperty constructor of the <b>parent</b> type,
by adding CustomProperty::property() as parent in Property constructor.\n
Child properties should return handleValue() == true and in CustomProperty::setValue(),
parent's Property::setValue() should be called, making sure that useCustomProperty argument is set
to false.\n
Parent's handleValue() should be set to false, unless you cannot store the property in a QVariant.
You just need to update children's value, making sure that useCustomProperty argument is set
to false.
\section custom_editor Using Custom Editors
First, create a subclass of Widget, and implement all the virtuals you need to tweak
the property editor. You can find examples of editors in the src/editors/ directory.\n
Then, register it using \ref registerFactoryForEditor(), as for properties (see test/ dir
for an example of custom editor). You can also register a new editor for a basic type,
if the basic editor doesn't fit your needs (if you have created a better editor,
Then, register it using \ref registerFactoryForEditor(), as for properties (see test/ dir
for an example of custom editor). You can also override the editor provided by KoProperty,
if it doesn't fit your needs (if you have created a better editor,
send us the code, and it may get included in KProperty library).\n
Every time a property of this type is created, createCustomWidget() method for
the custom CustomPropertyFactory-derived factory object you registered will be called
to create the custom editor widget item.
To use your new editor, just create properties with the type number you registered using
\ref registerFactoryForEditor() . Your editor will automatically appear in the Editor.
\section custom_prop_composed Using Custom Properties with value that cannot be stored in a QVariant
You then need to set handleValue() to true. The Widget you create also have
to call directly CustomProperty member to store the value. just make sure you call emitPropertyChanged()
when the proerty value changes. Also make sure to avoid infinite recursion if you use children properties.
\author Cedric Pasteur <cedric.pasteur@free.fr>
\author Alexander Dymo <cloudtemple@mskat.net>
......@@ -100,8 +116,8 @@ class KOPROPERTY_EXPORT FactoryManager : public QObject
{
public:
/*! Registers a custom factory \a factory for handling property editor for \a editorType.
This custom factory will be used before defaults when widgetForProperty() is called.
\a creator is not owned by this Factory object, but it's good idea
This custom factory will be used before defaults when widgetForProperty() is called.
\a creator is not owned by this Factory object, but it's good idea
to instantiate CustomPropertyFactory object itself as a child of Factory parent. For example:
\code
MyCustomPropertyFactory *f = new MyCustomPropertyFactory(KoProperty::Factory::self());
......@@ -113,8 +129,8 @@ class KOPROPERTY_EXPORT FactoryManager : public QObject
@see registerFactoryForEditor(). */
void registerFactoryForEditors(const Q3ValueList<int> &editorTypes, CustomPropertyFactory *factory);
/*! \return custom factory for type \a type or NULL if there
is no such property type registered.
/*! \return custom factory for type \a type or NULL if there
is no such property type registered.
To create a custom widget createWidgetForProperty() should be rather used. */
CustomPropertyFactory *factoryForEditorType(int type);
......@@ -130,7 +146,7 @@ class KOPROPERTY_EXPORT FactoryManager : public QObject
/*! Registers a custom property factory that handles a CustomProperty for \a types.
@see registerFactoryForProperty() */
void registerFactoryForProperties(const Q3ValueList<int> &propertyTypes,
void registerFactoryForProperties(const Q3ValueList<int> &propertyTypes,
CustomPropertyFactory *factory);
/*! This function is called in Property::Property() to create (optional)
......
......@@ -43,6 +43,9 @@ template<class U> class Q3AsciiDictIterator;
KoProperty framework also supports adding custom property types
and custom property editor types using CustomPropertyFactory.
If you cannot store your value type in a QVariant, consider using composed properties
(see FactoryManager for more information) or storing it in CustomProperty yourself with handleValue()
set to true.
\author Cedric Pasteur <cedric.pasteur@free.fr>
\author Alexander Dymo <cloudtemple@mskat.net>
......@@ -59,7 +62,8 @@ class Set;
// const QStringList &keys, const QStringList &values);
/*! PropertyType.
Integers that represent the type of the property. */
Integers that represent the type of the property. Plugin defined properties
should have a type number >= UserDefined .*/
enum PropertyType {
//standard supported QVariant types
Auto = QVariant::Invalid - 1,
......@@ -141,11 +145,20 @@ enum PropertyType {
property = Property(name, value, caption, description); // name is a QCString,
// value is whatever type QVariant supports
// To create a list property
// To create a valueFromList property (matching strings with strings)
QStringList keys, strings;
keys << "one" << "two" << "three";
keys << "one" << "two" << "three"; // possible values of the property
// Strings (possibly i18n-ed) shown in the editor instead of the values
strings << i18n("One") << i18n("Two") << i18n("Three");
property = Property(name, keys, strings, "two", caption);
// To create a valueFromList property (matching strings with QVariant)
QValueList<QVariant> keys2;
keys2.append(1);
keys2.append(2);
keys2.append(3);
Property::ListData listData(keys2, strings);
m_set->addProperty(new Property("List2", listData, "otheritem", "List2"), group);
\endcode
Note that you need to use QVariant(bool, int) to create a boolean property value.
......
......@@ -51,7 +51,7 @@ Test::Test()
f.setPixelSize(f.pixelSize()*2/3);
setFont(f);
/* First, create the Set which will hold the properties. */
/* First, create the Set which will hold the properties. */
m_set = new Set(this, "test");
m_set->setReadOnly(readOnly);
Q3CString group;
......@@ -68,15 +68,19 @@ Test::Test()
m_set->addProperty(new Property("DateTime", QDateTime::currentDateTime(),"DateTime"), group);
QStringList list;//keys
list.append("myitem");
list.append("otheritem");
list.append("3rditem");
list << "myitem" << "otheritem" << "3rditem";
QStringList name_list; //strings
name_list.append("My Item");
name_list.append("Other Item");
name_list.append("Third Item");
name_list << "My Item" << "Other Item" << "Third Item";
m_set->addProperty(new Property("List", list, name_list, "otheritem", "List"), group);
// A valueFromList property matching strings with ints (could be any type supported by QVariant)
QValueList<QVariant> keys;
keys.append(1);
keys.append(2);
keys.append(3);
Property::ListData *listData = new Property::ListData(keys, name_list);
m_set->addProperty(new Property("List2", listData, "otheritem", "List2"), group);
// Complex
group = flat ? "" : "ComplexGroup";
m_set->addProperty(new Property("Rect", this->geometry(),"Rect"), group);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment