File: undo.html

package info (click to toggle)
kiwi 1.9.22-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd, squeeze, wheezy
  • size: 11,912 kB
  • ctags: 5,549
  • sloc: python: 15,779; ansic: 193; xml: 77; makefile: 57; sh: 18
file content (289 lines) | stat: -rw-r--r-- 10,716 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<link rel="STYLESHEET" href="howto.css" type='text/css' />
<link rel="first" href="howto.html" title='Developing applications with Kiwi' />
<link rel='last' href='about.html' title='About this document...' />
<link rel='help' href='about.html' title='About this document...' />
<link rel="prev" href="multipleproxies.html" />
<link rel="parent" href="node16.html" />
<link rel="next" href="node26.html" />
<meta name='aesop' content='information' />
<title>2.9.9 Other Proxy features</title>
</head>
<body>
<DIV CLASS="navigation">
<div id='top-navigation-panel' xml:id='top-navigation-panel'>
<table align="center" width="100%" cellpadding="0" cellspacing="2">
<tr>
<td class='online-navigation'><a rel="prev" title="2.9.8 Multiple Proxies"
  href="multipleproxies.html"><img src='previous.png'
  border='0' height='32'  alt='Previous Page' width='32' /></A></td>
<td class='online-navigation'><a rel="parent" title="2.9 Proxies and Models"
  href="node16.html"><img src='up.png'
  border='0' height='32'  alt='Up One Level' width='32' /></A></td>
<td class='online-navigation'><a rel="next" title="3 Widgets"
  href="node26.html"><img src='next.png'
  border='0' height='32'  alt='Next Page' width='32' /></A></td>
<td align="center" width="100%">Developing applications with Kiwi</td>
<td class='online-navigation'><img src='blank.png'
  border='0' height='32'  alt='' width='32' /></td>
<td class='online-navigation'><img src='blank.png'
  border='0' height='32'  alt='' width='32' /></td>
<td class='online-navigation'><img src='blank.png'
  border='0' height='32'  alt='' width='32' /></td>
</tr></table>
<div class='online-navigation'>
<b class="navlabel">Previous:</b>
<a class="sectref" rel="prev" href="multipleproxies.html">2.9.8 Multiple Proxies</A>
<b class="navlabel">Up:</b>
<a class="sectref" rel="parent" href="node16.html">2.9 Proxies and Models</A>
<b class="navlabel">Next:</b>
<a class="sectref" rel="next" href="node26.html">3 Widgets</A>
</div>
<hr /></div>
</DIV>
<!--End of Navigation Panel-->
<div class='online-navigation'>
<!--Table of Child-Links-->
<A NAME="CHILD_LINKS"><STRONG>Subsections</STRONG></a>

<UL CLASS="ChildLinks">
<LI><A href="undo.html#SECTION000299100000000000000">2.9.9.1 Types</a>
<LI><A href="undo.html#SECTION000299200000000000000">2.9.9.2 Formats</a>
<LI><A href="undo.html#SECTION000299300000000000000">2.9.9.3 "Instant-apply" and Undo</a>
<LI><A href="undo.html#SECTION000299400000000000000">2.9.9.4 Proxy startup values</a>
</ul>
<!--End of Table of Child-Links-->
</div>
<HR>

<H3><A NAME="SECTION000299000000000000000">
2.9.9 Other Proxy features</A>
</H3>

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

<P>

<H4><A NAME="SECTION000299100000000000000">
2.9.9.1 Types</A>
</H4>

<P>
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.

<P>
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 Entry<A NAME="tex2html10"
  HREF="#foot427"><SUP>10</SUP></A> to avoid this problem.

<P>
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 <code>set_*()</code> method and avoid any risks.

<P>

<H4><A NAME="SECTION000299200000000000000"></A>
<A NAME="formats"></A>
<BR>
2.9.9.2 Formats
</H4>

<P>
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: <code>proxy.set_format(<I>attribute name</I>,
<I>format string</I>)</code> - 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.

<P>
Note that this does <I>not</I> apply to the data that is set <I>to</I> 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.

<P>

<H4><A NAME="SECTION000299300000000000000"></A>
<A NAME="undo"></A>
<BR>
2.9.9.3 "Instant-apply" and Undo
</H4>

<P>
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.

<P>
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:

<P>

<UL>
<LI>One solution would be to store the initial state of the instance -
<tt class="module">pickle</tt> 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.

<P>
</LI>
<LI>If you are using Zope.com's <I>excellent</I> database
<em class="citetitle"><a
 href="http://www.amk.ca/zodb/"
 title="ZODB"
 >ZODB</a></em>, 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.

<P>
</LI>
<LI>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.
</LI>
</UL>

<P>
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:

<P>

<UL>
<LI>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.

<P>
</LI>
<LI>The Proxy could implement this solution internally, too; an idea
would be a sort of GhostProxy, which had a <code>commit()</code> method which
copied state automatically from the "ghost" to the real model.
</LI>
</UL>

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

<P>

<H4><A NAME="SECTION000299400000000000000">
2.9.9.4 Proxy startup values</A>
</H4>

<P>
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:

<P>

<UL>
<LI>If the model's attribute value is <B>unset</B>, and there is no
accessor, the default value in the interface (specified in Glade or GTK
previously to initializing the Proxy) is used <I>and is set to the
model attribute</I>.
</LI>
<LI>If the instance variable is set but is <code>None</code>, the following
defaults are used for each widget:
    
<UL>
<LI><B>gtk.Entry, gtk.Label, gtk.Combo, gtk.Text, gtk.SpinButton</B>: an
    empty string is set to the model, and a blank widget is presented.
</LI>
<LI><B>gtk.RadioButton</B>: 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.
</LI>
<LI><B>gtk.OptionMenu</B>: the first item in the menu is selected, and
    its value is set to the model attribute.
</LI>
<LI><B>gtk.ToggleButton and gtk.CheckButton</B>: the widgets are set
    to unselected, and the model attribute is set to 0 (zero).
    
</LI>
</UL>
</LI>
</UL>

<P>
<BR><HR><H4>Footnotes</H4>
<DL>
<DT><A NAME="foot427">... Entry</A><A
 href="undo.html#tex2html10"><SUP>10</SUP></A></DT>
<DD>To be
released in the next version of Kiwi, but some examples have been posted
to pygtk-list

</DD>
</DL>
<DIV CLASS="navigation">
<div class='online-navigation'>
<p></p><hr />
<table align="center" width="100%" cellpadding="0" cellspacing="2">
<tr>
<td class='online-navigation'><a rel="prev" title="2.9.8 Multiple Proxies"
  href="multipleproxies.html"><img src='previous.png'
  border='0' height='32'  alt='Previous Page' width='32' /></A></td>
<td class='online-navigation'><a rel="parent" title="2.9 Proxies and Models"
  href="node16.html"><img src='up.png'
  border='0' height='32'  alt='Up One Level' width='32' /></A></td>
<td class='online-navigation'><a rel="next" title="3 Widgets"
  href="node26.html"><img src='next.png'
  border='0' height='32'  alt='Next Page' width='32' /></A></td>
<td align="center" width="100%">Developing applications with Kiwi</td>
<td class='online-navigation'><img src='blank.png'
  border='0' height='32'  alt='' width='32' /></td>
<td class='online-navigation'><img src='blank.png'
  border='0' height='32'  alt='' width='32' /></td>
<td class='online-navigation'><img src='blank.png'
  border='0' height='32'  alt='' width='32' /></td>
</tr></table>
<div class='online-navigation'>
<b class="navlabel">Previous:</b>
<a class="sectref" rel="prev" href="multipleproxies.html">2.9.8 Multiple Proxies</A>
<b class="navlabel">Up:</b>
<a class="sectref" rel="parent" href="node16.html">2.9 Proxies and Models</A>
<b class="navlabel">Next:</b>
<a class="sectref" rel="next" href="node26.html">3 Widgets</A>
</div>
</div>
<hr />
<span class="release-info">Release 1.9.22, documentation updated on August, 2006.</span>
</DIV>
<!--End of Navigation Panel-->

</BODY>
</HTML>