[Pythonmac-SIG] Re: password dialog (& toolbox interfaces followup)

Steven D. Majewski sdm7g@virginia.edu
Tue, 9 Feb 1999 13:54:57 -0500 (EST)


| Resending this message -- I sent it out last night and didn't
| see it appear on the mailing list --a nd looking back, I see 
| that my previous message which I acused Jack of not answering
| also didn't come back to me from the list. - Steve. 


Someone asked for a (hidden) password dialog. 
Here (at bottom) is one attempt -- it has a few flaws -- mainly
it doesn't handle full cut and pasted editing. Maybe a few more
I haven't found myself.  I don't think this is the best way to
do it in Python (see notes below) but I thought I'ld share the
effort, along with a few notes and questions. 
 Maybe someone else wants to either try the "special font" 
method, or else figure out how to get DialogCut et.al. to 
do the right thing.    -- Steve M.

NOTES on this function:
	Doesn't handle cut and paste from menu's or command keys.
	The following lines make the command key equivalents a NoOp:
				if ( mod & cmdKey ):
					MacOS.SysBeep()
					continue	# don't do cut & paste commands
	Removing those lines will restore command key actions, but
	they don't quite work in this dialog since DialogPaste, et.al.
	bypass the keyDown processing and the external python string
	buffer. ( So unless you want to figure out how to make it
	work completely, it's better to disable it entirely. )

	Also: backspace and left-arrow keys delete the last char
	from the buffer, but clicking into the middle of partially
	entered text and entering and/or deleting chars, or using
	left & right arrows together will not keep the display 
	& the internal buffer consistent. 

	The default resource id is the same used for AskString in
	EasyDialogs. If you make a duplicate in ResEdit and change
	the window type to 5 for a Movable Modal Dialog, and if you
	use that id, the dialog is made movable by the lines:
			if part == inDrag and win:
				win.DragWindow(where, screenbounds)
	If you use the default resource definition, then the window
	doesn't have a Drag part, so it does nothing. 


	eight bit chars may get munged in email. In the line:
		"msg =  ord('¥')"
	the character literal is the option-8 'dot' : 
		ord('¥') = '\\245' = 165 (10) = 0xA5  

Re: Previous message about Technote 1148 Dialog functions. 
	I mistakenly referred to them as new functions. They have
	been there since system 7.0. It's just a new technote 
	describing them. 

	They are there in Dlg, but as methods of dialog objects,
	not as module function. SetDialogDefaultItem & SetDialogCancelItem
	are used in EasyDialogs, and I've copies that use here (although,
	since I'm not calling ModalDialog to process the events, I 
	believe the only function of SetDialogDefaultItem is to cause
	the special emphasis drawing the default OK button. )
	There seem to be some problems with StdFilterProc (discussed below)


Other comments:
	Mac DTS has example password code in C that demonstrates three
	different methods: 
		[1] using two edit text items -- one hidden -- and redirecting
			events from the visible edit-text to the hidden one.
		[2]	Setting the dialog font to display a single glyph, and
			drawing the static text with a user proc.
		[3]	Internal buffer. 
	Both methods #1 and #3, in the DTS example code, used custom
	event filters in calls to ModalDialog. My function is a variant
	of method 3: it doesn't use a dialog event filter because I 
	had some problems with translating the event filter idiom to
	MacPython. (Also, doing more explicit processing allows it to
	support movable modal dialogs.) [ BTW: After taking a hack at
	#3 and seeing that it would take a bit more effort to support
	Cut & Paste & arrow keys properly, I think that #2 is probably
	the best way to get full functioning edit-text dialogs without
	visible echo. ]

	They way that the filter procedures are wrapped in MacPython
	seem to make it very difficult to translate these idioms.
	The DTS routines make a lot of use of the trick of modifying
	the event or item args in the filter, and returning False to
	signify that the event wasn't handled in the filter. 
	The toolbox wrapper code has to take an educated guess at
	which pointer args are IN, OUT, and INOUT. It looks like
	Dlg_UnivFilterProc in Dlgmodule.c folds the *item args and
	the return value together so that they can't be used independently. 
	Maybe it's possible, but I couldn't figure out how to do it.
	Also dialog.StdFilterProc appears to be a method of no args
	returning the boolean return value along with the event record
	and itemHit:

>>> d.StdFilterProc.__doc__
'() -> (Boolean _rv, EventRecord event, DialogItemIndex itemHit)'

	but to use is as described in some of the Apple Docs, it should
	be called with ( dialog, event, itemHit ) args. It looks like
	the Python wrapper assumes there are only OUT args, where the
	Apple Docs and examples sometimes modify the events they pass
	to the standard filter to process. 


Does this analysis sound reasonable ? 
In the previous message, I asked about how the automatic wrapping is done.
I've since been looking at the sources and I've seen some of the scripts.
I'm not yet sure that I understand the whole process. 
( So if I try to hack out a fix right now, I'm likely to start from
  Dlgmodule.c rather than regenerating the code templates from square one.)



#-----------------------
import Dlg,Win,Evt
import MacOS,sys
from EasyDialogs import cr2lf,lf2cr,screenbounds
from Dlg import GetNewDialog, SetDialogItemText, GetDialogItemText, ModalDialog
import Dialogs
from Events import *  		# for char-codes 
from Windows import inDrag,inMenuBar


def AskPassword(prompt,  id=257):	
	d = GetNewDialog(id, -1)
	if not d:
		print "Can't get DLOG resource with id =", id
		return
	tp, h, rect = d.GetDialogItem(3)	# STATIC TEXT ITEM <= prompt 
	SetDialogItemText(h, lf2cr(prompt))	
	tp, h, rect = d.GetDialogItem(4)	# EDIT TEXT ITEM 
	SetDialogItemText(h, '' )
	d.SetDialogDefaultItem(Dialogs.ok)
	d.SetDialogCancelItem(Dialogs.cancel)
	string = ''
	while 1:
		ready,ev = Evt.WaitNextEvent( -1, 6 )
		if not ready: continue
		what,msg,when,where,mod = ev
		if what == 0 : DlgDialogSelect(ev)  	# for blinking caret
		elif Dlg.IsDialogEvent(ev):
			if what == keyDown:
				charcode = msg & charCodeMask
				if ( mod & cmdKey ):
					MacOS.SysBeep()
					continue	# don't do cut & paste commands
				else:	
					if charcode == kReturnCharCode: return string
					elif charcode == kEscapeCharCode: return None
					elif charcode in (kLeftArrowCharCode,kBackspaceCharCode):
						string = string[:-1]
					else:
						string = string + chr(charcode)
						msg =  ord('¥')
						ev = (what,msg,when,where,mod)
			rs, win, item = Dlg.DialogSelect(ev)
			if item == Dialogs.ok : 	return string	
			elif item == Dialogs.cancel : 	return None
		elif what == mouseDown:
			part, win = Win.FindWindow(where)
			if part == inDrag and win:
				win.DragWindow(where, screenbounds)
			elif part == inMenuBar : MacOS.HandleEvent(ev)
		elif what == updateEvt: MacOS.HandleEvent(ev)








---|  Steven D. Majewski   (804-982-0831)  <sdm7g@Virginia.EDU>  |---
---|  Department of Molecular Physiology and Biological Physics  |---
---|  University of Virginia             Health Sciences Center  |---
---|  P.O. Box 10011            Charlottesville, VA  22906-0011  |---

Q: How many existentialists does it take to screw in a lightbulb?
A: Two.  One to screw it in and one to observe how the lightbulb itself
   symbolizes a single incandescent beacon of subjective reality in a
   netherworld of endless absurdity reaching out toward a maudlin
   cosmos of nothingness.