blob: 15bfa42bb870e143f130126c19992f2773d2c040 [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)
Jack Jansened24cd22001-02-14 17:07:04 +000062 tp, h, rect = self.dlg.GetDialogItem(DLG_SRCPATH)
Jack Jansenc9c99f21995-08-31 13:50:16 +000063 Dlg.SetDialogItemText(h, src)
Jack Jansened24cd22001-02-14 17:07:04 +000064 self.dlg.SetDialogDefaultItem(DLG_OK)
65 self.dlg.SetDialogCancelItem(DLG_CANCEL)
Jack Jansenc9c99f21995-08-31 13:50:16 +000066 if id == ID_INCLUDE:
Jack Jansened24cd22001-02-14 17:07:04 +000067 tp, h, rect = self.dlg.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 Jansened24cd22001-02-14 17:07:04 +000071 self.dlg.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 Jansened24cd22001-02-14 17:07:04 +000079 tp, h, rect = self.dlg.GetDialogItem(DLG_SRCPATH)
Jack Jansen86288971996-08-28 14:18:58 +000080 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:
Jack Jansened24cd22001-02-14 17:07:04 +000083 tp, h, rect = self.dlg.GetDialogItem(DLG_DSTPATH)
Jack Jansenc9c99f21995-08-31 13:50:16 +000084 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 Jansened24cd22001-02-14 17:07:04 +0000102 tp, h, rect = self.dlg.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)
Jack Jansen73023402001-01-23 14:58:20 +0000118 self.wid.InvalWindowRect(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 Jansened24cd22001-02-14 17:07:04 +0000173 self.dlg.SetDialogDefaultItem(MAIN_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 Jansen86288971996-08-28 14:18:58 +0000186 setwatchcursor()
Jack Jansen68552dd2000-05-05 23:07:43 +0000187 self.cb_run()
Jack Jansen86288971996-08-28 14:18:58 +0000188 setarrowcursor()
Jack Jansenc9c99f21995-08-31 13:50:16 +0000189 if item == MAIN_CHECK:
Jack Jansen86288971996-08-28 14:18:58 +0000190 setwatchcursor()
Jack Jansenc9c99f21995-08-31 13:50:16 +0000191 list = self.cb_check()
192 self.setlist(list)
Jack Jansen86288971996-08-28 14:18:58 +0000193 setarrowcursor()
Jack Jansenc9c99f21995-08-31 13:50:16 +0000194 if item == MAIN_INCLUDE:
195 self.do_dclick(self.delgetselection())
196 if item == MAIN_EXCLUDE:
197 for i in self.delgetselection():
Jack Jansen86288971996-08-28 14:18:58 +0000198 self.cb_add((i, None))
Jack Jansenc9c99f21995-08-31 13:50:16 +0000199
200 def do_dclick(self, list):
201 if not list:
202 list = ['']
203 for l in list:
204 w = EditDialogWindow(self.parent)
Jack Jansen86288971996-08-28 14:18:58 +0000205 w.open(ID_INCLUDE, (l, None), self.mycb_add, None)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000206
207 def mycb_add(self, ok, item):
208 if item:
209 self.cb_add(item)
210
211class IncListWindow(ListWindow):
212 """An include/exclude window"""
213 def open(self, id, editid, contents, cb_add, cb_del, cb_get):
214 ListWindow.open(self, id, contents)
Jack Jansened24cd22001-02-14 17:07:04 +0000215 self.dlg.SetDialogDefaultItem(INCEXC_CHANGE)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000216 self.editid = editid
217 self.cb_add = cb_add
218 self.cb_del = cb_del
219 self.cb_get = cb_get
220
221 def do_itemhit(self, item, event):
222 if item == MAIN_LIST:
223 self.do_listhit(event)
224 if item == INCEXC_DELETE:
225 old = self.delgetselection()
226 for i in old:
227 self.cb_del(i)
228 if item == INCEXC_CHANGE:
229 self.do_dclick(self.delgetselection())
230 if item == INCEXC_ADD:
231 w = EditDialogWindow(self.parent)
Jack Jansen86288971996-08-28 14:18:58 +0000232 w.open(self.editid, ('', None), self.mycb_add, None)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000233
234 def do_dclick(self, list):
235 if not list:
236 list = ['']
237 for l in list:
238 old = self.cb_get(l)
239 self.cb_del(l)
240 w = EditDialogWindow(self.parent)
241 w.open(self.editid, old, self.mycb_add, old)
242
243class MkDistrUI(Application):
244 def __init__(self, main):
245 self.main = main
246 Application.__init__(self)
247 self.mwin = MainListWindow(self)
248 self.mwin.open(ID_MAIN, self.main.check, self.main.run, self.main.inc.add)
249 self.iwin = None
250 self.ewin = None
251
252 def makeusermenus(self):
253 self.filemenu = m = Menu(self.menubar, "File")
254 self.includeitem = MenuItem(m, "Show Include window", "", self.showinc)
255 self.excludeitem = MenuItem(m, "Show Exclude window", "", self.showexc)
256 self.saveitem = MenuItem(m, "Save databases", "S", self.save)
257 self.quititem = MenuItem(m, "Quit", "Q", self.quit)
258
259 def quit(self, *args):
260 if self.main.is_modified():
261 rv = EasyDialogs.AskYesNoCancel('Database modified. Save?', -1)
262 if rv == -1:
263 return
264 if rv == 1:
265 self.main.save()
Jack Jansen6ab2cb62000-10-12 21:22:26 +0000266 self._quit()
Jack Jansenc9c99f21995-08-31 13:50:16 +0000267
268 def save(self, *args):
269 self.main.save()
270
271 def showinc(self, *args):
272 if self.iwin:
273 if self._windows.has_key(self.iwin):
274 self.iwin.close()
275 del self.iwin
276 self.iwin = IncListWindow(self)
Jack Jansen86288971996-08-28 14:18:58 +0000277 self.iwin.open(ID_INCWINDOW, ID_INCLUDE, self.main.inc.getall(), self.main.inc.add,
Jack Jansenc9c99f21995-08-31 13:50:16 +0000278 self.main.inc.delete, self.main.inc.get)
279
280 def showexc(self, *args):
281 if self.ewin:
282 if self._windows.has_key(self.ewin):
283 self.ewin.close()
284 del self.ewin
285 self.ewin = IncListWindow(self)
Jack Jansen86288971996-08-28 14:18:58 +0000286 self.ewin.open(ID_EXCWINDOW, ID_EXCLUDE, self.main.exc.getall(), self.main.exc.add,
Jack Jansenc9c99f21995-08-31 13:50:16 +0000287 self.main.exc.delete, self.main.exc.get)
288
289 def do_about(self, id, item, window, event):
290 EasyDialogs.Message("Test the MkDistr user interface.")
291
292def GetType():
293 """Ask user for distribution type"""
Jack Jansenc9c99f21995-08-31 13:50:16 +0000294 while 1:
Jack Jansen86288971996-08-28 14:18:58 +0000295 d = Dlg.GetNewDialog(ID_DTYPE, -1)
296 d.SetDialogDefaultItem(DTYPE_EXIST)
297 d.SetDialogCancelItem(DTYPE_CANCEL)
298 while 1:
299 rv = ModalDialog(None)
300 if rv in (DTYPE_EXIST, DTYPE_NEW, DTYPE_CANCEL):
301 break
302 del d
303 if rv == DTYPE_CANCEL:
304 sys.exit(0)
305 if rv == DTYPE_EXIST:
306## macfs.SetFolder(':(MkDistr)')
307 fss, ok = macfs.StandardGetFile('TEXT')
308 if not ok:
309 sys.exit(0)
310 path = fss.as_pathname()
311 basename = os.path.split(path)[-1]
312 if basename[-8:] <> '.include':
313 EasyDialogs.Message('That is not a distribution include file')
314 else:
315 return basename[:-8]
316 else:
317 name = EasyDialogs.AskString('Distribution name:')
318 if name:
319 return name
320 sys.exit(0)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000321
322def InitUI():
323 """Initialize stuff needed by UI (a resource file)"""
Jack Jansend13c3852000-06-20 21:59:25 +0000324 Res.FSpOpenResFile('MkDistr.rsrc', 1)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000325
326class _testerhelp:
327 def __init__(self, which):
328 self.which = which
329
330 def get(self):
331 return [self.which+'-one', self.which+'-two']
332
333 def add(self, value):
334 if value:
335 print 'ADD', self.which, value
336
337 def delete(self, value):
338 print 'DEL', self.which, value
339
340class _test:
341 def __init__(self):
342 import sys
Jack Jansend13c3852000-06-20 21:59:25 +0000343 Res.FSpOpenResFile('MkDistr.rsrc', 1)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000344 self.inc = _testerhelp('include')
345 self.exc = _testerhelp('exclude')
346 self.ui = MkDistrUI(self)
347 self.ui.mainloop()
348 sys.exit(1)
349
350 def check(self):
351 print 'CHECK'
352 return ['rv1', 'rv2']
353
354 def run(self):
355 print 'RUN'
356
357if __name__ == '__main__':
358 _test()