blob: 6c9f0f60537f2caca35a54fdf6fb7a8516a1acd2 [file] [log] [blame]
Jack Jansenc9c99f21995-08-31 13:50:16 +00001#
2# MkDistr - User Interface.
3#
4# Jack Jansen, CWI, August 1995
5#
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)
14#
15import Res
16import Dlg
17import Ctl
18import List
19import Win
20import Qd
21from FrameWork import *
22import EasyDialogs
23import macfs
Jack Jansen86288971996-08-28 14:18:58 +000024import os
25import sys
Jack Jansenc9c99f21995-08-31 13:50:16 +000026
27# Resource IDs
28ID_MAIN = 514
29MAIN_LIST=1
30MAIN_MKDISTR=2
31MAIN_CHECK=3
32MAIN_INCLUDE=4
33MAIN_EXCLUDE=5
34
Jack Jansen86288971996-08-28 14:18:58 +000035ID_INCWINDOW=515
36ID_EXCWINDOW=517
Jack Jansenc9c99f21995-08-31 13:50:16 +000037INCEXC_DELETE=2
38INCEXC_CHANGE=3
39INCEXC_ADD=4
40
41ID_INCLUDE=512
42ID_EXCLUDE=513
Jack Jansen86288971996-08-28 14:18:58 +000043DLG_OK=1 # Include for include, exclude for exclude
Jack Jansenc9c99f21995-08-31 13:50:16 +000044DLG_CANCEL=2
Jack Jansen86288971996-08-28 14:18:58 +000045DLG_SRCPATH=3
46DLG_DSTPATH=4 # include dialog only
47DLG_EXCLUDE=5 # Exclude, include dialog only
Jack Jansenc9c99f21995-08-31 13:50:16 +000048
49ID_DTYPE=516
Jack Jansen86288971996-08-28 14:18:58 +000050DTYPE_EXIST=1
51DTYPE_NEW=2
52DTYPE_CANCEL=3
Jack Jansenc9c99f21995-08-31 13:50:16 +000053
54class EditDialogWindow(DialogWindow):
55 """Include/exclude editor (modeless dialog window)"""
56
Jack Jansen86288971996-08-28 14:18:58 +000057 def open(self, id, (src, dst), callback, cancelrv):
Jack Jansenc9c99f21995-08-31 13:50:16 +000058 self.id = id
Jack Jansenc9c99f21995-08-31 13:50:16 +000059 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)
Jack Jansen86288971996-08-28 14:18:58 +000064 self.wid.SetDialogDefaultItem(DLG_OK)
65 self.wid.SetDialogCancelItem(DLG_CANCEL)
Jack Jansenc9c99f21995-08-31 13:50:16 +000066 if id == ID_INCLUDE:
67 tp, h, rect = self.wid.GetDialogItem(DLG_DSTPATH)
Jack Jansen86288971996-08-28 14:18:58 +000068 if dst == None:
69 dst = ''
Jack Jansenc9c99f21995-08-31 13:50:16 +000070 Dlg.SetDialogItemText(h, dst)
Jack Jansen86288971996-08-28 14:18:58 +000071 self.wid.DrawDialog()
Jack Jansenc9c99f21995-08-31 13:50:16 +000072
73 def do_itemhit(self, item, event):
Jack Jansen86288971996-08-28 14:18:58 +000074 if item in (DLG_OK, DLG_CANCEL, DLG_EXCLUDE):
Jack Jansenc9c99f21995-08-31 13:50:16 +000075 self.done(item)
Jack Jansenc9c99f21995-08-31 13:50:16 +000076 # else it is not interesting
77
78 def done(self, item):
Jack Jansen86288971996-08-28 14:18:58 +000079 tp, h, rect = self.wid.GetDialogItem(DLG_SRCPATH)
80 src = Dlg.GetDialogItemText(h)
Jack Jansenc9c99f21995-08-31 13:50:16 +000081 if item == DLG_OK:
Jack Jansenc9c99f21995-08-31 13:50:16 +000082 if self.id == ID_INCLUDE:
83 tp, h, rect = self.wid.GetDialogItem(DLG_DSTPATH)
84 dst = Dlg.GetDialogItemText(h)
Jack Jansen86288971996-08-28 14:18:58 +000085 rv = (src, dst)
Jack Jansenc9c99f21995-08-31 13:50:16 +000086 else:
Jack Jansen86288971996-08-28 14:18:58 +000087 rv = (src, None)
88 elif item == DLG_EXCLUDE:
89 rv = (src, None)
Jack Jansenc9c99f21995-08-31 13:50:16 +000090 else:
91 rv = self.cancelrv
92 self.close()
Jack Jansen86288971996-08-28 14:18:58 +000093 self.callback((item in (DLG_OK, DLG_EXCLUDE)), rv)
Jack Jansenc9c99f21995-08-31 13:50:16 +000094
95class ListWindow(DialogWindow):
96 """A dialog window containing a list as its main item"""
97
98 def open(self, id, contents):
99 self.id = id
100 DialogWindow.open(self, id)
Jack Jansen86288971996-08-28 14:18:58 +0000101 Qd.SetPort(self.wid)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000102 tp, h, rect = self.wid.GetDialogItem(MAIN_LIST)
Jack Jansen86288971996-08-28 14:18:58 +0000103 self.listrect = rect
104 rect2 = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-16 # Scroll bar space
Jack Jansenc9c99f21995-08-31 13:50:16 +0000105 self.list = List.LNew(rect2, (0, 0, 1, len(contents)), (0,0), 0, self.wid,
106 0, 1, 1, 1)
107 self.setlist(contents)
108
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)
Jack Jansen86288971996-08-28 14:18:58 +0000117 ##self.list.LUpdate(self.wid.GetWindowPort().visRgn)
118 Win.InvalRect(self.listrect)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000119
120 def additem(self, item):
121 where = self.list.LAddRow(1, 0)
122 self.list.LSetCell(item, (0, where))
123
124 def delgetitem(self, item):
125 data = self.list.LGetCell(1000, (0, item))
126 self.list.LDelRow(1, item)
127 return data
128
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())
135
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
150
151 def do_rawupdate(self, window, event):
Jack Janseneba88561996-04-12 16:34:58 +0000152 Qd.SetPort(window)
Jack Jansen86288971996-08-28 14:18:58 +0000153 Qd.FrameRect(self.listrect)
Jack Jansen822a30b1996-04-10 14:52:18 +0000154 self.list.LUpdate(self.wid.GetWindowPort().visRgn)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000155
156 def do_close(self):
157 self.close()
158
159 def close(self):
160 del self.list
161 DialogWindow.close(self)
162
163 def mycb_add(self, ok, item):
164 if item:
Jack Jansen86288971996-08-28 14:18:58 +0000165 self.additem(item[0])
Jack Jansenc9c99f21995-08-31 13:50:16 +0000166 self.cb_add(item)
167
168class MainListWindow(ListWindow):
169 """The main window"""
170
171 def open(self, id, cb_check, cb_run, cb_add):
172 ListWindow.open(self, id, [])
Jack Jansen86288971996-08-28 14:18:58 +0000173 self.wid.SetDialogDefaultItem(ID_INCLUDE)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000174 self.cb_run = cb_run
175 self.cb_check = cb_check
176 self.cb_add = cb_add
Jack Jansen86288971996-08-28 14:18:58 +0000177 setwatchcursor()
178 list = self.cb_check()
179 self.setlist(list)
180 setarrowcursor()
Jack Jansenc9c99f21995-08-31 13:50:16 +0000181
182 def do_itemhit(self, item, event):
183 if item == MAIN_LIST:
184 self.do_listhit(event)
185 if item == MAIN_MKDISTR:
Jack Jansen6f69c501997-05-23 15:41:15 +0000186## XXXX Why doesn't this work??!?!?
187## fss, ok = macfs.StandardPutFile('Destination folder?')
Jack Jansen86288971996-08-28 14:18:58 +0000188## 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()
Jack Jansenc9c99f21995-08-31 13:50:16 +0000195 if item == MAIN_CHECK:
Jack Jansen86288971996-08-28 14:18:58 +0000196 setwatchcursor()
Jack Jansenc9c99f21995-08-31 13:50:16 +0000197 list = self.cb_check()
198 self.setlist(list)
Jack Jansen86288971996-08-28 14:18:58 +0000199 setarrowcursor()
Jack Jansenc9c99f21995-08-31 13:50:16 +0000200 if item == MAIN_INCLUDE:
201 self.do_dclick(self.delgetselection())
202 if item == MAIN_EXCLUDE:
203 for i in self.delgetselection():
Jack Jansen86288971996-08-28 14:18:58 +0000204 self.cb_add((i, None))
Jack Jansenc9c99f21995-08-31 13:50:16 +0000205
206 def do_dclick(self, list):
207 if not list:
208 list = ['']
209 for l in list:
210 w = EditDialogWindow(self.parent)
Jack Jansen86288971996-08-28 14:18:58 +0000211 w.open(ID_INCLUDE, (l, None), self.mycb_add, None)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000212
213 def mycb_add(self, ok, item):
214 if item:
215 self.cb_add(item)
216
217class 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)
Jack Jansen86288971996-08-28 14:18:58 +0000221 self.wid.SetDialogDefaultItem(INCEXC_CHANGE)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000222 self.editid = editid
223 self.cb_add = cb_add
224 self.cb_del = cb_del
225 self.cb_get = cb_get
226
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)
Jack Jansen86288971996-08-28 14:18:58 +0000238 w.open(self.editid, ('', None), self.mycb_add, None)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000239
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)
248
249class 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
257
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)
264
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
273
274 def save(self, *args):
275 self.main.save()
276
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)
Jack Jansen86288971996-08-28 14:18:58 +0000283 self.iwin.open(ID_INCWINDOW, ID_INCLUDE, self.main.inc.getall(), self.main.inc.add,
Jack Jansenc9c99f21995-08-31 13:50:16 +0000284 self.main.inc.delete, self.main.inc.get)
285
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)
Jack Jansen86288971996-08-28 14:18:58 +0000292 self.ewin.open(ID_EXCWINDOW, ID_EXCLUDE, self.main.exc.getall(), self.main.exc.add,
Jack Jansenc9c99f21995-08-31 13:50:16 +0000293 self.main.exc.delete, self.main.exc.get)
294
295 def do_about(self, id, item, window, event):
296 EasyDialogs.Message("Test the MkDistr user interface.")
297
298def GetType():
299 """Ask user for distribution type"""
Jack Jansenc9c99f21995-08-31 13:50:16 +0000300 while 1:
Jack Jansen86288971996-08-28 14:18:58 +0000301 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)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000327
328def InitUI():
329 """Initialize stuff needed by UI (a resource file)"""
330 Res.OpenResFile('MkDistr.rsrc')
331
332class _testerhelp:
333 def __init__(self, which):
334 self.which = which
335
336 def get(self):
337 return [self.which+'-one', self.which+'-two']
338
339 def add(self, value):
340 if value:
341 print 'ADD', self.which, value
342
343 def delete(self, value):
344 print 'DEL', self.which, value
345
346class _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)
355
356 def check(self):
357 print 'CHECK'
358 return ['rv1', 'rv2']
359
360 def run(self):
361 print 'RUN'
362
363if __name__ == '__main__':
364 _test()