mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	Interactively create a distribution from a sourcetree.
Not yet fully tested.
This commit is contained in:
		
							parent
							
								
									7c86b21812
								
							
						
					
					
						commit
						c9c99f2538
					
				
					 3 changed files with 657 additions and 0 deletions
				
			
		
							
								
								
									
										280
									
								
								Mac/scripts/MkDistr.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										280
									
								
								Mac/scripts/MkDistr.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,280 @@ | ||||||
|  | # | ||||||
|  | # Interactively decide what to distribute | ||||||
|  | # | ||||||
|  | # The distribution type is signalled by a letter. The currently | ||||||
|  | # defined letters are: | ||||||
|  | # p		PPC normal distribution | ||||||
|  | # P		PPC development distribution | ||||||
|  | # m		68K normal distribution | ||||||
|  | # M		68K development distribution | ||||||
|  | # | ||||||
|  | # The exclude file signals files to always exclude, | ||||||
|  | # The pattern file records are of the form | ||||||
|  | # ('pm', '*.c') | ||||||
|  | # This excludes all files ending in .c for normal distributions. | ||||||
|  | # | ||||||
|  | # The include file signals files and directories to include. | ||||||
|  | # Records are of the form | ||||||
|  | # ('pPmM', 'Lib') | ||||||
|  | # This includes the Lib dir in all distributions | ||||||
|  | # ('pPmM', 'Tools:bgen:AE:AppleEvents.py', 'Lib:MacToolbox:AppleEvents.py') | ||||||
|  | # This includes the specified file, putting it in the given place. | ||||||
|  | # | ||||||
|  | from MkDistr_ui import * | ||||||
|  | import fnmatch | ||||||
|  | import regex | ||||||
|  | import os | ||||||
|  | import sys | ||||||
|  | import macfs | ||||||
|  | import macostools | ||||||
|  | 
 | ||||||
|  | SyntaxError='Include/exclude file syntax error' | ||||||
|  | 
 | ||||||
|  | class Matcher: | ||||||
|  | 	"""Include/exclude database, common code""" | ||||||
|  | 	 | ||||||
|  | 	def __init__(self, type, filename): | ||||||
|  | 		self.type = type | ||||||
|  | 		self.filename = filename | ||||||
|  | 		self.rawdata = [] | ||||||
|  | 		self.parse(filename) | ||||||
|  | 		self.rawdata.sort() | ||||||
|  | 		self.rebuild() | ||||||
|  | 		self.modified = 0 | ||||||
|  | 
 | ||||||
|  | 	def parse(self, dbfile): | ||||||
|  | 		try: | ||||||
|  | 			fp = open(dbfile) | ||||||
|  | 		except IOError: | ||||||
|  | 			return | ||||||
|  | 		data = fp.readlines() | ||||||
|  | 		fp.close() | ||||||
|  | 		for d in data: | ||||||
|  | 			d = d[:-1] | ||||||
|  | 			if not d or d[0] == '#': continue | ||||||
|  | 			pat = self.parseline(d) | ||||||
|  | 			self.rawdata.append(pat) | ||||||
|  | 				 | ||||||
|  | 	def parseline(self, line): | ||||||
|  | 		try: | ||||||
|  | 			data = eval(line) | ||||||
|  | 		except: | ||||||
|  | 			raise SyntaxError, line | ||||||
|  | 		if type(data) <> type(()) or len(data) not in (2,3): | ||||||
|  | 			raise SyntaxError, line | ||||||
|  | 		if len(data) == 2: | ||||||
|  | 			data = data + ('',) | ||||||
|  | 		return data | ||||||
|  | 		 | ||||||
|  | 	def save(self): | ||||||
|  | 		fp = open(self.filename, 'w') | ||||||
|  | 		for d in self.rawdata: | ||||||
|  | 			fp.write(`d`+'\n') | ||||||
|  | 		self.modified = 0 | ||||||
|  | 			 | ||||||
|  | 	def add(self, value): | ||||||
|  | 		if len(value) == 2: | ||||||
|  | 			value = value + ('',) | ||||||
|  | 		self.rawdata.append(value) | ||||||
|  | 		self.rebuild1(value) | ||||||
|  | 		self.modified = 1 | ||||||
|  | 		 | ||||||
|  | 	def delete(self, value): | ||||||
|  | 		key = value | ||||||
|  | 		for i in range(len(self.rawdata)): | ||||||
|  | 			if self.rawdata[i][1] == key: | ||||||
|  | 				del self.rawdata[i] | ||||||
|  | 				self.unrebuild1(i, key) | ||||||
|  | 				self.modified = 1 | ||||||
|  | 				return | ||||||
|  | 		print 'Not found!', key | ||||||
|  | 				 | ||||||
|  | 	def getall(self): | ||||||
|  | 		return map(lambda x: x[1], self.rawdata) | ||||||
|  | 	 | ||||||
|  | 	def get(self, value): | ||||||
|  | 		for t, src, dst in self.rawdata: | ||||||
|  | 			if src == value: | ||||||
|  | 				return t, src, dst | ||||||
|  | 		print 'Not found!', value | ||||||
|  | 				 | ||||||
|  | 	def is_modified(self): | ||||||
|  | 		return self.modified | ||||||
|  | 							 | ||||||
|  | class IncMatcher(Matcher): | ||||||
|  | 	"""Include filename database and matching engine""" | ||||||
|  | 
 | ||||||
|  | 	def rebuild(self): | ||||||
|  | 		self.idict = {} | ||||||
|  | 		self.edict = {} | ||||||
|  | 		for v in self.rawdata: | ||||||
|  | 			self.rebuild1(v) | ||||||
|  | 			 | ||||||
|  | 	def rebuild1(self, (tp, src, dst)): | ||||||
|  | 		if self.type in tp: | ||||||
|  | 			if dst == '': | ||||||
|  | 				dst = src | ||||||
|  | 			self.idict[src] = dst | ||||||
|  | 		else: | ||||||
|  | 			self.edict[src] = '' | ||||||
|  | 			 | ||||||
|  | 	def unrebuild1(self, num, src): | ||||||
|  | 		if self.idict.has_key(src): | ||||||
|  | 			del self.idict[src] | ||||||
|  | 		else: | ||||||
|  | 			del self.edict[src] | ||||||
|  | 	 | ||||||
|  | 	def match(self, patharg): | ||||||
|  | 		removed = [] | ||||||
|  | 		# First check the include directory | ||||||
|  | 		path = patharg | ||||||
|  | 		while 1: | ||||||
|  | 			if self.idict.has_key(path): | ||||||
|  | 				# We know of this path (or initial piece of path) | ||||||
|  | 				dstpath = self.idict[path] | ||||||
|  | 				# We do want it distributed. Tack on the tail. | ||||||
|  | 				while removed: | ||||||
|  | 					dstpath = os.path.join(dstpath, removed[0]) | ||||||
|  | 					removed = removed[1:] | ||||||
|  | 				# Finally, if the resultant string ends in a separator | ||||||
|  | 				# tack on our input filename | ||||||
|  | 				if dstpath[-1] == os.sep: | ||||||
|  | 					dir, file = os.path.split(path) | ||||||
|  | 					dstpath = os.path.join(dstpath, path) | ||||||
|  | 				return dstpath | ||||||
|  | 			path, lastcomp = os.path.split(path) | ||||||
|  | 			if not path: | ||||||
|  | 				break | ||||||
|  | 			removed[0:0] = [lastcomp] | ||||||
|  | 		# Next check the exclude directory | ||||||
|  | 		path = patharg | ||||||
|  | 		while 1: | ||||||
|  | 			if self.edict.has_key(path): | ||||||
|  | 				return '' | ||||||
|  | 			path, lastcomp = os.path.split(path) | ||||||
|  | 			if not path: | ||||||
|  | 				break | ||||||
|  | 			removed[0:0] = [lastcomp] | ||||||
|  | 		return None | ||||||
|  | 			 | ||||||
|  | 	def checksourcetree(self): | ||||||
|  | 		rv = [] | ||||||
|  | 		for name in self.idict.keys(): | ||||||
|  | 			if not os.path.exists(name): | ||||||
|  | 				rv.append(name) | ||||||
|  | 		return rv | ||||||
|  | 				 | ||||||
|  | class ExcMatcher(Matcher): | ||||||
|  | 	"""Exclude pattern database and matching engine""" | ||||||
|  | 
 | ||||||
|  | 	def rebuild(self): | ||||||
|  | 		self.relist = [] | ||||||
|  | 		for v in self.rawdata: | ||||||
|  | 			self.rebuild1(v) | ||||||
|  | 		 | ||||||
|  | 	def rebuild1(self, (tp, src, dst)): | ||||||
|  | 		if self.type in tp: | ||||||
|  | 			pat = fnmatch.translate(src) | ||||||
|  | 			self.relist.append(regex.compile(pat)) | ||||||
|  | 		else: | ||||||
|  | 			self.relist.append(None) | ||||||
|  | 			 | ||||||
|  | 	def unrebuild1(self, num, src): | ||||||
|  | 		del self.relist[num] | ||||||
|  | 	 | ||||||
|  | 	def match(self, path): | ||||||
|  | 		comps = os.path.split(path) | ||||||
|  | 		file = comps[-1] | ||||||
|  | 		for pat in self.relist: | ||||||
|  | 			if pat and pat.match(file) == len(file): | ||||||
|  | 				return 1 | ||||||
|  | 		return 0		 | ||||||
|  | 		  | ||||||
|  | 		 | ||||||
|  | class Main: | ||||||
|  | 	"""The main program glueing it all together""" | ||||||
|  | 	 | ||||||
|  | 	def __init__(self): | ||||||
|  | 		InitUI() | ||||||
|  | 		fss, ok = macfs.GetDirectory('Source directory:') | ||||||
|  | 		if not ok: | ||||||
|  | 			sys.exit(0) | ||||||
|  | 		os.chdir(fss.as_pathname()) | ||||||
|  | 		self.typedist = GetType() | ||||||
|  | 		print 'TYPE', self.typedist | ||||||
|  | 		self.inc = IncMatcher(self.typedist, '(MkDistr.include)') | ||||||
|  | 		self.exc = ExcMatcher(self.typedist, '(MkDistr.exclude)') | ||||||
|  | 		self.ui = MkDistrUI(self) | ||||||
|  | 		self.ui.mainloop() | ||||||
|  | 		 | ||||||
|  | 	def check(self): | ||||||
|  | 		return self.checkdir(':', 1) | ||||||
|  | 		 | ||||||
|  | 	def checkdir(self, path, istop): | ||||||
|  | 		files = os.listdir(path) | ||||||
|  | 		rv = [] | ||||||
|  | 		todo = [] | ||||||
|  | 		for f in files: | ||||||
|  | 			if self.exc.match(f): | ||||||
|  | 				continue | ||||||
|  | 			fullname = os.path.join(path, f) | ||||||
|  | 			if self.inc.match(fullname) == None: | ||||||
|  | 				if os.path.isdir(fullname): | ||||||
|  | 					todo.append(fullname) | ||||||
|  | 				else: | ||||||
|  | 					rv.append(fullname) | ||||||
|  | 		for d in todo: | ||||||
|  | 			if len(rv) > 100: | ||||||
|  | 				if istop: | ||||||
|  | 					rv.append('... and more ...') | ||||||
|  | 				return rv | ||||||
|  | 			rv = rv + self.checkdir(d, 0) | ||||||
|  | 		return rv | ||||||
|  | 		 | ||||||
|  | 	def run(self, destprefix): | ||||||
|  | 		missing = self.inc.checksourcetree() | ||||||
|  | 		if missing: | ||||||
|  | 			print '==== Missing source files ====' | ||||||
|  | 			for i in missing: | ||||||
|  | 				print i | ||||||
|  | 			print '==== Fix and retry ====' | ||||||
|  | 			return | ||||||
|  | 		if not self.rundir(':', destprefix, 0): | ||||||
|  | 			return | ||||||
|  | 		self.rundir(':', destprefix, 1) | ||||||
|  | 
 | ||||||
|  | 	def rundir(self, path, destprefix, doit): | ||||||
|  | 		files = os.listdir(path) | ||||||
|  | 		todo = [] | ||||||
|  | 		rv = 1 | ||||||
|  | 		for f in files: | ||||||
|  | 			if self.exc.match(f): | ||||||
|  | 				continue | ||||||
|  | 			fullname = os.path.join(path, f) | ||||||
|  | 			if os.path.isdir(fullname): | ||||||
|  | 				todo.append(fullname) | ||||||
|  | 			else: | ||||||
|  | 				dest = self.inc.match(fullname) | ||||||
|  | 				if dest == None: | ||||||
|  | 					print 'Not yet resolved:', fullname | ||||||
|  | 					rv = 0 | ||||||
|  | 				if dest: | ||||||
|  | 					if doit: | ||||||
|  | 						print 'COPY ', fullname | ||||||
|  | 						print '  -> ', os.path.join(destprefix, dest) | ||||||
|  | 						macostools.copy(fullname, os.path.join(destprefix, dest), 1) | ||||||
|  | 		for d in todo: | ||||||
|  | 			if not self.rundir(d, destprefix, doit): | ||||||
|  | 				rv = 0 | ||||||
|  | 		return rv | ||||||
|  | 		 | ||||||
|  | 	def save(self): | ||||||
|  | 		self.inc.save() | ||||||
|  | 		self.exc.save() | ||||||
|  | 		 | ||||||
|  | 	def is_modified(self): | ||||||
|  | 		return self.inc.is_modified() or self.exc.is_modified() | ||||||
|  | 
 | ||||||
|  | if __name__ == '__main__': | ||||||
|  | 	Main() | ||||||
|  | 	 | ||||||
							
								
								
									
										31
									
								
								Mac/scripts/MkDistr.rsrc.hqx
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								Mac/scripts/MkDistr.rsrc.hqx
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,31 @@ | ||||||
|  | (This file may be decompressed with BinHex 4.0) | ||||||
|  | 
 | ||||||
|  | :$%eV4'PcG()ZFR0bB`"bFh*M8P0&4!%!N!F&SINN!*!%!3!!!!5[!!!$V`!!!2)8 | ||||||
|  | T8SJ&+9+%"5P5rJ6'6!)%!!!#"!!!!J3!!!)%!!!#!a0Dd4TFh4b,R*cFQ0b!J!! | ||||||
|  | !(*cFQ058d9%!3$rN!3!!(*cFQ058d9%!3$rN!3!N"+XA"N$!*!'"D(rq"rrrJ!I | ||||||
|  | rrm!(rrrJ"rrrm!IrrrJ(rrrm"rrrrJIrrri(rrrq"rrrrJIrrri(rrrq"rrrrJI | ||||||
|  | rrri(rrrq"rrrrJIrrri(rrrq"rrrrJIrrri(rrrq"rrrrJIrrri(rrrq"rrrrJI | ||||||
|  | rrri(rrrq"rrrrJIrrri(rrrq"rrrrJIrrri!!!!&3"F!$i!rJ'K!!8"!!%!N!8# | ||||||
|  | !*!&&3"F!$i!rJ'K!!8"!!%!N!8#!3#3"-`!#!#3"B)")J#@!9`%!Np,!*!&JJ!+ | ||||||
|  | !*B!4!3'3f&ZBf9X!*!&C!$F!(B"@`8'8fpeFQ0P!*!&8!$F!')"@`8,8&"$)'4P | ||||||
|  | GQ9XEh!!N!C3!'i!BJ$B"3Sf1%XJ3QPZBA*j!*!&C!"Z!(B!f!8+8&"$)'*TEQ&b | ||||||
|  | H3#3"43!EJ!M!9B3#89NDA3J9'9iG&X!N!88!!S!*!"KL!K3BA4dCA*Z1J#3"9!! | ||||||
|  | #J"J!'+)#d9iBfaeC'8JD@ik!*!%p!!+!*!&JJ%L!*B"A!3#6dX!N!@#!!S!PJ"% | ||||||
|  | "!C$B@jMC@`!N!9N!0`!GJ&E"3C6Eh9bBf8!N!93!0`!BJ&E"3Y38%-JC'9fC@a[ | ||||||
|  | F!#3"P!!EJ"L!0J&#MBi5b"#D@jKFRN!N!9N!'i!GJ$B"3T38%-JBQPZBA*j!*!& | ||||||
|  | &!"Z!#-"9K!*4@4TG#"8CAKd@`#3"6)!EJ""!9F3!*!'&!!+!#3!BBJ(8fpeFQ0P | ||||||
|  | 1Jm!N!8b!!S!3J"KL!a%CA0dD@jKG'P[EMS!N!93!!S!B!"LL!Y*EQ0XG@4P)'PZ | ||||||
|  | 1Q`!!!!9!#J!+!%k!F3!!!%!!3#3"3)#!*!%&3!S!#J"1J(%!!!"!!%!N!8#!`#3 | ||||||
|  | "%i!!`#3"3S!#J$G!Bi!N!I`!33""!'2"!C%C@aPG'8!N!A`!'i""!$j"!G&C'Pd | ||||||
|  | ,LiZ!*!'m!!+!33!BJ3'3@4N,LiZ!!!!&3"`!'i!k`&E!!!"!!%!N!8#"!#3"+)! | ||||||
|  | "!#3"4i!&!!`!13'#dCeE'`JFfpeFQ0PG!#3"6)!&!"%!13'$e"33b"NCACPE'p` | ||||||
|  | E@9ZG1F!N!9'!"3!@!$N"Jmf1%XJBQPZBA*j,@pZE(RR!*!&@J!8!'`!j!B28&"$ | ||||||
|  | )'*TEQ&bH5e[EQajj`#3"3S!#J!D!1D)(P4jF'8JEfBJC'PcG(*TBR9dD@pZ)(4[ | ||||||
|  | )'*eD@aN1J!!!'i!"!#3"3S!#J$G!Bi!N!I`!6B""3'-"!T%DA0dFQPLGA4P!*!& | ||||||
|  | m!$5!33",J3+3fKPBfXJG(*PC3#3"I!!#J%%!')%#NPZBfaeC'8Z,Li!N!A`!'i" | ||||||
|  | "!$'"!G&H'0XG@4P!!!!!3!!!!5[!!!$V`!!!2)!cC58%83!!!!F!+B!!84-6dF! | ||||||
|  | "!!54%P86!!%!%i#!*!)cC0`!J%!$`!!!"N!cC0i!J)!(J!!!IS!cC0X!J-!)`!! | ||||||
|  | !K-!cC0S!J3!1J!!!Ri!cC0N!J$rr`!!!3)!N!3#!Irr!!!!-J#3"!)#rrm!!!-p | ||||||
|  | !-f52!)$rrm!!!)X!*!%!J6rr`!!!TF!N!315@jME(9NC5"ND@&XEfF14AKME(9N | ||||||
|  | C5"ND@&XEfF%6@&TEKC*EQ0XG@4P,f9iBfaeC'8JGfPZC'ph%84TFh4bD@*eG'P[ | ||||||
|  | EL"dHA"PJqX: | ||||||
							
								
								
									
										346
									
								
								Mac/scripts/MkDistr_ui.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										346
									
								
								Mac/scripts/MkDistr_ui.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,346 @@ | ||||||
|  | # | ||||||
|  | # MkDistr - User Interface. | ||||||
|  | # | ||||||
|  | # Jack Jansen, CWI, August 1995 | ||||||
|  | # | ||||||
|  | # XXXX To be done (requires mods of FrameWork and toolbox interfaces too): | ||||||
|  | # - Give dialogs titles (need dlg->win conversion) | ||||||
|  | # - Place dialogs better (???) | ||||||
|  | # - <return> as <ok> | ||||||
|  | # - big box around ok button | ||||||
|  | # - window-close crashes on reopen (why?) | ||||||
|  | # - Box around lists (???) | ||||||
|  | # - Change cursor while busy (need cursor support in Qd) | ||||||
|  | # | ||||||
|  | import Res | ||||||
|  | import Dlg | ||||||
|  | import Ctl | ||||||
|  | import List | ||||||
|  | import Win | ||||||
|  | import Qd | ||||||
|  | from FrameWork import * | ||||||
|  | import EasyDialogs | ||||||
|  | import macfs | ||||||
|  | 
 | ||||||
|  | # Resource IDs | ||||||
|  | ID_MAIN = 514 | ||||||
|  | MAIN_LIST=1 | ||||||
|  | MAIN_MKDISTR=2 | ||||||
|  | MAIN_CHECK=3 | ||||||
|  | MAIN_INCLUDE=4 | ||||||
|  | MAIN_EXCLUDE=5 | ||||||
|  | 
 | ||||||
|  | ID_INCEXC=515 | ||||||
|  | INCEXC_DELETE=2 | ||||||
|  | INCEXC_CHANGE=3 | ||||||
|  | INCEXC_ADD=4 | ||||||
|  | 
 | ||||||
|  | ID_INCLUDE=512 | ||||||
|  | ID_EXCLUDE=513 | ||||||
|  | DLG_OK=1 | ||||||
|  | DLG_CANCEL=2 | ||||||
|  | DLG_FULL=3 | ||||||
|  | DLG_PPCDEV=4 | ||||||
|  | DLG_68K=5 | ||||||
|  | DLG_PPC=6 | ||||||
|  | DLG_BUTTONS=[DLG_FULL, DLG_PPCDEV, DLG_68K, DLG_PPC] | ||||||
|  | DLG_LETTERS=['S', 'P', 'm', 'p'] | ||||||
|  | DLG_SRCPATH=7 | ||||||
|  | DLG_DSTPATH=8 | ||||||
|  | 
 | ||||||
|  | ID_DTYPE=516 | ||||||
|  | 
 | ||||||
|  | class EditDialogWindow(DialogWindow): | ||||||
|  | 	"""Include/exclude editor (modeless dialog window)""" | ||||||
|  | 	 | ||||||
|  | 	def open(self, id, (type, src, dst), callback, cancelrv): | ||||||
|  | 		self.id = id | ||||||
|  | 		if id == ID_INCLUDE: | ||||||
|  | 			title = "Include file dialog" | ||||||
|  | 		else: | ||||||
|  | 			title = "Exclude pattern dialog" | ||||||
|  | 		#self.wid.as_Window().SetWTitle(title) | ||||||
|  | 		self.callback = callback | ||||||
|  | 		self.cancelrv = cancelrv | ||||||
|  | 		DialogWindow.open(self, id) | ||||||
|  | 		tp, h, rect = self.wid.GetDialogItem(DLG_SRCPATH) | ||||||
|  | 		Dlg.SetDialogItemText(h, src) | ||||||
|  | 		if id == ID_INCLUDE: | ||||||
|  | 			tp, h, rect = self.wid.GetDialogItem(DLG_DSTPATH) | ||||||
|  | 			Dlg.SetDialogItemText(h, dst) | ||||||
|  | 		for b in range(len(DLG_BUTTONS)): | ||||||
|  | 			if type == None or DLG_LETTERS[b] in type: | ||||||
|  | 				self.setbutton(DLG_BUTTONS[b], 1) | ||||||
|  | 
 | ||||||
|  | 	def setbutton(self, num, value): | ||||||
|  | 		tp, h, rect = self.wid.GetDialogItem(num) | ||||||
|  | 		h.as_Control().SetControlValue(value) | ||||||
|  | 		 | ||||||
|  | 	def getbutton(self, num): | ||||||
|  | 		tp, h, rect = self.wid.GetDialogItem(num) | ||||||
|  | 		return h.as_Control().GetControlValue() | ||||||
|  | 	 | ||||||
|  | 	def do_itemhit(self, item, event): | ||||||
|  | 		if item in (DLG_OK, DLG_CANCEL): | ||||||
|  | 			self.done(item) | ||||||
|  | 		elif item in DLG_BUTTONS: | ||||||
|  | 			v = self.getbutton(item) | ||||||
|  | 			self.setbutton(item, (not v)) | ||||||
|  | 		# else it is not interesting | ||||||
|  | 		 | ||||||
|  | 	def done(self, item): | ||||||
|  | 		if item == DLG_OK: | ||||||
|  | 			distlist = '' | ||||||
|  | 			for i in range(len(DLG_BUTTONS)): | ||||||
|  | 				if self.getbutton(DLG_BUTTONS[i]): | ||||||
|  | 					distlist = distlist + DLG_LETTERS[i] | ||||||
|  | 			tp, h, rect = self.wid.GetDialogItem(DLG_SRCPATH) | ||||||
|  | 			src = Dlg.GetDialogItemText(h) | ||||||
|  | 			if self.id == ID_INCLUDE: | ||||||
|  | 				tp, h, rect = self.wid.GetDialogItem(DLG_DSTPATH) | ||||||
|  | 				dst = Dlg.GetDialogItemText(h) | ||||||
|  | 				rv = (distlist, src, dst) | ||||||
|  | 			else: | ||||||
|  | 				rv = (distlist, src) | ||||||
|  | 		else: | ||||||
|  | 			rv = self.cancelrv | ||||||
|  | 		self.close() | ||||||
|  | 		self.callback((item==DLG_OK), rv) | ||||||
|  | 		 | ||||||
|  | class ListWindow(DialogWindow): | ||||||
|  | 	"""A dialog window containing a list as its main item""" | ||||||
|  | 	 | ||||||
|  | 	def open(self, id, contents): | ||||||
|  | 		self.id = id | ||||||
|  | 		DialogWindow.open(self, id) | ||||||
|  | 		tp, h, rect = self.wid.GetDialogItem(MAIN_LIST) | ||||||
|  | 		rect2 = rect[0], rect[1], rect[2]-16, rect[3]-16	# Scroll bar space | ||||||
|  | 		self.list = List.LNew(rect2, (0, 0, 1, len(contents)), (0,0), 0, self.wid, | ||||||
|  | 				0, 1, 1, 1) | ||||||
|  | 		self.setlist(contents) | ||||||
|  | 
 | ||||||
|  | 	def setlist(self, contents): | ||||||
|  | 		self.list.LDelRow(0, 0) | ||||||
|  | 		self.list.LSetDrawingMode(0) | ||||||
|  | 		if contents: | ||||||
|  | 			self.list.LAddRow(len(contents), 0) | ||||||
|  | 			for i in range(len(contents)): | ||||||
|  | 				self.list.LSetCell(contents[i], (0, i)) | ||||||
|  | 		self.list.LSetDrawingMode(1) | ||||||
|  | 		self.list.LUpdate() | ||||||
|  | 		 | ||||||
|  | 	def additem(self, item): | ||||||
|  | 		where = self.list.LAddRow(1, 0) | ||||||
|  | 		self.list.LSetCell(item, (0, where)) | ||||||
|  | 		 | ||||||
|  | 	def delgetitem(self, item): | ||||||
|  | 		data = self.list.LGetCell(1000, (0, item)) | ||||||
|  | 		self.list.LDelRow(1, item) | ||||||
|  | 		return data | ||||||
|  | 		 | ||||||
|  | 	def do_listhit(self, event): | ||||||
|  | 		(what, message, when, where, modifiers) = event | ||||||
|  | 		Qd.SetPort(self.wid) | ||||||
|  | 		where = Qd.GlobalToLocal(where) | ||||||
|  | 		if self.list.LClick(where, modifiers): | ||||||
|  | 			self.do_dclick(self.delgetselection()) | ||||||
|  | 		 | ||||||
|  | 	def delgetselection(self): | ||||||
|  | 		items = [] | ||||||
|  | 		point = (0,0) | ||||||
|  | 		while 1: | ||||||
|  | 			ok, point = self.list.LGetSelect(1, point) | ||||||
|  | 			if not ok: | ||||||
|  | 				break | ||||||
|  | 			items.append(point[1]) | ||||||
|  | 			point = point[0], point[1]+1 | ||||||
|  | 		values = [] | ||||||
|  | 		items.reverse() | ||||||
|  | 		for i in items: | ||||||
|  | 			values.append(self.delgetitem(i)) | ||||||
|  | 		return values | ||||||
|  | 		 | ||||||
|  | 	def do_rawupdate(self, window, event): | ||||||
|  | 		self.list.LUpdate() | ||||||
|  | 		 | ||||||
|  | 	def do_close(self): | ||||||
|  | 		self.close() | ||||||
|  | 		 | ||||||
|  | 	def close(self): | ||||||
|  | 		del self.list | ||||||
|  | 		DialogWindow.close(self) | ||||||
|  | 		 | ||||||
|  | 	def mycb_add(self, ok, item): | ||||||
|  | 		if item: | ||||||
|  | 			self.additem(item[1]) | ||||||
|  | 			self.cb_add(item) | ||||||
|  | 		 | ||||||
|  | class MainListWindow(ListWindow): | ||||||
|  | 	"""The main window""" | ||||||
|  | 
 | ||||||
|  | 	def open(self, id, cb_check, cb_run, cb_add): | ||||||
|  | 		ListWindow.open(self, id, []) | ||||||
|  | 		title = "MkDistr: Unresolved files" | ||||||
|  | 		#self.wid.as_Window().SetWTitle(title) | ||||||
|  | 		self.cb_run = cb_run | ||||||
|  | 		self.cb_check = cb_check | ||||||
|  | 		self.cb_add = cb_add | ||||||
|  | 
 | ||||||
|  | 	def do_itemhit(self, item, event): | ||||||
|  | 		if item == MAIN_LIST: | ||||||
|  | 			self.do_listhit(event) | ||||||
|  | 		if item == MAIN_MKDISTR: | ||||||
|  | 			fss, ok = macfs.StandardPutFile('Destination folder:') | ||||||
|  | 			if not ok: | ||||||
|  | 				return | ||||||
|  | 			self.cb_run(fss.as_pathname()) | ||||||
|  | 		if item == MAIN_CHECK: | ||||||
|  | 			list = self.cb_check() | ||||||
|  | 			self.setlist(list) | ||||||
|  | 		if item == MAIN_INCLUDE: | ||||||
|  | 			self.do_dclick(self.delgetselection()) | ||||||
|  | 		if item == MAIN_EXCLUDE: | ||||||
|  | 			for i in self.delgetselection(): | ||||||
|  | 				self.cb_add(('', i, '')) | ||||||
|  | 			 | ||||||
|  | 	def do_dclick(self, list): | ||||||
|  | 		if not list: | ||||||
|  | 			list = [''] | ||||||
|  | 		for l in list: | ||||||
|  | 			w = EditDialogWindow(self.parent) | ||||||
|  | 			w.open(ID_INCLUDE, (None, l, ''), self.mycb_add, None) | ||||||
|  | 
 | ||||||
|  | 	def mycb_add(self, ok, item): | ||||||
|  | 		if item: | ||||||
|  | 			self.cb_add(item) | ||||||
|  | 
 | ||||||
|  | class IncListWindow(ListWindow): | ||||||
|  | 	"""An include/exclude window""" | ||||||
|  | 	def open(self, id, editid, contents, cb_add, cb_del, cb_get): | ||||||
|  | 		ListWindow.open(self, id, contents) | ||||||
|  | 		if editid == ID_INCLUDE: | ||||||
|  | 			title = "MkDistr: files to include" | ||||||
|  | 		else: | ||||||
|  | 			title = "MkDistr: patterns to exclude" | ||||||
|  | 		#self.wid.as_Window().SetWTitle(title) | ||||||
|  | 		self.editid = editid | ||||||
|  | 		self.cb_add = cb_add | ||||||
|  | 		self.cb_del = cb_del | ||||||
|  | 		self.cb_get = cb_get | ||||||
|  | 
 | ||||||
|  | 	def do_itemhit(self, item, event): | ||||||
|  | 		if item == MAIN_LIST: | ||||||
|  | 			self.do_listhit(event) | ||||||
|  | 		if item == INCEXC_DELETE: | ||||||
|  | 			old = self.delgetselection() | ||||||
|  | 			for i in old: | ||||||
|  | 				self.cb_del(i) | ||||||
|  | 		if item == INCEXC_CHANGE: | ||||||
|  | 			self.do_dclick(self.delgetselection()) | ||||||
|  | 		if item == INCEXC_ADD: | ||||||
|  | 			w = EditDialogWindow(self.parent) | ||||||
|  | 			w.open(self.editid, (None, '', ''), self.mycb_add, None) | ||||||
|  | 			 | ||||||
|  | 	def do_dclick(self, list): | ||||||
|  | 		if not list: | ||||||
|  | 			list = [''] | ||||||
|  | 		for l in list: | ||||||
|  | 			old = self.cb_get(l) | ||||||
|  | 			self.cb_del(l) | ||||||
|  | 			w = EditDialogWindow(self.parent) | ||||||
|  | 			w.open(self.editid, old, self.mycb_add, old) | ||||||
|  | 
 | ||||||
|  | class MkDistrUI(Application): | ||||||
|  | 	def __init__(self, main): | ||||||
|  | 		self.main = main | ||||||
|  | 		Application.__init__(self) | ||||||
|  | 		self.mwin = MainListWindow(self) | ||||||
|  | 		self.mwin.open(ID_MAIN, self.main.check, self.main.run, self.main.inc.add) | ||||||
|  | 		self.iwin = None | ||||||
|  | 		self.ewin = None	 | ||||||
|  | 		 | ||||||
|  | 	def makeusermenus(self): | ||||||
|  | 		self.filemenu = m = Menu(self.menubar, "File") | ||||||
|  | 		self.includeitem = MenuItem(m, "Show Include window", "", self.showinc) | ||||||
|  | 		self.excludeitem = MenuItem(m, "Show Exclude window", "", self.showexc) | ||||||
|  | 		self.saveitem = MenuItem(m, "Save databases", "S", self.save) | ||||||
|  | 		self.quititem = MenuItem(m, "Quit", "Q", self.quit) | ||||||
|  | 		 | ||||||
|  | 	def quit(self, *args): | ||||||
|  | 		if self.main.is_modified(): | ||||||
|  | 			rv = EasyDialogs.AskYesNoCancel('Database modified. Save?', -1) | ||||||
|  | 			if rv == -1: | ||||||
|  | 				return | ||||||
|  | 			if rv == 1: | ||||||
|  | 				self.main.save() | ||||||
|  | 		raise self | ||||||
|  | 		 | ||||||
|  | 	def save(self, *args): | ||||||
|  | 		self.main.save() | ||||||
|  | 		 | ||||||
|  | 	def showinc(self, *args): | ||||||
|  | 		if self.iwin: | ||||||
|  | 			if self._windows.has_key(self.iwin): | ||||||
|  | 				self.iwin.close() | ||||||
|  | 			del self.iwin | ||||||
|  | 		self.iwin = IncListWindow(self) | ||||||
|  | 		self.iwin.open(ID_INCEXC, ID_INCLUDE, self.main.inc.getall(), self.main.inc.add, | ||||||
|  | 			self.main.inc.delete, self.main.inc.get) | ||||||
|  | 		 | ||||||
|  | 	def showexc(self, *args): | ||||||
|  | 		if self.ewin: | ||||||
|  | 			if self._windows.has_key(self.ewin): | ||||||
|  | 				self.ewin.close() | ||||||
|  | 			del self.ewin | ||||||
|  | 		self.ewin = IncListWindow(self) | ||||||
|  | 		self.ewin.open(ID_INCEXC, ID_EXCLUDE, self.main.exc.getall(), self.main.exc.add, | ||||||
|  | 			self.main.exc.delete, self.main.exc.get) | ||||||
|  | 
 | ||||||
|  | 	def do_about(self, id, item, window, event): | ||||||
|  | 		EasyDialogs.Message("Test the MkDistr user interface.") | ||||||
|  | 		 | ||||||
|  | def GetType(): | ||||||
|  | 	"""Ask user for distribution type""" | ||||||
|  | 	d = Dlg.GetNewDialog(ID_DTYPE, -1) | ||||||
|  | 	while 1: | ||||||
|  | 		rv = ModalDialog(None) | ||||||
|  | 		if rv >= 1 and rv <= 4: | ||||||
|  | 			return DLG_LETTERS[rv-1] | ||||||
|  | 			 | ||||||
|  | def InitUI(): | ||||||
|  | 	"""Initialize stuff needed by UI (a resource file)""" | ||||||
|  | 	Res.OpenResFile('MkDistr.rsrc') | ||||||
|  | 
 | ||||||
|  | class _testerhelp: | ||||||
|  | 	def __init__(self, which): | ||||||
|  | 		self.which = which | ||||||
|  | 		 | ||||||
|  | 	def get(self): | ||||||
|  | 		return [self.which+'-one', self.which+'-two'] | ||||||
|  | 		 | ||||||
|  | 	def add(self, value): | ||||||
|  | 		if value: | ||||||
|  | 			print 'ADD', self.which, value | ||||||
|  | 			 | ||||||
|  | 	def delete(self, value): | ||||||
|  | 		print 'DEL', self.which, value | ||||||
|  | 		 | ||||||
|  | class _test: | ||||||
|  | 	def __init__(self): | ||||||
|  | 		import sys | ||||||
|  | 		Res.OpenResFile('MkDistr.rsrc') | ||||||
|  | 		self.inc = _testerhelp('include') | ||||||
|  | 		self.exc = _testerhelp('exclude') | ||||||
|  | 		self.ui = MkDistrUI(self) | ||||||
|  | 		self.ui.mainloop() | ||||||
|  | 		sys.exit(1) | ||||||
|  | 		 | ||||||
|  | 	def check(self): | ||||||
|  | 		print 'CHECK' | ||||||
|  | 		return ['rv1', 'rv2'] | ||||||
|  | 		 | ||||||
|  | 	def run(self): | ||||||
|  | 		print 'RUN' | ||||||
|  | 		 | ||||||
|  | if __name__ == '__main__': | ||||||
|  | 	_test() | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jack Jansen
						Jack Jansen