12 class List(Wbase
.SelectableWidget
):
14 """Standard list widget."""
18 def __init__(self
, possize
, items
= None, callback
= None, flags
= 0, cols
= 1, typingcasesens
=0):
22 Wbase
.SelectableWidget
.__init
__(self
, possize
)
27 self
._callback
= callback
29 self
.typingcasesens
= typingcasesens
31 self
.lasttime
= Evt
.TickCount()
37 self
.setdrawingmode(0)
39 self
.setdrawingmode(1)
46 rect
= rect
[0]+1, rect
[1]+1, rect
[2]-16, rect
[3]-1
47 self
._list
= List
.LNew(rect
, (0, 0, self
._cols
, 0), (0, 0), self
.LDEF_ID
, self
._parentwindow
.wid
,
50 self
._list
.LSetDrawingMode(0)
51 self
._list
.selFlags
= self
._flags
52 self
.setitems(self
.items
)
53 if hasattr(self
, "_sel"):
54 self
.setselection(self
._sel
)
57 def adjust(self
, oldbounds
):
60 self
.GetWindow().InvalWindowRect(Qd
.InsetRect(oldbounds
, -3, -3))
61 self
.GetWindow().InvalWindowRect(Qd
.InsetRect(self
._bounds
, -3, -3))
63 self
.GetWindow().InvalWindowRect(oldbounds
)
64 self
.GetWindow().InvalWindowRect(self
._bounds
)
65 if oldbounds
[:2] == self
._bounds
[:2]:
66 # set visRgn to empty, to prevent nasty drawing side effect of LSize()
67 Qd
.RectRgn(self
._parentwindow
.wid
.GetWindowPort().visRgn
, (0, 0, 0, 0))
68 # list still has the same upper/left coordinates, use LSize
69 l
, t
, r
, b
= self
._bounds
72 self
._list
.LSize(width
, height
)
73 # now *why* doesn't the list manager recalc the cellrect???
74 l
, t
, r
, b
= self
._list
.LRect((0,0))
76 self
._list
.LCellSize((width
, cellheight
))
78 self
._parentwindow
.wid
.CalcVis()
80 # oh well, since the list manager doesn't have a LMove call,
81 # we have to make the list all over again...
82 sel
= self
.getselection()
83 topcell
= self
.gettopcell()
85 self
.setdrawingmode(0)
87 self
.setselection(sel
)
88 self
.settopcell(topcell
)
89 self
.setdrawingmode(1)
95 Wbase
.SelectableWidget
.close(self
)
100 def setitems(self
, items
):
102 the_list
= self
._list
103 if not self
._parent
or not self
._list
:
105 self
.setdrawingmode(0)
106 topcell
= self
.gettopcell()
107 the_list
.LDelRow(0, 1)
108 the_list
.LAddRow(len(self
.items
), 0)
109 self_itemrepr
= self
.itemrepr
110 set_cell
= the_list
.LSetCell
111 for i
in range(len(items
)):
112 set_cell(self_itemrepr(items
[i
]), (0, i
))
113 self
.settopcell(topcell
)
114 self
.setdrawingmode(1)
116 def click(self
, point
, modifiers
):
117 if not self
._enabled
:
119 isdoubleclick
= self
._list
.LClick(point
, modifiers
)
121 Wbase
.CallbackCall(self
._callback
, 0, isdoubleclick
)
124 def key(self
, char
, event
):
125 (what
, message
, when
, where
, modifiers
) = event
126 sel
= self
.getselection()
128 if char
== Wkeys
.uparrowkey
:
129 if len(sel
) >= 1 and min(sel
) > 0:
130 newselection
= [min(sel
) - 1]
133 elif char
== Wkeys
.downarrowkey
:
134 if len(sel
) >= 1 and max(sel
) < (len(self
.items
) - 1):
135 newselection
= [max(sel
) + 1]
137 newselection
= [len(self
.items
) - 1]
140 if (self
.lasttime
+ self
.timelimit
) < Evt
.TickCount():
142 if self
.typingcasesens
:
143 self
.lasttyping
= self
.lasttyping
+ char
145 self
.lasttyping
= self
.lasttyping
+ string
.lower(char
)
146 self
.lasttime
= Evt
.TickCount()
147 i
= self
.findmatch(self
.lasttyping
)
149 if modifiers
& Events
.shiftKey
and not self
._list
.selFlags
& Lists
.lOnlyOne
:
150 newselection
= newselection
+ sel
151 self
.setselection(newselection
)
152 self
._list
.LAutoScroll()
153 self
.click((-1, -1), 0)
155 def findmatch(self
, tag
):
158 typingcasesens
= self
.typingcasesens
162 for i
in range(len(items
)):
164 if not typingcasesens
:
166 if tag
<= item
< match
:
172 return len(items
) - 1
174 def domenu_copy(self
, *args
):
175 sel
= self
.getselection()
178 selitems
.append(str(self
.items
[i
]))
179 text
= string
.join(selitems
, '\r')
182 Scrap
.PutScrap('TEXT', text
)
184 def can_copy(self
, *args
):
185 return len(self
.getselection()) <> 0
187 def domenu_selectall(self
, *args
):
190 def can_selectall(self
, *args
):
191 return not self
._list
.selFlags
& Lists
.lOnlyOne
194 if not self
._list
.selFlags
& Lists
.lOnlyOne
:
195 self
.setselection(range(len(self
.items
)))
196 self
._list
.LAutoScroll()
197 self
.click((-1, -1), 0)
199 def getselection(self
):
200 if not self
._parent
or not self
._list
:
201 if hasattr(self
, "_sel"):
207 ok
, point
= self
._list
.LGetSelect(1, point
)
210 items
.append(point
[1])
211 point
= point
[0], point
[1]+1
214 def setselection(self
, selection
):
215 if not self
._parent
or not self
._list
:
216 self
._sel
= selection
218 set_sel
= self
._list
.LSetSelect
219 for i
in range(len(self
.items
)):
224 self
._list
.LAutoScroll()
226 def getselectedobjects(self
):
227 sel
= self
.getselection()
230 objects
.append(self
.items
[i
])
233 def setselectedobjects(self
, objects
):
237 sel
.append(self
.items
.index(o
))
240 self
.setselection(sel
)
242 def gettopcell(self
):
243 l
, t
, r
, b
= self
._bounds
245 cl
, ct
, cr
, cb
= self
._list
.LRect((0, 0))
247 return (t
- ct
) / cellheight
249 def settopcell(self
, topcell
):
250 top
= self
.gettopcell()
252 self
._list
.LScroll(0, diff
)
254 def draw(self
, visRgn
= None):
257 visRgn
= self
._parentwindow
.wid
.GetWindowPort().visRgn
258 self
._list
.LUpdate(visRgn
)
259 Qd
.FrameRect(self
._bounds
)
260 if self
._selected
and self
._activated
:
263 def select(self
, onoff
, isclick
= 0):
264 if Wbase
.SelectableWidget
.select(self
, onoff
):
267 self
.drawselframe(onoff
)
269 def activate(self
, onoff
):
270 self
._activated
= onoff
272 self
._list
.LActivate(onoff
)
274 self
.drawselframe(onoff
)
279 def itemrepr(self
, item
):
280 return str(item
)[:255]
282 def __getitem__(self
, index
):
283 return self
.items
[index
]
285 def __setitem__(self
, index
, item
):
286 if self
._parent
and self
._list
:
287 self
._list
.LSetCell(self
.itemrepr(item
), (0, index
))
288 self
.items
[index
] = item
290 def __delitem__(self
, index
):
291 if self
._parent
and self
._list
:
292 self
._list
.LDelRow(1, index
)
293 del self
.items
[index
]
295 def __getslice__(self
, a
, b
):
296 return self
.items
[a
:b
]
298 def __delslice__(self
, a
, b
):
300 if self
._parent
and self
._list
:
301 self
._list
.LDelRow(b
-a
, a
)
304 def __setslice__(self
, a
, b
, items
):
305 if self
._parent
and self
._list
:
307 the_list
= self
._list
308 self
.setdrawingmode(0)
310 if b
> len(self
.items
):
311 # fix for new 1.5 "feature" where b is sys.maxint instead of len(self)...
312 # LDelRow doesn't like maxint.
314 the_list
.LDelRow(b
-a
, a
)
315 the_list
.LAddRow(l
, a
)
316 self_itemrepr
= self
.itemrepr
317 set_cell
= the_list
.LSetCell
318 for i
in range(len(items
)):
319 set_cell(self_itemrepr(items
[i
]), (0, i
+ a
))
320 self
.items
[a
:b
] = items
321 self
.setdrawingmode(1)
323 self
.items
[a
:b
] = items
326 return len(self
.items
)
328 def append(self
, item
):
329 if self
._parent
and self
._list
:
330 index
= len(self
.items
)
331 self
._list
.LAddRow(1, index
)
332 self
._list
.LSetCell(self
.itemrepr(item
), (0, index
))
333 self
.items
.append(item
)
335 def remove(self
, item
):
336 index
= self
.items
.index(item
)
337 self
.__delitem
__(index
)
339 def index(self
, item
):
340 return self
.items
.index(item
)
342 def insert(self
, index
, item
):
345 if self
._parent
and self
._list
:
346 self
._list
.LAddRow(1, index
)
347 self
._list
.LSetCell(self
.itemrepr(item
), (0, index
))
348 self
.items
.insert(index
, item
)
350 def setdrawingmode(self
, onoff
):
352 self
.drawingmode
= self
.drawingmode
- 1
353 if self
.drawingmode
== 0 and self
._list
is not None:
354 self
._list
.LSetDrawingMode(1)
356 bounds
= l
, t
, r
, b
= Qd
.InsetRect(self
._bounds
, 1, 1)
357 cl
, ct
, cr
, cb
= self
._list
.LRect((0, len(self
.items
)-1))
360 Qd
.EraseRect((l
, cb
, cr
, b
))
361 self
._list
.LUpdate(self
._parentwindow
.wid
.GetWindowPort().visRgn
)
362 self
.GetWindow().ValidWindowRect(bounds
)
364 if self
.drawingmode
== 0 and self
._list
is not None:
365 self
._list
.LSetDrawingMode(0)
366 self
.drawingmode
= self
.drawingmode
+ 1
369 class TwoLineList(List
):
373 def createlist(self
):
378 rect
= rect
[0]+1, rect
[1]+1, rect
[2]-16, rect
[3]-1
379 self
._list
= List
.LNew(rect
, (0, 0, 1, 0), (0, 28), self
.LDEF_ID
, self
._parentwindow
.wid
,
386 """Simple results window. The user cannot make this window go away completely:
387 closing it will just hide it. It will remain in the windows list. The owner of this window
388 should call the done() method to indicate it's done with it.
391 def __init__(self
, possize
=None, title
="Results", callback
=None):
395 self
.w
= W
.Window(possize
, title
, minsize
=(200, 100))
396 self
.w
.results
= W
.TwoLineList((-1, -1, 1, -14), callback
=None)
397 self
.w
.bind("<close>", self
.hide
)
403 if not self
.w
.isvisible():
411 def append(self
, msg
):
412 if not self
.w
.isvisible():
415 msg
= string
.replace(msg
, '\n', '\r')
416 self
.w
.results
.append(msg
)
417 self
.w
.results
.setselection([len(self
.w
.results
)-1])
419 def __getattr__(self
, attr
):
420 return getattr(self
.w
.results
, attr
)
423 class MultiList(List
):
425 """XXX Experimantal!!!"""
427 def setitems(self
, items
):
429 if not self
._parent
or not self
._list
:
431 self
._list
.LDelRow(0, 1)
432 self
.setdrawingmode(0)
433 self
._list
.LAddRow(len(self
.items
), 0)
434 self_itemrepr
= self
.itemrepr
435 set_cell
= self
._list
.LSetCell
436 for i
in range(len(items
)):
438 for j
in range(len(row
)):
440 set_cell(self_itemrepr(item
), (j
, i
))
441 self
.setdrawingmode(1)
443 def getselection(self
):
444 if not self
._parent
or not self
._list
:
445 if hasattr(self
, "_sel"):
451 ok
, point
= self
._list
.LGetSelect(1, point
)
454 items
.append(point
[1])
455 point
= point
[0], point
[1]+1
458 def setselection(self
, selection
):
459 if not self
._parent
or not self
._list
:
460 self
._sel
= selection
462 set_sel
= self
._list
.LSetSelect
463 for i
in range(len(self
.items
)):
468 #self._list.LAutoScroll()