blob: 53869505d2f7495e3183d72d93824018ff7ae39c [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#
Jack Jansen5a6fdcd2001-08-25 12:15:04 +000015from Carbon import Res
16from Carbon import Dlg
17from Carbon import Ctl
18from Carbon import List
19from Carbon import Win
20from Carbon import Qd
Jack Jansenc9c99f21995-08-31 13:50:16 +000021from FrameWork import *
22import EasyDialogs
23import macfs
Jack Jansen86288971996-08-28 14:18:58 +000024import os
25import sys
Jack Jansen3c06b9a2001-08-27 21:41:23 +000026import macresource
Jack Jansenc9c99f21995-08-31 13:50:16 +000027
28# Resource IDs
29ID_MAIN = 514
30MAIN_LIST=1
31MAIN_MKDISTR=2
32MAIN_CHECK=3
33MAIN_INCLUDE=4
34MAIN_EXCLUDE=5
35
Jack Jansen86288971996-08-28 14:18:58 +000036ID_INCWINDOW=515
37ID_EXCWINDOW=517
Jack Jansenc9c99f21995-08-31 13:50:16 +000038INCEXC_DELETE=2
39INCEXC_CHANGE=3
40INCEXC_ADD=4
41
42ID_INCLUDE=512
43ID_EXCLUDE=513
Jack Jansen86288971996-08-28 14:18:58 +000044DLG_OK=1 # Include for include, exclude for exclude
Jack Jansenc9c99f21995-08-31 13:50:16 +000045DLG_CANCEL=2
Jack Jansen86288971996-08-28 14:18:58 +000046DLG_SRCPATH=3
47DLG_DSTPATH=4 # include dialog only
48DLG_EXCLUDE=5 # Exclude, include dialog only
Jack Jansenc9c99f21995-08-31 13:50:16 +000049
50ID_DTYPE=516
Jack Jansen86288971996-08-28 14:18:58 +000051DTYPE_EXIST=1
52DTYPE_NEW=2
53DTYPE_CANCEL=3
Jack Jansenc9c99f21995-08-31 13:50:16 +000054
55class EditDialogWindow(DialogWindow):
56 """Include/exclude editor (modeless dialog window)"""
57
Jack Jansen86288971996-08-28 14:18:58 +000058 def open(self, id, (src, dst), callback, cancelrv):
Jack Jansenc9c99f21995-08-31 13:50:16 +000059 self.id = id
Jack Jansenc9c99f21995-08-31 13:50:16 +000060 self.callback = callback
61 self.cancelrv = cancelrv
62 DialogWindow.open(self, id)
Jack Jansened24cd22001-02-14 17:07:04 +000063 tp, h, rect = self.dlg.GetDialogItem(DLG_SRCPATH)
Jack Jansenc9c99f21995-08-31 13:50:16 +000064 Dlg.SetDialogItemText(h, src)
Jack Jansened24cd22001-02-14 17:07:04 +000065 self.dlg.SetDialogDefaultItem(DLG_OK)
66 self.dlg.SetDialogCancelItem(DLG_CANCEL)
Jack Jansenc9c99f21995-08-31 13:50:16 +000067 if id == ID_INCLUDE:
Jack Jansened24cd22001-02-14 17:07:04 +000068 tp, h, rect = self.dlg.GetDialogItem(DLG_DSTPATH)
Jack Jansen86288971996-08-28 14:18:58 +000069 if dst == None:
70 dst = ''
Jack Jansenc9c99f21995-08-31 13:50:16 +000071 Dlg.SetDialogItemText(h, dst)
Jack Jansened24cd22001-02-14 17:07:04 +000072 self.dlg.DrawDialog()
Jack Jansenc9c99f21995-08-31 13:50:16 +000073
74 def do_itemhit(self, item, event):
Jack Jansen86288971996-08-28 14:18:58 +000075 if item in (DLG_OK, DLG_CANCEL, DLG_EXCLUDE):
Jack Jansenc9c99f21995-08-31 13:50:16 +000076 self.done(item)
Jack Jansenc9c99f21995-08-31 13:50:16 +000077 # else it is not interesting
78
79 def done(self, item):
Jack Jansened24cd22001-02-14 17:07:04 +000080 tp, h, rect = self.dlg.GetDialogItem(DLG_SRCPATH)
Jack Jansen86288971996-08-28 14:18:58 +000081 src = Dlg.GetDialogItemText(h)
Jack Jansenc9c99f21995-08-31 13:50:16 +000082 if item == DLG_OK:
Jack Jansenc9c99f21995-08-31 13:50:16 +000083 if self.id == ID_INCLUDE:
Jack Jansened24cd22001-02-14 17:07:04 +000084 tp, h, rect = self.dlg.GetDialogItem(DLG_DSTPATH)
Jack Jansenc9c99f21995-08-31 13:50:16 +000085 dst = Dlg.GetDialogItemText(h)
Jack Jansen86288971996-08-28 14:18:58 +000086 rv = (src, dst)
Jack Jansenc9c99f21995-08-31 13:50:16 +000087 else:
Jack Jansen86288971996-08-28 14:18:58 +000088 rv = (src, None)
89 elif item == DLG_EXCLUDE:
90 rv = (src, None)
Jack Jansenc9c99f21995-08-31 13:50:16 +000091 else:
92 rv = self.cancelrv
93 self.close()
Jack Jansen86288971996-08-28 14:18:58 +000094 self.callback((item in (DLG_OK, DLG_EXCLUDE)), rv)
Jack Jansenc9c99f21995-08-31 13:50:16 +000095
96class ListWindow(DialogWindow):
97 """A dialog window containing a list as its main item"""
98
99 def open(self, id, contents):
100 self.id = id
101 DialogWindow.open(self, id)
Jack Jansen86288971996-08-28 14:18:58 +0000102 Qd.SetPort(self.wid)
Jack Jansened24cd22001-02-14 17:07:04 +0000103 tp, h, rect = self.dlg.GetDialogItem(MAIN_LIST)
Jack Jansen86288971996-08-28 14:18:58 +0000104 self.listrect = rect
105 rect2 = rect[0]+1, rect[1]+1, rect[2]-16, rect[3]-16 # Scroll bar space
Jack Jansenc9c99f21995-08-31 13:50:16 +0000106 self.list = List.LNew(rect2, (0, 0, 1, len(contents)), (0,0), 0, self.wid,
107 0, 1, 1, 1)
108 self.setlist(contents)
109
110 def setlist(self, contents):
111 self.list.LDelRow(0, 0)
112 self.list.LSetDrawingMode(0)
113 if contents:
114 self.list.LAddRow(len(contents), 0)
115 for i in range(len(contents)):
116 self.list.LSetCell(contents[i], (0, i))
117 self.list.LSetDrawingMode(1)
Jack Jansen86288971996-08-28 14:18:58 +0000118 ##self.list.LUpdate(self.wid.GetWindowPort().visRgn)
Jack Jansen73023402001-01-23 14:58:20 +0000119 self.wid.InvalWindowRect(self.listrect)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000120
121 def additem(self, item):
122 where = self.list.LAddRow(1, 0)
123 self.list.LSetCell(item, (0, where))
124
125 def delgetitem(self, item):
126 data = self.list.LGetCell(1000, (0, item))
127 self.list.LDelRow(1, item)
128 return data
129
130 def do_listhit(self, event):
131 (what, message, when, where, modifiers) = event
132 Qd.SetPort(self.wid)
133 where = Qd.GlobalToLocal(where)
134 if self.list.LClick(where, modifiers):
135 self.do_dclick(self.delgetselection())
136
137 def delgetselection(self):
138 items = []
139 point = (0,0)
140 while 1:
141 ok, point = self.list.LGetSelect(1, point)
142 if not ok:
143 break
144 items.append(point[1])
145 point = point[0], point[1]+1
146 values = []
147 items.reverse()
148 for i in items:
149 values.append(self.delgetitem(i))
150 return values
151
152 def do_rawupdate(self, window, event):
Jack Janseneba88561996-04-12 16:34:58 +0000153 Qd.SetPort(window)
Jack Jansen86288971996-08-28 14:18:58 +0000154 Qd.FrameRect(self.listrect)
Jack Jansen822a30b1996-04-10 14:52:18 +0000155 self.list.LUpdate(self.wid.GetWindowPort().visRgn)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000156
157 def do_close(self):
158 self.close()
159
160 def close(self):
161 del self.list
162 DialogWindow.close(self)
163
164 def mycb_add(self, ok, item):
165 if item:
Jack Jansen86288971996-08-28 14:18:58 +0000166 self.additem(item[0])
Jack Jansenc9c99f21995-08-31 13:50:16 +0000167 self.cb_add(item)
168
169class MainListWindow(ListWindow):
170 """The main window"""
171
172 def open(self, id, cb_check, cb_run, cb_add):
173 ListWindow.open(self, id, [])
Jack Jansened24cd22001-02-14 17:07:04 +0000174 self.dlg.SetDialogDefaultItem(MAIN_INCLUDE)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000175 self.cb_run = cb_run
176 self.cb_check = cb_check
177 self.cb_add = cb_add
Jack Jansen86288971996-08-28 14:18:58 +0000178 setwatchcursor()
179 list = self.cb_check()
180 self.setlist(list)
181 setarrowcursor()
Jack Jansenc9c99f21995-08-31 13:50:16 +0000182
183 def do_itemhit(self, item, event):
184 if item == MAIN_LIST:
185 self.do_listhit(event)
186 if item == MAIN_MKDISTR:
Jack Jansen86288971996-08-28 14:18:58 +0000187 setwatchcursor()
Jack Jansen68552dd2000-05-05 23:07:43 +0000188 self.cb_run()
Jack Jansen86288971996-08-28 14:18:58 +0000189 setarrowcursor()
Jack Jansenc9c99f21995-08-31 13:50:16 +0000190 if item == MAIN_CHECK:
Jack Jansen86288971996-08-28 14:18:58 +0000191 setwatchcursor()
Jack Jansenc9c99f21995-08-31 13:50:16 +0000192 list = self.cb_check()
193 self.setlist(list)
Jack Jansen86288971996-08-28 14:18:58 +0000194 setarrowcursor()
Jack Jansenc9c99f21995-08-31 13:50:16 +0000195 if item == MAIN_INCLUDE:
196 self.do_dclick(self.delgetselection())
197 if item == MAIN_EXCLUDE:
198 for i in self.delgetselection():
Jack Jansen86288971996-08-28 14:18:58 +0000199 self.cb_add((i, None))
Jack Jansenc9c99f21995-08-31 13:50:16 +0000200
201 def do_dclick(self, list):
202 if not list:
203 list = ['']
204 for l in list:
205 w = EditDialogWindow(self.parent)
Jack Jansen86288971996-08-28 14:18:58 +0000206 w.open(ID_INCLUDE, (l, None), self.mycb_add, None)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000207
208 def mycb_add(self, ok, item):
209 if item:
210 self.cb_add(item)
211
212class IncListWindow(ListWindow):
213 """An include/exclude window"""
214 def open(self, id, editid, contents, cb_add, cb_del, cb_get):
215 ListWindow.open(self, id, contents)
Jack Jansened24cd22001-02-14 17:07:04 +0000216 self.dlg.SetDialogDefaultItem(INCEXC_CHANGE)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000217 self.editid = editid
218 self.cb_add = cb_add
219 self.cb_del = cb_del
220 self.cb_get = cb_get
221
222 def do_itemhit(self, item, event):
223 if item == MAIN_LIST:
224 self.do_listhit(event)
225 if item == INCEXC_DELETE:
226 old = self.delgetselection()
227 for i in old:
228 self.cb_del(i)
229 if item == INCEXC_CHANGE:
230 self.do_dclick(self.delgetselection())
231 if item == INCEXC_ADD:
232 w = EditDialogWindow(self.parent)
Jack Jansen86288971996-08-28 14:18:58 +0000233 w.open(self.editid, ('', None), self.mycb_add, None)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000234
235 def do_dclick(self, list):
236 if not list:
237 list = ['']
238 for l in list:
239 old = self.cb_get(l)
240 self.cb_del(l)
241 w = EditDialogWindow(self.parent)
242 w.open(self.editid, old, self.mycb_add, old)
243
244class MkDistrUI(Application):
245 def __init__(self, main):
246 self.main = main
247 Application.__init__(self)
248 self.mwin = MainListWindow(self)
249 self.mwin.open(ID_MAIN, self.main.check, self.main.run, self.main.inc.add)
250 self.iwin = None
251 self.ewin = None
252
253 def makeusermenus(self):
254 self.filemenu = m = Menu(self.menubar, "File")
255 self.includeitem = MenuItem(m, "Show Include window", "", self.showinc)
256 self.excludeitem = MenuItem(m, "Show Exclude window", "", self.showexc)
257 self.saveitem = MenuItem(m, "Save databases", "S", self.save)
258 self.quititem = MenuItem(m, "Quit", "Q", self.quit)
259
260 def quit(self, *args):
261 if self.main.is_modified():
262 rv = EasyDialogs.AskYesNoCancel('Database modified. Save?', -1)
263 if rv == -1:
264 return
265 if rv == 1:
266 self.main.save()
Jack Jansen6ab2cb62000-10-12 21:22:26 +0000267 self._quit()
Jack Jansenc9c99f21995-08-31 13:50:16 +0000268
269 def save(self, *args):
270 self.main.save()
271
272 def showinc(self, *args):
273 if self.iwin:
274 if self._windows.has_key(self.iwin):
275 self.iwin.close()
276 del self.iwin
277 self.iwin = IncListWindow(self)
Jack Jansen86288971996-08-28 14:18:58 +0000278 self.iwin.open(ID_INCWINDOW, ID_INCLUDE, self.main.inc.getall(), self.main.inc.add,
Jack Jansenc9c99f21995-08-31 13:50:16 +0000279 self.main.inc.delete, self.main.inc.get)
280
281 def showexc(self, *args):
282 if self.ewin:
283 if self._windows.has_key(self.ewin):
284 self.ewin.close()
285 del self.ewin
286 self.ewin = IncListWindow(self)
Jack Jansen86288971996-08-28 14:18:58 +0000287 self.ewin.open(ID_EXCWINDOW, ID_EXCLUDE, self.main.exc.getall(), self.main.exc.add,
Jack Jansenc9c99f21995-08-31 13:50:16 +0000288 self.main.exc.delete, self.main.exc.get)
289
290 def do_about(self, id, item, window, event):
291 EasyDialogs.Message("Test the MkDistr user interface.")
292
293def GetType():
294 """Ask user for distribution type"""
Jack Jansenc9c99f21995-08-31 13:50:16 +0000295 while 1:
Jack Jansen86288971996-08-28 14:18:58 +0000296 d = Dlg.GetNewDialog(ID_DTYPE, -1)
297 d.SetDialogDefaultItem(DTYPE_EXIST)
298 d.SetDialogCancelItem(DTYPE_CANCEL)
299 while 1:
300 rv = ModalDialog(None)
301 if rv in (DTYPE_EXIST, DTYPE_NEW, DTYPE_CANCEL):
302 break
303 del d
304 if rv == DTYPE_CANCEL:
305 sys.exit(0)
306 if rv == DTYPE_EXIST:
307## macfs.SetFolder(':(MkDistr)')
308 fss, ok = macfs.StandardGetFile('TEXT')
309 if not ok:
310 sys.exit(0)
311 path = fss.as_pathname()
312 basename = os.path.split(path)[-1]
313 if basename[-8:] <> '.include':
314 EasyDialogs.Message('That is not a distribution include file')
315 else:
316 return basename[:-8]
317 else:
318 name = EasyDialogs.AskString('Distribution name:')
319 if name:
320 return name
321 sys.exit(0)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000322
323def InitUI():
324 """Initialize stuff needed by UI (a resource file)"""
Jack Jansen3c06b9a2001-08-27 21:41:23 +0000325 macresource.need('DLOG', ID_MAIN, 'MkDistr.rsrc', modname=__name__)
Jack Jansenc9c99f21995-08-31 13:50:16 +0000326
327class _testerhelp:
328 def __init__(self, which):
329 self.which = which
330
331 def get(self):
332 return [self.which+'-one', self.which+'-two']
333
334 def add(self, value):
335 if value:
336 print 'ADD', self.which, value
337
338 def delete(self, value):
339 print 'DEL', self.which, value
340
341class _test:
342 def __init__(self):
343 import sys
Jack Jansen3c06b9a2001-08-27 21:41:23 +0000344 InitUI()
Jack Jansenc9c99f21995-08-31 13:50:16 +0000345 self.inc = _testerhelp('include')
346 self.exc = _testerhelp('exclude')
347 self.ui = MkDistrUI(self)
348 self.ui.mainloop()
349 sys.exit(1)
350
351 def check(self):
352 print 'CHECK'
353 return ['rv1', 'rv2']
354
355 def run(self):
356 print 'RUN'
357
358if __name__ == '__main__':
359 _test()