この文書はDr. Corran WebsterさんによるW Widgetsの"Template Application"を訳したものです。
訳の公開に快く承諾してくださったDr. Corran Websterさんに感謝いたします。
内容の理解が伴っていないので、おかしいところがあるかもしれません。お気づきの点がございましたら、わたしまでお願いいたします。

Template Application


Wウィジェットを使う
Template Application / Template Document

最小限のアプリケーションは以下のようになります:

import W
import Wapplication
import FrameWork

import macfs

from MyDocument import MyDocumentClass

class MyApp(Wapplication.Application):
	MyCreatorType = 'XXXX'		# Creator type of this application
	MyDocumentTypes = ['TEXT']	# List of up to four document types recognised
	preffilepath = ":SomeDirectory"	# Location of prefs in Preferences Folder

	def __init__(self):
		# Standard initialisation.
		Wapplication.Application.__init__(self, self.MyCreatorType)
		
		# All applications should handle these Apple Events,
		#  but you'll need an aete resource.
		import AE, AppleEvents
		AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEOpenApplication, 
				self.ignoreevent)	# We're already open
		AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEPrintDocuments, 
				self.ignoreevent)	# No printing in this app
		AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEOpenDocuments, 
				self.opendocsevent)
		AE.AEInstallEventHandler(AppleEvents.kCoreEventClass, AppleEvents.kAEQuitApplication, 
				self.quitevent)

		# If you had a splash screen, it would go here

		# Open documents passed in through argv
		import sys
		for path in sys.argv[1:]:
			self.opendoc(path)

		# Process some events!
		self.mainloop()

	def makeusermenus(self):
		# Set up menu items which all applications should have.
		#   Apple Menu has already been set up.

		# File menu
		m = Wapplication.Menu(self.menubar, "File")
		newitem = FrameWork.MenuItem(m, "New", "N", 'new')
		openitem = FrameWork.MenuItem(m, "Open…", "O", 'open')
		FrameWork.Separator(m)
		closeitem = FrameWork.MenuItem(m, "Close", "W", 'close')
		saveitem = FrameWork.MenuItem(m, "Save", "S", 'save')
		saveasitem = FrameWork.MenuItem(m, "Save as…", None, 'save_as')
		FrameWork.Separator(m)
		quititem = FrameWork.MenuItem(m, "Quit", "Q", 'quit')
		
		# Edit menu
		m = Wapplication.Menu(self.menubar, "Edit")
		undoitem = FrameWork.MenuItem(m, "Undo", 'Z', "undo")
		FrameWork.Separator(m)
		cutitem = FrameWork.MenuItem(m, "Cut", 'X', "cut")
		copyitem = FrameWork.MenuItem(m, "Copy", "C", "copy")
		pasteitem = FrameWork.MenuItem(m, "Paste", "V", "paste")
		clearitem = FrameWork.MenuItem(m, "Clear", None,  "clear")
		FrameWork.Separator(m)
		selallitem = FrameWork.MenuItem(m, "Select all", "A", "selectall")

		# Any other menus would go here

		# These menu items need to be updated periodically;
		#   any menu item not handled by the application should be here,
		#   as should any with a "can_" handler.
		self._menustocheck = [closeitem, saveitem, saveasitem,
				undoitem, cutitem, copyitem, pasteitem, 
				clearitem, selallitem]

	# no window menu, so pass
	def checkopenwindowsmenu(self):
		pass

	# Handle Apple Events	
	def ignoreevent(self, theAppleEvent, theReply):
		pass
	
	def quitevent(self, theAppleEvent, theReply):
		# System is telling us to quit
		#   allow some time to ask about save documents and quit

		import AE
		AE.AEInteractWithUser(50000000)
		self._quit()

	def opendocsevent(self, theAppleEvent, theReply):
		# System is telling us to open some documents
		#   unpack the names, and call opendoc() to open each

		W.SetCursor('watch')
		import aetools
		parameters, args = aetools.unpackevent(theAppleEvent)
		docs = parameters['----']
		if type(docs) <> type([]):
			docs = [docs]
		for doc in docs:
			fss, a = doc.Resolve()
			path = fss.as_pathname()
			self.opendoc(path)

	# Handle menu items
	def do_about(self, id, item, window, event):
		# This shows your application's about box.
		#   Replace it
		pass

	def domenu_open(self, *args):
		# This gives a standard open file dialog.

		fss, ok = apply(macfs.StandardGetFile, self.MyDocumentTypes)
		if ok:
			self.opendoc(fss.as_pathname())

	def domenu_new(self, *args):
		# This opens a blank document (usually a subclass of Window).
		#   Replace it with whatever calls you need.
		doc = MyDocumentClass()
		doc.open()

	def domenu_quit(self):
		# buh-bye
		self._quit()

	# Utility routines; the real work starts here
	def opendoc(self, path):
		# This does the dirty work of actually opening a document.
		#   Replace it
		fcreator, ftype = macfs.FSSpec(path).GetCreatorType()
		if ftype == 'TEXT':
			# This is one we know how to load
			doc = MyDocumentClass(path)
			doc.open()
		# elif ftype == 'OTHR': 
			# Maybe different file types need different document types
			#MyOtherDocumentClass(path)
		else:
			# No good, throw it back
			W.Message("Can’t open file '%s' of type '%s'." % (path, ftype))

# Run the app
MyApp()