### 2.9.9 Other Proxy features

Proxies are complex and featureful beasts; this section discusses some additional details on them.

#### 2.9.9.1 Types

GTK+ treats most of the information in the interface as strings - its API usually takes data as strings, and it returns strings. However, this is a bit of a problem when dealing with an associated model, since the model may very well use integer, float or any other types internally.

For numeric types, Proxies have special support. On startup, the Proxy will look at the attached model and try and detect what attributes are numeric, by looking at their current values. Of course, if there is no value in the model, or it is a string, it will be assumed to be a string; however, if it is a number (float or integer) it will be remembered, and the Proxy will convert it from the GTK's internal string to a numeric type before sending it to the model. Note that this conversion is rather dumb and if invalid characters are used, exceptions will be raised (that's about it, though; the mainloop allows the application to go on running); use a validated Entry10 to avoid this problem.

For other types, you must convert from strings using getter and setter methods. If dealing with numeric types, you can also manually convert in the `set_*()` method and avoid any risks.

####
2.9.9.2 Formats

To avoid needing to provide accessors to deal with simple format conversions, Proxies provide a way to set Python format strings that will be applied to the attribute value when it is being applied to the widget. The syntax is: `proxy.set_format(attribute name, format string)` - the name is a string with the name of the attribute. You can pass a list of strings, optionally, to apply the same format string to multiple attributes.

Note that this does not apply to the data that is set to the model from the interface; it will be send without any conversion. Think of it as a simple, one-way filter for data sent from the model to the interface.

####
2.9.9.3 "Instant-apply" and Undo

The proxy can present something of a hazard for complex applications if its "instant-apply" model is not understood completely. Instant-apply means that, at any time, the UI and the model have the same state. If you pop up a dialog with a Proxy, and you alter the model, even before clicking "OK" the value in the model will have changed.

This may cause two classes of problems. The first is undoing the changes performed upon the model during manipulation of the Proxy (think "cancel button" if you are having a hard time imagining why). Solutions:

- One solution would be to store the initial state of the instance - `pickle` can probably be used for implementing this. If Undo is necessary, just reset the state of the model to the saved state. I have not yet tested this, but I think it would work.

- If you are using Zope.com's excellent database ZODB, you already have undo and rollback mechanisms in your persistent objects, and all you need to do is call the appropriate method and your model state is back to the previous state.

- Kiwi may at some point offer undo functionality, which would allow one to undo selectively changes done to the model in the Proxy. At the moment, this is just an idea, but I imagine it would not be hard to implement.

The second problem is using the model in another part of the application simultaneously (think "I am editing a price at the same time she is selling the product"). This problem can be aggravated when using multiple proxies attached to the same model. Solutions:

- You can offer a copy of your instance as the actual proxy instance, and upon finishing editing using the proxy (or upon "committing" the changes) you can transfer the state from the copy to the real instance. This way, the application continues using the real instance normally, and the proxy uses the copy without risking hard to the application itself.

- The Proxy could implement this solution internally, too; an idea would be a sort of GhostProxy, which had a `commit()` method which copied state automatically from the "ghost" to the real model.

(Yes, this part needs more research. I'll be looking into it.)

#### 2.9.9.4 Proxy startup values

When starting up a Proxy, the model attributes to be attached to the Proxy are analyzed and the initial state of the Proxy interface is set. The process by which this is performed is rather involved, and for the sake of completeness (debugging these things can be a bit tiresome), is listed here:

- If the model's attribute value is unset, and there is no accessor, the default value in the interface (specified in Glade or GTK previously to initializing the Proxy) is used and is set to the model attribute.
- If the instance variable is set but is `None`, the following defaults are used for each widget:
  - gtk.Entry, gtk.Label, gtk.Combo, gtk.Text, gtk.SpinButton: an empty string is set to the model, and a blank widget is presented.
  - gtk.RadioButton: The button set in Glade or GTK as initially on is selected, and if none is selected, the button that is most to the top and left of the Proxy interface is selected. The value associated with the radiobutton is set to the model attribute.
  - gtk.OptionMenu: the first item in the menu is selected, and its value is set to the model attribute.
  - gtk.ToggleButton and gtk.CheckButton: the widgets are set to unselected, and the model attribute is set to 0 (zero).

#### Footnotes

... Entry 10
  To be released in the next version of Kiwi, but some examples have been posted to pygtk-list