Teach Windows build and installer about new _symtable module/DLL.
[python/dscho.git] / Mac / Tools / IDE / Wlists.py
blobdd43a2d79813622ca59d801d8b43e4f9970bed90
1 import Wbase
2 import Wkeys
3 import Scrap
4 import string
5 import Evt
6 import Events
7 import Qd
8 import Win
9 import Lists
12 class List(Wbase.SelectableWidget):
14 """Standard list widget."""
16 LDEF_ID = 0
18 def __init__(self, possize, items = None, callback = None, flags = 0, cols = 1, typingcasesens=0):
19 if items is None:
20 items = []
21 self.items = items
22 Wbase.SelectableWidget.__init__(self, possize)
23 self._selected = 0
24 self._enabled = 1
25 self._list = None
26 self._cols = cols
27 self._callback = callback
28 self._flags = flags
29 self.typingcasesens = typingcasesens
30 self.lasttyping = ""
31 self.lasttime = Evt.TickCount()
32 self.timelimit = 30
33 self.setitems(items)
34 self.drawingmode = 0
36 def open(self):
37 self.setdrawingmode(0)
38 self.createlist()
39 self.setdrawingmode(1)
41 def createlist(self):
42 import List
43 self._calcbounds()
44 self.SetPort()
45 rect = self._bounds
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,
48 0, 1, 0, 1)
49 if self.drawingmode:
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)
55 del self._sel
57 def adjust(self, oldbounds):
58 self.SetPort()
59 if self._selected:
60 self.GetWindow().InvalWindowRect(Qd.InsetRect(oldbounds, -3, -3))
61 self.GetWindow().InvalWindowRect(Qd.InsetRect(self._bounds, -3, -3))
62 else:
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
70 width = r - l - 17
71 height = b - t - 2
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))
75 cellheight = b - t
76 self._list.LCellSize((width, cellheight))
77 # reset visRgn
78 self._parentwindow.wid.CalcVis()
79 else:
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()
84 self._list = None
85 self.setdrawingmode(0)
86 self.createlist()
87 self.setselection(sel)
88 self.settopcell(topcell)
89 self.setdrawingmode(1)
91 def close(self):
92 self._list = None
93 self._callback = None
94 self.items = []
95 Wbase.SelectableWidget.close(self)
97 def set(self, items):
98 self.setitems(items)
100 def setitems(self, items):
101 self.items = items
102 the_list = self._list
103 if not self._parent or not self._list:
104 return
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:
118 return
119 isdoubleclick = self._list.LClick(point, modifiers)
120 if self._callback:
121 Wbase.CallbackCall(self._callback, 0, isdoubleclick)
122 return 1
124 def key(self, char, event):
125 (what, message, when, where, modifiers) = event
126 sel = self.getselection()
127 newselection = []
128 if char == Wkeys.uparrowkey:
129 if len(sel) >= 1 and min(sel) > 0:
130 newselection = [min(sel) - 1]
131 else:
132 newselection = [0]
133 elif char == Wkeys.downarrowkey:
134 if len(sel) >= 1 and max(sel) < (len(self.items) - 1):
135 newselection = [max(sel) + 1]
136 else:
137 newselection = [len(self.items) - 1]
138 else:
139 modifiers = 0
140 if (self.lasttime + self.timelimit) < Evt.TickCount():
141 self.lasttyping = ""
142 if self.typingcasesens:
143 self.lasttyping = self.lasttyping + char
144 else:
145 self.lasttyping = self.lasttyping + string.lower(char)
146 self.lasttime = Evt.TickCount()
147 i = self.findmatch(self.lasttyping)
148 newselection = [i]
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):
156 lower = string.lower
157 items = self.items
158 typingcasesens = self.typingcasesens
159 taglen = len(tag)
160 match = '\377' * 100
161 match_i = -1
162 for i in range(len(items)):
163 item = str(items[i])
164 if not typingcasesens:
165 item = lower(item)
166 if tag <= item < match:
167 match = item
168 match_i = i
169 if match_i >= 0:
170 return match_i
171 else:
172 return len(items) - 1
174 def domenu_copy(self, *args):
175 sel = self.getselection()
176 selitems = []
177 for i in sel:
178 selitems.append(str(self.items[i]))
179 text = string.join(selitems, '\r')
180 if text:
181 Scrap.ZeroScrap()
182 Scrap.PutScrap('TEXT', text)
184 def can_copy(self, *args):
185 return len(self.getselection()) <> 0
187 def domenu_selectall(self, *args):
188 self.selectall()
190 def can_selectall(self, *args):
191 return not self._list.selFlags & Lists.lOnlyOne
193 def selectall(self):
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"):
202 return self._sel
203 return []
204 items = []
205 point = (0,0)
206 while 1:
207 ok, point = self._list.LGetSelect(1, point)
208 if not ok:
209 break
210 items.append(point[1])
211 point = point[0], point[1]+1
212 return items
214 def setselection(self, selection):
215 if not self._parent or not self._list:
216 self._sel = selection
217 return
218 set_sel = self._list.LSetSelect
219 for i in range(len(self.items)):
220 if i in selection:
221 set_sel(1, (0, i))
222 else:
223 set_sel(0, (0, i))
224 self._list.LAutoScroll()
226 def getselectedobjects(self):
227 sel = self.getselection()
228 objects = []
229 for i in sel:
230 objects.append(self.items[i])
231 return objects
233 def setselectedobjects(self, objects):
234 sel = []
235 for o in objects:
236 try:
237 sel.append(self.items.index(o))
238 except:
239 pass
240 self.setselection(sel)
242 def gettopcell(self):
243 l, t, r, b = self._bounds
244 t = t + 1
245 cl, ct, cr, cb = self._list.LRect((0, 0))
246 cellheight = cb - ct
247 return (t - ct) / cellheight
249 def settopcell(self, topcell):
250 top = self.gettopcell()
251 diff = topcell - top
252 self._list.LScroll(0, diff)
254 def draw(self, visRgn = None):
255 if self._visible:
256 if not visRgn:
257 visRgn = self._parentwindow.wid.GetWindowPort().visRgn
258 self._list.LUpdate(visRgn)
259 Qd.FrameRect(self._bounds)
260 if self._selected and self._activated:
261 self.drawselframe(1)
263 def select(self, onoff, isclick = 0):
264 if Wbase.SelectableWidget.select(self, onoff):
265 return
266 self.SetPort()
267 self.drawselframe(onoff)
269 def activate(self, onoff):
270 self._activated = onoff
271 if self._visible:
272 self._list.LActivate(onoff)
273 if self._selected:
274 self.drawselframe(onoff)
276 def get(self):
277 return self.items
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):
299 if b-a:
300 if self._parent and self._list:
301 self._list.LDelRow(b-a, a)
302 del self.items[a:b]
304 def __setslice__(self, a, b, items):
305 if self._parent and self._list:
306 l = len(items)
307 the_list = self._list
308 self.setdrawingmode(0)
309 if b-a:
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.
313 b = len(self.items)
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)
322 else:
323 self.items[a:b] = items
325 def __len__(self):
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):
343 if index < 0:
344 index = 0
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):
351 if onoff:
352 self.drawingmode = self.drawingmode - 1
353 if self.drawingmode == 0 and self._list is not None:
354 self._list.LSetDrawingMode(1)
355 if self._visible:
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))
358 if cb < b:
359 self.SetPort()
360 Qd.EraseRect((l, cb, cr, b))
361 self._list.LUpdate(self._parentwindow.wid.GetWindowPort().visRgn)
362 self.GetWindow().ValidWindowRect(bounds)
363 else:
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):
371 LDEF_ID = 468
373 def createlist(self):
374 import List
375 self._calcbounds()
376 self.SetPort()
377 rect = self._bounds
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,
380 0, 1, 0, 1)
381 self.set(self.items)
384 class ResultsWindow:
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):
392 import W
393 if possize is None:
394 possize = (500, 200)
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)
398 self.w.open()
399 self._done = 0
401 def done(self):
402 self._done = 1
403 if not self.w.isvisible():
404 self.w.close()
406 def hide(self):
407 if not self._done:
408 self.w.show(0)
409 return -1
411 def append(self, msg):
412 if not self.w.isvisible():
413 self.w.show(1)
414 self.w.select()
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):
428 self.items = items
429 if not self._parent or not self._list:
430 return
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)):
437 row = items[i]
438 for j in range(len(row)):
439 item = row[j]
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"):
446 return self._sel
447 return []
448 items = []
449 point = (0,0)
450 while 1:
451 ok, point = self._list.LGetSelect(1, point)
452 if not ok:
453 break
454 items.append(point[1])
455 point = point[0], point[1]+1
456 return items
458 def setselection(self, selection):
459 if not self._parent or not self._list:
460 self._sel = selection
461 return
462 set_sel = self._list.LSetSelect
463 for i in range(len(self.items)):
464 if i in selection:
465 set_sel(1, (0, i))
466 else:
467 set_sel(0, (0, i))
468 #self._list.LAutoScroll()