Quick update to the README file. For intros and books we now point to
[python/dscho.git] / Mac / scripts / MkDistr_ui.py
blobbabd156c5616ca346f87e6d73a167f57e9d10025
2 # MkDistr - User Interface.
4 # Jack Jansen, CWI, August 1995
6 # XXXX To be done (requires mods of FrameWork and toolbox interfaces too):
7 # - Give dialogs titles (need dlg->win conversion)
8 # - Place dialogs better (???)
9 # - <return> as <ok>
10 # - big box around ok button
11 # - window-close crashes on reopen (why?)
12 # - Box around lists (???)
13 # - Change cursor while busy (need cursor support in Qd)
15 import Res
16 import Dlg
17 import Ctl
18 import List
19 import Win
20 import Qd
21 from FrameWork import *
22 import EasyDialogs
23 import macfs
24 import os
25 import sys
27 # Resource IDs
28 ID_MAIN = 514
29 MAIN_LIST=1
30 MAIN_MKDISTR=2
31 MAIN_CHECK=3
32 MAIN_INCLUDE=4
33 MAIN_EXCLUDE=5
35 ID_INCWINDOW=515
36 ID_EXCWINDOW=517
37 INCEXC_DELETE=2
38 INCEXC_CHANGE=3
39 INCEXC_ADD=4
41 ID_INCLUDE=512
42 ID_EXCLUDE=513
43 DLG_OK=1 # Include for include, exclude for exclude
44 DLG_CANCEL=2
45 DLG_SRCPATH=3
46 DLG_DSTPATH=4 # include dialog only
47 DLG_EXCLUDE=5 # Exclude, include dialog only
49 ID_DTYPE=516
50 DTYPE_EXIST=1
51 DTYPE_NEW=2
52 DTYPE_CANCEL=3
54 class EditDialogWindow(DialogWindow):
55 """Include/exclude editor (modeless dialog window)"""
57 def open(self, id, (src, dst), callback, cancelrv):
58 self.id = id
59 self.callback = callback
60 self.cancelrv = cancelrv
61 DialogWindow.open(self, id)
62 tp, h, rect = self.wid.GetDialogItem(DLG_SRCPATH)
63 Dlg.SetDialogItemText(h, src)
64 self.wid.SetDialogDefaultItem(DLG_OK)
65 self.wid.SetDialogCancelItem(DLG_CANCEL)
66 if id == ID_INCLUDE:
67 tp, h, rect = self.wid.GetDialogItem(DLG_DSTPATH)
68 if dst == None:
69 dst = ''
70 Dlg.SetDialogItemText(h, dst)
71 self.wid.DrawDialog()
73 def do_itemhit(self, item, event):
74 if item in (DLG_OK, DLG_CANCEL, DLG_EXCLUDE):
75 self.done(item)
76 # else it is not interesting
78 def done(self, item):
79 tp, h, rect = self.wid.GetDialogItem(DLG_SRCPATH)
80 src = Dlg.GetDialogItemText(h)
81 if item == DLG_OK:
82 if self.id == ID_INCLUDE:
83 tp, h, rect = self.wid.GetDialogItem(DLG_DSTPATH)
84 dst = Dlg.GetDialogItemText(h)
85 rv = (src, dst)
86 else:
87 rv = (src, None)
88 elif item == DLG_EXCLUDE:
89 rv = (src, None)
90 else:
91 rv = self.cancelrv
92 self.close()
93 self.callback((item in (DLG_OK, DLG_EXCLUDE)), rv)
95 class ListWindow(DialogWindow):
96 """A dialog window containing a list as its main item"""
98 def open(self, id, contents):
99 self.id = id
100 DialogWindow.open(self, id)
101 Qd.SetPort(self.wid)
102 tp, h, rect = self.wid.GetDialogItem(MAIN_LIST)
103 self.listrect = rect
104 rect2 = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-16 # Scroll bar space
105 self.list = List.LNew(rect2, (0, 0, 1, len(contents)), (0,0), 0, self.wid,
106 0, 1, 1, 1)
107 self.setlist(contents)
109 def setlist(self, contents):
110 self.list.LDelRow(0, 0)
111 self.list.LSetDrawingMode(0)
112 if contents:
113 self.list.LAddRow(len(contents), 0)
114 for i in range(len(contents)):
115 self.list.LSetCell(contents[i], (0, i))
116 self.list.LSetDrawingMode(1)
117 ##self.list.LUpdate(self.wid.GetWindowPort().visRgn)
118 Win.InvalRect(self.listrect)
120 def additem(self, item):
121 where = self.list.LAddRow(1, 0)
122 self.list.LSetCell(item, (0, where))
124 def delgetitem(self, item):
125 data = self.list.LGetCell(1000, (0, item))
126 self.list.LDelRow(1, item)
127 return data
129 def do_listhit(self, event):
130 (what, message, when, where, modifiers) = event
131 Qd.SetPort(self.wid)
132 where = Qd.GlobalToLocal(where)
133 if self.list.LClick(where, modifiers):
134 self.do_dclick(self.delgetselection())
136 def delgetselection(self):
137 items = []
138 point = (0,0)
139 while 1:
140 ok, point = self.list.LGetSelect(1, point)
141 if not ok:
142 break
143 items.append(point[1])
144 point = point[0], point[1]+1
145 values = []
146 items.reverse()
147 for i in items:
148 values.append(self.delgetitem(i))
149 return values
151 def do_rawupdate(self, window, event):
152 Qd.SetPort(window)
153 Qd.FrameRect(self.listrect)
154 self.list.LUpdate(self.wid.GetWindowPort().visRgn)
156 def do_close(self):
157 self.close()
159 def close(self):
160 del self.list
161 DialogWindow.close(self)
163 def mycb_add(self, ok, item):
164 if item:
165 self.additem(item[0])
166 self.cb_add(item)
168 class MainListWindow(ListWindow):
169 """The main window"""
171 def open(self, id, cb_check, cb_run, cb_add):
172 ListWindow.open(self, id, [])
173 self.wid.SetDialogDefaultItem(MAIN_INCLUDE)
174 self.cb_run = cb_run
175 self.cb_check = cb_check
176 self.cb_add = cb_add
177 setwatchcursor()
178 list = self.cb_check()
179 self.setlist(list)
180 setarrowcursor()
182 def do_itemhit(self, item, event):
183 if item == MAIN_LIST:
184 self.do_listhit(event)
185 if item == MAIN_MKDISTR:
186 ## XXXX Why doesn't this work??!?!?
187 ## fss, ok = macfs.StandardPutFile('Destination folder?')
188 ## if not ok:
189 ## return
190 ## dest = fss.as_pathname()
191 dest = os.path.join(os.getcwd(), 'Distribution')
192 setwatchcursor()
193 self.cb_run(dest)
194 setarrowcursor()
195 if item == MAIN_CHECK:
196 setwatchcursor()
197 list = self.cb_check()
198 self.setlist(list)
199 setarrowcursor()
200 if item == MAIN_INCLUDE:
201 self.do_dclick(self.delgetselection())
202 if item == MAIN_EXCLUDE:
203 for i in self.delgetselection():
204 self.cb_add((i, None))
206 def do_dclick(self, list):
207 if not list:
208 list = ['']
209 for l in list:
210 w = EditDialogWindow(self.parent)
211 w.open(ID_INCLUDE, (l, None), self.mycb_add, None)
213 def mycb_add(self, ok, item):
214 if item:
215 self.cb_add(item)
217 class IncListWindow(ListWindow):
218 """An include/exclude window"""
219 def open(self, id, editid, contents, cb_add, cb_del, cb_get):
220 ListWindow.open(self, id, contents)
221 self.wid.SetDialogDefaultItem(INCEXC_CHANGE)
222 self.editid = editid
223 self.cb_add = cb_add
224 self.cb_del = cb_del
225 self.cb_get = cb_get
227 def do_itemhit(self, item, event):
228 if item == MAIN_LIST:
229 self.do_listhit(event)
230 if item == INCEXC_DELETE:
231 old = self.delgetselection()
232 for i in old:
233 self.cb_del(i)
234 if item == INCEXC_CHANGE:
235 self.do_dclick(self.delgetselection())
236 if item == INCEXC_ADD:
237 w = EditDialogWindow(self.parent)
238 w.open(self.editid, ('', None), self.mycb_add, None)
240 def do_dclick(self, list):
241 if not list:
242 list = ['']
243 for l in list:
244 old = self.cb_get(l)
245 self.cb_del(l)
246 w = EditDialogWindow(self.parent)
247 w.open(self.editid, old, self.mycb_add, old)
249 class MkDistrUI(Application):
250 def __init__(self, main):
251 self.main = main
252 Application.__init__(self)
253 self.mwin = MainListWindow(self)
254 self.mwin.open(ID_MAIN, self.main.check, self.main.run, self.main.inc.add)
255 self.iwin = None
256 self.ewin = None
258 def makeusermenus(self):
259 self.filemenu = m = Menu(self.menubar, "File")
260 self.includeitem = MenuItem(m, "Show Include window", "", self.showinc)
261 self.excludeitem = MenuItem(m, "Show Exclude window", "", self.showexc)
262 self.saveitem = MenuItem(m, "Save databases", "S", self.save)
263 self.quititem = MenuItem(m, "Quit", "Q", self.quit)
265 def quit(self, *args):
266 if self.main.is_modified():
267 rv = EasyDialogs.AskYesNoCancel('Database modified. Save?', -1)
268 if rv == -1:
269 return
270 if rv == 1:
271 self.main.save()
272 raise self
274 def save(self, *args):
275 self.main.save()
277 def showinc(self, *args):
278 if self.iwin:
279 if self._windows.has_key(self.iwin):
280 self.iwin.close()
281 del self.iwin
282 self.iwin = IncListWindow(self)
283 self.iwin.open(ID_INCWINDOW, ID_INCLUDE, self.main.inc.getall(), self.main.inc.add,
284 self.main.inc.delete, self.main.inc.get)
286 def showexc(self, *args):
287 if self.ewin:
288 if self._windows.has_key(self.ewin):
289 self.ewin.close()
290 del self.ewin
291 self.ewin = IncListWindow(self)
292 self.ewin.open(ID_EXCWINDOW, ID_EXCLUDE, self.main.exc.getall(), self.main.exc.add,
293 self.main.exc.delete, self.main.exc.get)
295 def do_about(self, id, item, window, event):
296 EasyDialogs.Message("Test the MkDistr user interface.")
298 def GetType():
299 """Ask user for distribution type"""
300 while 1:
301 d = Dlg.GetNewDialog(ID_DTYPE, -1)
302 d.SetDialogDefaultItem(DTYPE_EXIST)
303 d.SetDialogCancelItem(DTYPE_CANCEL)
304 while 1:
305 rv = ModalDialog(None)
306 if rv in (DTYPE_EXIST, DTYPE_NEW, DTYPE_CANCEL):
307 break
308 del d
309 if rv == DTYPE_CANCEL:
310 sys.exit(0)
311 if rv == DTYPE_EXIST:
312 ## macfs.SetFolder(':(MkDistr)')
313 fss, ok = macfs.StandardGetFile('TEXT')
314 if not ok:
315 sys.exit(0)
316 path = fss.as_pathname()
317 basename = os.path.split(path)[-1]
318 if basename[-8:] <> '.include':
319 EasyDialogs.Message('That is not a distribution include file')
320 else:
321 return basename[:-8]
322 else:
323 name = EasyDialogs.AskString('Distribution name:')
324 if name:
325 return name
326 sys.exit(0)
328 def InitUI():
329 """Initialize stuff needed by UI (a resource file)"""
330 Res.OpenResFile('MkDistr.rsrc')
332 class _testerhelp:
333 def __init__(self, which):
334 self.which = which
336 def get(self):
337 return [self.which+'-one', self.which+'-two']
339 def add(self, value):
340 if value:
341 print 'ADD', self.which, value
343 def delete(self, value):
344 print 'DEL', self.which, value
346 class _test:
347 def __init__(self):
348 import sys
349 Res.OpenResFile('MkDistr.rsrc')
350 self.inc = _testerhelp('include')
351 self.exc = _testerhelp('exclude')
352 self.ui = MkDistrUI(self)
353 self.ui.mainloop()
354 sys.exit(1)
356 def check(self):
357 print 'CHECK'
358 return ['rv1', 'rv2']
360 def run(self):
361 print 'RUN'
363 if __name__ == '__main__':
364 _test()