Skip to content

The generic approach to property editing

Monday, 16 February 2004  |  Adymo

Last time I worked on Kugar Report Designer I've noticed that I need to have a property editor similar to what Qt Designer have. Further I've discovered that such a property editor can also be usefull in KDevelop. Existing implementations were too tied with Kugar Designer and Qt Designer and Qt Designer's version was GPL'ed. So I decided to wrote my own "generic" property editing library (partially based on my property editing classes from Kugar) which I'm happy to present.
The core of the library is formed by Property, PropertyList and PropertyEditor classes.
Property has name, value (stored in QVariant), description and a list of possible values. Library supports (i.e. provides facilities to edit them visually) several property types by default: String, Integer, Double, Boolean, StringList, Color, List, Map, ValueFromList, Symbol and FontName.
Class PropertyList is a way to store properties together. It is worth to mention that properties can also be grouped into a smaller lists within property list. For example, such properties as "x", "y", "width" and "height" can be grouped into "Geometry" group.
Your object should include a PropertyList. This way it is simple to pass the list to PropertyEditor and display them in GUI. PropertyEditor cares about displaying a grouped list of properties and creating property editor widgets when necessary.
Sometimes there is a selection of objects in program and you want to display properties of those objects. You can't simply pass a list of properties to a property editor, you should "intersect" them first and pass only properties that are common to all objects. Property editing library takes care about this too. Property lists can be intersected and the result of intersection can be passed to PropertyEditor.
The use of properties and lists can be illustrated by this example:

    PropertyEditor *editor = new PropertyEditor(this);
    
    PropertyList *list = new PropertyList;
    list->addProperty("My Group", new Property(Integer, "First Property",
        "This is my first property", -5));
    list->addProperty("My Group", new Property(String, "Second Property",
        "This is my second property", "Hello"));
    list->addProperty(new Property(Color, "Third Property",
        "This is my third property", QColor("green")));
        
    editor->populateProperties(*list);

Screenshot of property editor with list displayed:

More advanced example with list intersection:

    PropertyEditor *editor = new PropertyEditor(this);
    
    PropertyList *list = new PropertyList;
    list->addProperty("My Group", new Property(Integer, "First Property",
        "This is my first property", -5));
    list->addProperty("My Group", new Property(String, "Second Property",
        "This is my second property", "Hello"));
    list->addProperty(new Property(Color, "Third Property",
        "This is my third property", QColor("green")));

    PropertyList *list2 = new PropertyList;
    list2->addProperty("My Group", new Property(Integer, "First Property",
        "This is my first property", -7));
    list2->addProperty("My Group", new Property(String, "Second Property",
        "This is my second property", "Hello"));
    list2->addProperty(new Property(String, "Third Property",
        "This is my third property", "green"));

    PropertyAccessor *ac = list->intersect(*list2);
    
    editor->populateProperties(ac);

In this example only properties named "First Property" and "Second Property" will be shown in editor. "Third Property" has different type in list and list2 and will not be included in intersection.

Property editing library was designed with extensibility in mind. You can create properties with custom type or even subclass Property class. If you do so, you also need to register a "Machine" in PropertyMachineFactory to create property editor widgets for that custom property type. Library provides editor widgets for all predefined types. For example, QLineEdit widget is used as an editor for String type, KColorCombo - for Color type. You can either use predefined widgets or create custom by subclassing abstract PropertyWidget class and implementing it's methods.

You can find library in KDevelop cvs, module kdevelop/lib/widgets/propeditor or a tarball at my homepage: http://www.cloudtemple.mksat.net/propeditor.tar.bz2