'release21-maint'.
--- /dev/null
+# Test suite for SocketServer.py
+
+# XXX This must be run manually -- somehow the I/O redirection of the
+# regression test breaks the test.
+
+from test_support import verbose, verify, TESTFN
+if not verbose:
+ raise ImportError, "test_socketserver can only be run manually"
+
+from SocketServer import *
+import socket
+import select
+import time
+import threading
+import os
+
+NREQ = 3
+DELAY = 0.5
+
+class MyMixinHandler:
+ def handle(self):
+ time.sleep(DELAY)
+ line = self.rfile.readline()
+ time.sleep(DELAY)
+ self.wfile.write(line)
+
+class MyStreamHandler(MyMixinHandler, StreamRequestHandler):
+ pass
+
+class MyDatagramHandler(MyMixinHandler, DatagramRequestHandler):
+ pass
+
+class MyMixinServer:
+ def serve_a_few(self):
+ for i in range(NREQ):
+ self.handle_request()
+ def handle_error(self, request, client_address):
+ self.close_request(request)
+ self.server_close()
+ raise
+
+teststring = "hello world\n"
+
+def receive(sock, n, timeout=20):
+ r, w, x = select.select([sock], [], [], timeout)
+ if sock in r:
+ return sock.recv(n)
+ else:
+ raise RuntimeError, "timed out on %s" % `sock`
+
+def testdgram(proto, addr):
+ s = socket.socket(proto, socket.SOCK_DGRAM)
+ s.sendto(teststring, addr)
+ buf = data = receive(s, 100)
+ while data and '\n' not in buf:
+ data = receive(s, 100)
+ buf += data
+ verify(buf == teststring)
+ s.close()
+
+def teststream(proto, addr):
+ s = socket.socket(proto, socket.SOCK_STREAM)
+ s.connect(addr)
+ s.send(teststring)
+ buf = data = receive(s, 100)
+ while data and '\n' not in buf:
+ data = receive(s, 100)
+ buf += data
+ verify(buf == teststring)
+ s.close()
+
+class ServerThread(threading.Thread):
+ def __init__(self, addr, svrcls, hdlrcls):
+ threading.Thread.__init__(self)
+ self.__addr = addr
+ self.__svrcls = svrcls
+ self.__hdlrcls = hdlrcls
+ def run(self):
+ class svrcls(MyMixinServer, self.__svrcls):
+ pass
+ if verbose: print "thread: creating server"
+ svr = svrcls(self.__addr, self.__hdlrcls)
+ if verbose: print "thread: serving three times"
+ svr.serve_a_few()
+ if verbose: print "thread: done"
+
+seed = 0
+def pickport():
+ global seed
+ seed += 1
+ return 10000 + (os.getpid() % 1000)*10 + seed
+
+host = "localhost"
+testfiles = []
+def pickaddr(proto):
+ if proto == socket.AF_INET:
+ return (host, pickport())
+ else:
+ fn = TESTFN + str(pickport())
+ testfiles.append(fn)
+ return fn
+
+def cleanup():
+ for fn in testfiles:
+ try:
+ os.remove(fn)
+ except os.error:
+ pass
+ testfiles[:] = []
+
+def testloop(proto, servers, hdlrcls, testfunc):
+ for svrcls in servers:
+ addr = pickaddr(proto)
+ if verbose:
+ print "ADDR =", addr
+ print "CLASS =", svrcls
+ t = ServerThread(addr, svrcls, hdlrcls)
+ if verbose: print "server created"
+ t.start()
+ if verbose: print "server running"
+ for i in range(NREQ):
+ time.sleep(DELAY)
+ if verbose: print "test client", i
+ testfunc(proto, addr)
+ if verbose: print "waiting for server"
+ t.join()
+ if verbose: print "done"
+
+tcpservers = [TCPServer, ThreadingTCPServer]
+if hasattr(os, 'fork'):
+ tcpservers.append(ForkingTCPServer)
+udpservers = [UDPServer, ThreadingUDPServer]
+if hasattr(os, 'fork'):
+ udpservers.append(ForkingUDPServer)
+
+if not hasattr(socket, 'AF_UNIX'):
+ streamservers = []
+ dgramservers = []
+else:
+ class ForkingUnixStreamServer(ForkingMixIn, UnixStreamServer): pass
+ streamservers = [UnixStreamServer, ThreadingUnixStreamServer,
+ ForkingUnixStreamServer]
+ class ForkingUnixDatagramServer(ForkingMixIn, UnixDatagramServer): pass
+ dgramservers = [UnixDatagramServer, ThreadingUnixDatagramServer,
+ ForkingUnixDatagramServer]
+
+def testall():
+ testloop(socket.AF_INET, tcpservers, MyStreamHandler, teststream)
+ testloop(socket.AF_INET, udpservers, MyDatagramHandler, testdgram)
+ if hasattr(socket, 'AF_UNIX'):
+ testloop(socket.AF_UNIX, streamservers, MyStreamHandler, teststream)
+ # Alas, on Linux (at least) recvfrom() doesn't return a meaningful
+ # client address so this cannot work:
+ ##testloop(socket.AF_UNIX, dgramservers, MyDatagramHandler, testdgram)
+
+def main():
+ try:
+ testall()
+ finally:
+ cleanup()
+
+main()
--- /dev/null
+"""VerySimplePlayer converted to python
+
+Jack Jansen, CWI, December 1995
+"""
+
+import Qt
+import QuickTime
+import Qd
+import QuickDraw
+import Evt
+import Events
+import Win
+import Windows
+import macfs
+import sys
+
+# XXXX maxbounds = (40, 40, 1000, 1000)
+
+def main():
+ print 'hello world' # XXXX
+ # skip the toolbox initializations, already done
+ # XXXX Should use gestalt here to check for quicktime version
+ Qt.EnterMovies()
+
+ # Get the movie file
+ fss, ok = macfs.StandardGetFile(QuickTime.MovieFileType)
+ if not ok:
+ sys.exit(0)
+
+ # Open the window
+ bounds = (175, 75, 175+160, 75+120)
+ theWindow = Win.NewCWindow(bounds, fss.as_tuple()[2], 0, 0, -1, 1, 0)
+ # XXXX Needed? SetGWorld((CGrafPtr)theWindow, nil)
+ Qd.SetPort(theWindow)
+
+ # Get the movie
+ theMovie = loadMovie(fss)
+
+ # Relocate to (0, 0)
+ bounds = theMovie.GetMovieBox()
+ bounds = 0, 0, bounds[2]-bounds[0], bounds[3]-bounds[1]
+ theMovie.SetMovieBox(bounds)
+
+ # Create a controller
+ theController = theMovie.NewMovieController(bounds, QuickTime.mcTopLeftMovie)
+
+ # Get movie size and update window parameters
+ rv, bounds = theController.MCGetControllerBoundsRect()
+ theWindow.SizeWindow(bounds[2], bounds[3], 0) # XXXX or [3] [2]?
+ Qt.AlignWindow(theWindow, 0)
+ theWindow.ShowWindow()
+
+ # XXXX MCDoAction(theController, mcActionSetGrowBoxBounds, &maxBounds)
+ theController.MCDoAction(QuickTime.mcActionSetKeysEnabled, '1')
+
+ # XXXX MCSetActionFilterWithRefCon(theController, movieControllerEventFilter, (long)theWindow)
+
+ done = 0
+ while not done:
+ gotone, evt = Evt.WaitNextEvent(0xffff, 0)
+ (what, message, when, where, modifiers) = evt
+## print what, message, when, where, modifiers # XXXX
+
+ if theController.MCIsPlayerEvent(evt):
+ continue
+
+ if what == Events.mouseDown:
+ part, whichWindow = Win.FindWindow(where)
+ if part == Windows.inGoAway:
+ done = whichWindow.TrackGoAway(where)
+ elif part == Windows.inDrag:
+ Qt.DragAlignedWindow(whichWindow, where, (0, 0, 4000, 4000))
+ elif what == Events.updateEvt:
+ whichWindow = Win.WhichWindow(message)
+ if not whichWindow:
+ # Probably the console window. Print something, hope it helps.
+ print 'update'
+ else:
+ Qd.SetPort(whichWindow)
+ whichWindow.BeginUpdate()
+ Qd.EraseRect(whichWindow.GetWindowPort().portRect)
+ whichWindow.EndUpdate()
+
+def loadMovie(theFile):
+ """Load a movie given an fsspec. Return the movie object"""
+ movieResRef = Qt.OpenMovieFile(theFile, 1)
+ movie, d1, d2 = Qt.NewMovieFromFile(movieResRef, 0, QuickTime.newMovieActive)
+ return movie
+
+if __name__ == '__main__':
+ main()
+
--- /dev/null
+How to make a Python-distribution.
+----------------------------------
+
+These notes are mainly for myself, or for whoever tries to make a MacPython
+distribution when I'm fed up with it. They were last updated for 2.1b2.
+
+- Increase fragment version number in PythonCore and PythonCoreCarbon.
+ the fragment number is Python's sys.hexversion, it should be set in the
+ "PEF" preferences.
+- Increase version number in _versioncheck.py
+- Build PythonStandSmall, run once in root folder
+- Update Relnotes, readme's, Demo:build.html
+- Make sure tkresources.rsrc is up-to-date
+- fullbuild everything with increase-buildno
+- Update Numeric and build/install it both with Classic and with Carbon python
+- Run configurepython
+- Recompile OSAm and possibly other Contrib stuff
+- mkdistr binary.include
+- mkdistr dev.include
+- make distribution archive with Installer Vise
+ Things to make sure of:
+ - Finder icon positions
+ - Version numbers in "Packages..." window
+ - Version number in "Installer Settings" -> "Easy Install Text"
+ - Version number in "Project" -> Attributes
+ - Version number in "Project" -> PostProcess
+ - Version number in "Internet" -> "Download Sites"
+ - Version number in "Internet" -> "File Groups".
+- test on virgin systems (OSX, OS9, OS8 without Carbon). Make sure to test
+ tkinter too.
+- Upload
+- Update README file in ftp directory
+- Change version number in public_html/macpythonversion.txt .
+- Update macpython.html
+- Send an announcement to:
+ pythonmac-sig@python.org
+ python-dev@python.org
+ python-announce@python.org
+ archivist@info-mac.org
+ adcnews@apple.com
+ http://www.macupdate.com
+ http://guide.apple.com/usindex.html
+ http://www.versiontracker.com/ Jack.Jansen@oratrix.com
\ No newline at end of file
--- /dev/null
+/***********************************************************
+Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/* config.h for Macintosh.
+ Valid only for CodeWarrior.
+ There's no point in giving exact version numbers of the compilers
+ since we don't update this file as each compiler comes out;
+ with CodeWarrior, we generally use the most recent version.
+*/
+
+#define USE_STACKCHECK
+
+/* Define if on Macintosh (MPW or __MWERKS__ should also be defined) */
+#ifndef macintosh
+#define macintosh
+#endif
+
+#if defined(USE_GUSI1) || defined(USE_GUSI2)
+#define USE_GUSI
+#endif
+
+#ifndef USE_GUSI
+#define DONT_HAVE_SYS_TYPES_H
+#define DONT_HAVE_SYS_STAT_H
+#define HAVE_STAT_H
+#endif
+
+/* Define if on AIX 3.
+ System headers sometimes define this.
+ We just want to avoid a redefinition error message. */
+#ifndef _ALL_SOURCE
+#undef _ALL_SOURCE
+#endif
+
+/* Define if type char is unsigned and you are not using gcc. */
+#ifndef __CHAR_UNSIGNED__
+#undef __CHAR_UNSIGNED__
+#endif
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Define if your struct tm has tm_zone. */
+#undef HAVE_TM_ZONE
+
+/* Define if you don't have tm_zone but do have the external array
+ tzname. */
+#undef HAVE_TZNAME
+
+/* Define if on MINIX. */
+#undef _MINIX
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef mode_t
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef pid_t
+
+/* Define if the system does not provide POSIX.1 features except
+ with this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define if you need to in order for stat and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define as the return type of signal handlers (int or void). */
+#define RETSIGTYPE void
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your <sys/time.h> declares struct tm. */
+#undef TM_IN_SYS_TIME
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+/* Define if your processor stores words with the most significant
+ byte first (like Motorola and SPARC, unlike Intel and VAX). */
+#define WORDS_BIGENDIAN 1
+
+/* Define for AIX if your compiler is a genuine IBM xlC/xlC_r
+ and you want support for AIX C++ shared extension modules. */
+#undef AIX_GENUINE_CPLUSPLUS
+
+/* Define if your <unistd.h> contains bad prototypes for exec*()
+ (as it does on SGI IRIX 4.x) */
+#undef BAD_EXEC_PROTOTYPES
+
+/* Define if your compiler botches static forward declarations */
+#define BAD_STATIC_FORWARD
+
+/* Define this if you have BeOS threads */
+#undef BEOS_THREADS
+
+/* Define if you have the Mach cthreads package */
+#undef C_THREADS
+
+/* Defined when case of imported modules are checked against case of file. */
+#define CHECK_IMPORT_CASE
+
+/* Define to `long' if <time.h> doesn't define. */
+#undef clock_t
+
+/* Defined on Solaris to see additional function prototypes. */
+#undef __EXTENSIONS__
+
+/* Define if getpgrp() must be called as getpgrp(0). */
+#undef GETPGRP_HAVE_ARG
+
+/* Define if gettimeofday() does not have second (timezone) argument
+ This is the case on Motorola V4 (R40V4.2) */
+#undef GETTIMEOFDAY_NO_TZ
+
+/* Define this if your time.h defines altzone */
+#undef HAVE_ALTZONE
+
+/* Defined when any dynamic module loading is enabled */
+/* #undef HAVE_DYNAMIC_LOADING */
+
+/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */
+#undef HAVE_GETC_UNLOCKED
+
+/* Define this if you have some version of gethostbyname_r() */
+#undef HAVE_GETHOSTBYNAME_R
+
+/* Define this if you have the 3-arg version of gethostbyname_r() */
+#undef HAVE_GETHOSTBYNAME_R_3_ARG
+
+/* Define this if you have the 5-arg version of gethostbyname_r() */
+#undef HAVE_GETHOSTBYNAME_R_5_ARG
+
+/* Define this if you have the 6-arg version of gethostbyname_r() */
+#undef HAVE_GETHOSTBYNAME_R_6_ARG
+
+/* Defined to enable large file support when an off_t is bigger than a long
+ and long long is available and at least as big as an off_t. You may need
+ to add some flags for configuration and compilation to enable this mode.
+ E.g, for Solaris 2.7:
+ CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" OPT="-O2 $CFLAGS" \
+ configure
+*/
+#undef HAVE_LARGEFILE_SUPPORT
+
+/* Define this if you have the type long long */
+#undef HAVE_LONG_LONG
+
+/* Define if your compiler supports function prototypes */
+#define HAVE_PROTOTYPES 1
+
+/* Define if you have GNU PTH threads */
+#undef HAVE_PTH
+
+/* Define if your compiler supports variable length function prototypes
+ (e.g. void fprintf(FILE *, char *, ...);) *and* <stdarg.h> */
+#define HAVE_STDARG_PROTOTYPES
+
+/* Define this if you have the type uintptr_t */
+#undef HAVE_UINTPTR_T
+
+/* Define if you have a useable wchar_t type defined in wchar.h; useable
+ means wchar_t must be 16-bit unsigned type. (see
+ Include/unicodeobject.h). */
+#define HAVE_USABLE_WCHAR_T 1
+
+/* Define if the compiler provides a wchar.h header file. */
+#define HAVE_WCHAR_H 1
+
+/* Define if you want to have a Unicode type. */
+#define Py_USING_UNICODE 1
+
+/* Define as the integral type used for Unicode representation. */
+#define PY_UNICODE_TYPE wchar_t
+
+/* Define as the size of the unicode type. */
+#define Py_UNICODE_SIZE 2
+
+/* Define if malloc(0) returns a NULL pointer */
+#ifdef USE_MSL_MALLOC
+#define MALLOC_ZERO_RETURNS_NULL
+#else
+#undef MALLOC_ZERO_RETURNS_NULL
+#endif
+
+/* Define if you have POSIX threads */
+#ifdef USE_GUSI2
+#define _POSIX_THREADS
+#endif
+
+/* Define if you want to build an interpreter with many run-time checks */
+#undef Py_DEBUG
+
+/* Define to force use of thread-safe errno, h_errno, and other functions */
+#undef _REENTRANT
+
+/* Define if setpgrp() must be called as setpgrp(0, 0). */
+#undef SETPGRP_HAVE_ARG
+
+/* Define to empty if the keyword does not work. */
+#undef signed
+
+/* Define if i>>j for signed int i does not extend the sign bit
+ when i < 0
+*/
+#define SIGNED_RIGHT_SHIFT_ZERO_FILLS
+
+/* The number of bytes in an off_t. */
+#define SIZEOF_OFF_T 4
+
+/* The number of bytes in a time_t. */
+#define SIZEOF_TIME_T 4
+
+/* The number of bytes in a pthread_t. */
+#ifdef USE_GUSI2
+#define SIZEOF_PTHREAD_T 4
+#endif
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef socklen_t
+
+/* Define if you can safely include both <sys/select.h> and <sys/time.h>
+ (which you can't on SCO ODT 3.0). */
+#undef SYS_SELECT_WITH_SYS_TIME
+
+/* Define if a va_list is an array of some kind */
+#undef VA_LIST_IS_ARRAY
+
+/* Define to empty if the keyword does not work. */
+#undef volatile
+
+/* Define if you want SIGFPE handled (see Include/pyfpe.h). */
+#undef WANT_SIGFPE_HANDLER
+
+/* Define if you want wctype.h functions to be used instead of the
+ one supplied by Python itself. (see Include/unicodectype.h). */
+#undef WANT_WCTYPE_FUNCTIONS
+
+/* Define if you want to compile in cycle garbage collection */
+#undef WITH_CYCLE_GC
+
+/* Define if you want to emulate SGI (IRIX 4) dynamic linking.
+ This is rumoured to work on VAX (Ultrix), Sun3 (SunOS 3.4),
+ Sequent Symmetry (Dynix), and Atari ST.
+ This requires the "dl-dld" library,
+ ftp://ftp.cwi.nl/pub/dynload/dl-dld-1.1.tar.Z,
+ as well as the "GNU dld" library,
+ ftp://ftp.cwi.nl/pub/dynload/dld-3.2.3.tar.Z.
+ Don't bother on SunOS 4 or 5, they already have dynamic linking using
+ shared libraries */
+#undef WITH_DL_DLD
+
+/* Define if you want to use the new-style (Openstep, Rhapsody, MacOS)
+ dynamic linker (dyld) instead of the old-style (NextStep) dynamic
+ linker (rld). Dyld is necessary to support frameworks. */
+#undef WITH_DYLD
+
+/* Define if you want to compile in Python-specific mallocs */
+#undef WITH_PYMALLOC
+
+/* Define if you want to produce an OpenStep/Rhapsody framework
+ (shared library plus accessory files). */
+#undef WITH_NEXT_FRAMEWORK
+
+/* Define if you want to use SGI (IRIX 4) dynamic linking.
+ This requires the "dl" library by Jack Jansen,
+ ftp://ftp.cwi.nl/pub/dynload/dl-1.6.tar.Z.
+ Don't bother on IRIX 5, it already has dynamic linking using SunOS
+ style shared libraries */
+#undef WITH_SGI_DL
+
+/* Define if you want to compile in rudimentary thread support */
+/* #undef WITH_THREAD */
+
+/* The number of bytes in a char. */
+#define SIZEOF_CHAR 1
+
+/* The number of bytes in a double. */
+#define SIZEOF_DOUBLE 8
+
+/* The number of bytes in a float. */
+#define SIZEOF_FLOAT 4
+
+/* The number of bytes in a fpos_t. */
+#define SIZEOF_FPOS_T 4
+
+/* The number of bytes in a int. */
+#define SIZEOF_INT 4
+
+/* The number of bytes in a long. */
+#define SIZEOF_LONG 4
+
+/* The number of bytes in a long long. */
+#undef SIZEOF_LONG_LONG
+
+/* The number of bytes in a short. */
+#define SIZEOF_SHORT 2
+
+/* The number of bytes in a uintptr_t. */
+#define SIZEOF_UINTPTR_T 4
+
+/* The number of bytes in a void *. */
+#define SIZEOF_VOID_P 4
+
+/* Define if you have the _getpty function. */
+#undef HAVE__GETPTY
+
+/* Define if you have the alarm function. */
+#undef HAVE_ALARM
+
+/* Define if you have the chown function. */
+#undef HAVE_CHOWN
+
+/* Define if you have clock. */
+#define HAVE_CLOCK
+
+/* Define if you have the confstr function. */
+#undef HAVE_CONFSTR
+
+/* Define if you have the ctermid function. */
+#undef HAVE_CTERMID
+
+/* Define if you have the ctermid_r function. */
+#undef HAVE_CTERMID_R
+
+/* Define if you have the dlopen function. */
+#undef HAVE_DLOPEN
+
+/* Define if you have the dup2 function. */
+#undef HAVE_DUP2
+
+/* Define if you have the execv function. */
+#undef HAVE_EXECV
+
+/* Define if you have the fdatasync function. */
+#undef HAVE_FDATASYNC
+
+/* Define if you have the flock function. */
+#undef HAVE_FLOCK
+
+/* Define if you have the fork function. */
+#undef HAVE_FORK
+
+/* Define if you have the forkpty function. */
+#undef HAVE_FORKPTY
+
+/* Define if you have the fpathconf function. */
+#undef HAVE_FPATHCONF
+
+/* Define if you have the fseek64 function. */
+#undef HAVE_FSEEK64
+
+/* Define if you have the fseeko function. */
+#undef HAVE_FSEEKO
+
+/* Define if you have the fstatvfs function. */
+#undef HAVE_FSTATVFS
+
+/* Define if you have the fsync function. */
+#define HAVE_FSYNC
+
+/* Define if you have the ftell64 function. */
+#undef HAVE_FTELL64
+
+/* Define if you have the ftello function. */
+#undef HAVE_FTELLO
+
+/* Define if you have the ftime function. */
+#undef HAVE_FTIME
+
+/* Define if you have the ftruncate function. */
+#ifdef USE_GUSI
+#define HAVE_FTRUNCATE
+#endif
+
+/* Define if you have the getcwd function. */
+#define HAVE_GETCWD
+
+/* Define if you have the getgroups function. */
+#undef HAVE_GETGROUPS
+
+/* Define if you have the gethostbyname function. */
+#ifdef USE_GUSI
+#define HAVE_GETHOSTBYNAME 1
+#endif
+
+/* Define if you have the getlogin function. */
+#undef HAVE_GETLOGIN
+
+/* Define if you have the getpeername function. */
+#ifdef USE_GUSI
+#define HAVE_GETPEERNAME
+#endif
+
+/* Define if you have the getpgrp function. */
+#undef HAVE_GETPGRP
+
+/* Define if you have the getpid function. */
+#undef HAVE_GETPID
+
+/* Define if you have the getpwent function. */
+#undef HAVE_GETPWENT
+
+/* Define if you have the gettimeofday function. */
+#ifdef USE_GUSI
+#define HAVE_GETTIMEOFDAY
+#endif
+
+/* Define if you have the getwd function. */
+#undef HAVE_GETWD
+
+/* Define if you have the hypot function. */
+#ifndef __MC68K__
+/* 68K hypot definition (and implementation) are unuseable
+** because they use 10-byte floats.
+*/
+#define HAVE_HYPOT
+#endif
+
+/* Define if you have the kill function. */
+#undef HAVE_KILL
+
+/* Define if you have the link function. */
+#undef HAVE_LINK
+
+/* Define if you have the lstat function. */
+#undef HAVE_LSTAT
+
+/* Define if you have the memmove function. */
+#define HAVE_MEMMOVE
+
+/* Define if you have the mkfifo function. */
+#undef HAVE_MKFIFO
+
+/* Define if you have the mktime function. */
+#define HAVE_MKTIME
+
+/* Define if you have the mremap function. */
+#undef HAVE_MREMAP
+
+/* Define if you have the nice function. */
+#undef HAVE_NICE
+
+/* Define if you have the openpty function. */
+#undef HAVE_OPENPTY
+
+/* Define if you have the pathconf function. */
+#undef HAVE_PATHCONF
+
+/* Define if you have the pause function. */
+#undef HAVE_PAUSE
+
+/* Define if you have the plock function. */
+#undef HAVE_PLOCK
+
+/* Define if you have the poll function. */
+#undef HAVE_POLL
+
+/* Define if you have the pthread_init function. */
+#undef HAVE_PTHREAD_INIT
+
+/* Define if you have the putenv function. */
+#undef HAVE_PUTENV
+
+/* Define if you have the readlink function. */
+#undef HAVE_READLINK
+
+/* Define if you have the select function. */
+#ifdef USE_GUSI
+#define HAVE_SELECT
+#endif
+
+/* Define if you have the setegid function. */
+#undef HAVE_SETEGID
+
+/* Define if you have the seteuid function. */
+#undef HAVE_SETEUID
+
+/* Define if you have the setgid function. */
+#undef HAVE_SETGID
+
+/* Define if you have the setlocale function. */
+#undef HAVE_SETLOCALE
+
+/* Define if you have the setpgid function. */
+#undef HAVE_SETPGID
+
+/* Define if you have the setpgrp function. */
+#undef HAVE_SETPGRP
+
+/* Define if you have the setregid function. */
+#undef HAVE_SETREGID
+
+/* Define if you have the setreuid function. */
+#undef HAVE_SETREUID
+
+/* Define if you have the setsid function. */
+#undef HAVE_SETSID
+
+/* Define if you have the setuid function. */
+#undef HAVE_SETUID
+
+/* Define if you have the setvbuf function. */
+#define HAVE_SETVBUF
+
+/* Define if you have the sigaction function. */
+#undef HAVE_SIGACTION
+
+/* Define if you have the siginterrupt function. */
+#undef HAVE_SIGINTERRUPT
+
+/* Define if you have the sigrelse function. */
+#undef HAVE_SIGRELSE
+
+/* Define if you have the statvfs function. */
+#undef HAVE_STATVFS
+
+/* Define if you have the strdup function. */
+#undef HAVE_STRDUP
+
+/* Define if you have the strerror function. */
+#define HAVE_STRERROR
+
+/* Define if you have the strftime function. */
+#define HAVE_STRFTIME
+
+/* Define if you have the strptime function. */
+#undef HAVE_STRPTIME
+
+/* Define if you have the symlink function. */
+#undef HAVE_SYMLINK
+
+/* Define if you have the sysconf function. */
+#undef HAVE_SYSCONF
+
+/* Define if you have the tcgetpgrp function. */
+#undef HAVE_TCGETPGRP
+
+/* Define if you have the tcsetpgrp function. */
+#undef HAVE_TCSETPGRP
+
+/* Define if you have the tempnam function. */
+#undef HAVE_TEMPNAM
+
+/* Define if you have the timegm function. */
+#undef HAVE_TIMEGM
+
+/* Define if you have the times function. */
+#undef HAVE_TIMES
+
+/* Define if you have the tmpfile function. */
+#define HAVE_TMPFILE
+
+/* Define if you have the tmpnam function. */
+#define HAVE_TMPNAM
+
+/* Define if you have the tmpnam_r function. */
+#undef HAVE_TMPNAM_R
+
+/* Define if you have the truncate function. */
+#define HAVE_TRUNCATE
+
+/* Define if you have the uname function. */
+#undef HAVE_UNAME
+
+/* Define if you have the waitpid function. */
+#undef HAVE_WAITPID
+
+/* Define if you have the <db.h> header file. */
+#undef HAVE_DB_H
+
+/* Define if you have the <db1/ndbm.h> header file. */
+#undef HAVE_DB1_NDBM_H
+
+/* Define if you have the <db_185.h> header file. */
+#undef HAVE_DB_185_H
+
+/* Define if you have the <dirent.h> header file. */
+#ifdef USE_GUSI
+#define HAVE_DIRENT_H
+#endif
+
+/* Define if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H
+
+/* Define if you have the <gdbm/ndbm.h> header file. */
+#undef HAVE_GDBM_NDBM_H
+
+/* Define if you have the <libutil.h> header file. */
+#undef HAVE_LIBUTIL_H
+
+/* Define if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H
+
+/* Define if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H
+
+/* Define if you have the <ncurses.h> header file. */
+#undef HAVE_NCURSES_H
+
+/* Define if you have the <ndbm.h> header file. */
+#undef HAVE_NDBM_H
+
+/* Define if you have the <ndir.h> header file. */
+#undef HAVE_NDIR_H
+
+/* Define if you have the <poll.h> header file. */
+#undef HAVE_POLL_H
+
+/* Define if you have the <pthread.h> header file. */
+#ifdef USE_GUSI2
+#define HAVE_PTHREAD_H
+#endif
+
+/* Define if you have the <pty.h> header file. */
+#undef HAVE_PTY_H
+
+/* Define if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H
+
+/* Define if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H
+
+/* Define if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H
+
+/* Define if you have the <sys/audioio.h> header file. */
+#undef HAVE_SYS_AUDIOIO_H
+
+/* Define if you have the <sys/dir.h> header file. */
+#undef HAVE_SYS_DIR_H
+
+/* Define if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define if you have the <sys/lock.h> header file. */
+#undef HAVE_SYS_LOCK_H
+
+/* Define if you have the <sys/modem.h> header file. */
+#undef HAVE_SYS_MODEM_H
+
+/* Define if you have the <sys/ndir.h> header file. */
+#undef HAVE_SYS_NDIR_H
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define if you have the <sys/socket.h> header file. */
+#ifdef USE_GUSI
+#define HAVE_SYS_SOCKET_H
+#endif
+
+/* Define if you have the <sys/time.h> header file. */
+#ifdef USE_GUSI
+#define HAVE_SYS_TIME_H
+#endif
+
+/* Define if you have the <sys/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
+
+/* Define if you have the <sys/un.h> header file. */
+#undef HAVE_SYS_UN_H
+
+/* Define if you have the <sys/utsname.h> header file. */
+#undef HAVE_SYS_UTSNAME_H
+
+/* Define if you have the <sys/wait.h> header file. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define if you have the <thread.h> header file. */
+#undef HAVE_THREAD_H
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H
+
+/* Define if you have the <utime.h> header file. */
+#define HAVE_UTIME_H
+
+/* Define if you have the dl library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define if you have the dld library (-ldld). */
+#undef HAVE_LIBDLD
+
+/* Define if you have the ieee library (-lieee). */
+#undef HAVE_LIBIEEE
+
+#ifdef __CYGWIN__
+#ifdef USE_DL_IMPORT
+#define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE
+#define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE
+#else
+#define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE
+#define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE
+#endif
+#endif
--- /dev/null
+/***********************************************************
+Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+#ifdef WITHOUT_FRAMEWORKS
+#include <Types.h>
+#include <Files.h>
+#include <Events.h>
+#include <StandardFile.h>
+#else
+#include <Carbon/Carbon.h>
+#endif
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Scheduler parameters */
+typedef struct {
+ int check_interrupt; /* if true check for command-dot */
+ int process_events; /* if nonzero enable evt processing, this mask */
+ int besocial; /* Be social, give up CPU now and again */
+ double check_interval; /* how often to check */
+ double bg_yield; /* yield at most so long when in background */
+} PyMacSchedParams;
+
+char *PyMac_getscript(void); /* Get the default encoding for our 8bit character set */
+#ifdef USE_GUSI1
+void PyMac_FixGUSIcd(void); /* Workaround for GUSI chdir() call */
+extern void PyMac_SetGUSISpin(void); /* Install our private GUSI spin routine */
+#endif
+
+char *PyMac_StrError(int); /* strerror with mac errors */
+PyObject *PyErr_Mac(PyObject *, int); /* Exception with a mac error */
+PyObject *PyMac_Error(OSErr); /* Uses PyMac_GetOSErrException */
+unsigned char *Pstring(char *str); /* Convert c-string to pascal-string in static buffer */
+
+#ifdef USE_GUSI
+extern int PyMac_ConsoleIsDead; /* True when exiting */
+extern void PyMac_StopGUSISpin(void); /* Stop eventprocessing during exit() */
+#endif
+
+extern short PyMac_AppRefNum; /* RefNum of application rsrcfork (from macmain.c) */
+extern FSSpec PyMac_ApplicationFSSpec; /* Application location (from macargv.c) */
+extern char PyMac_ApplicationPath[]; /* Application location (from macargv.c) */
+extern OSErr PyMac_init_application_location(void); /* Init the above */
+extern OSErr PyMac_GetFullPath(FSSpec *, char *); /* convert fsspec->path (macargv.c) */
+extern int PyMac_GetArgv(char ***, int); /* Get argc, argv (from macargv.c) */
+extern int PyMac_AppearanceCompliant; /* True if in appearance support mode */
+
+extern PyObject *PyMac_OSErrException; /* Exception for OSErr */
+PyObject *PyMac_GetOSErrException(void); /* Initialize & return it */
+
+#if !TARGET_API_MAC_OSX
+void PyMac_GetSchedParams(PyMacSchedParams *); /* Get schedulers params */
+void PyMac_SetSchedParams(PyMacSchedParams *); /* Set schedulers params */
+int PyMac_DoYield(int, int); /* Yield cpu. First arg is maxtime, second ok to call python */
+#endif
+int PyMac_HandleEvent(EventRecord *); /* Handle one event, possibly in Python */
+void PyMac_HandleEventIntern(EventRecord *); /* Handle one event internal only */
+int PyMac_SetEventHandler(PyObject *); /* set python-coded event handler */
+
+#if !TARGET_API_MAC_OSX
+void PyMac_InitMenuBar(void); /* Setup menu bar as we want it */
+void PyMac_RestoreMenuBar(void); /* Restore menu bar for ease of exiting */
+void PyMac_RaiseConsoleWindow(); /* Bring console window to front, if it exists */
+#endif
+int PyMac_FindResourceModule(PyStringObject *, char *, char *); /* Test for 'PYC ' resource in a file */
+PyObject * PyMac_LoadResourceModule(char *, char *); /* Load 'PYC ' resource from file */
+int PyMac_FindCodeResourceModule(PyStringObject *, char *, char *); /* Test for 'PYD ' resource in a file */
+PyObject * PyMac_LoadCodeResourceModule(char *, char *); /* Load 'PYD ' resource from file */
+struct filedescr *PyMac_FindModuleExtension(char *, size_t *, char *); /* Look for module in single folder */
+
+#if TARGET_API_MAC_OS8
+int PyMac_GetDirectory(FSSpec *dirfss, char *prompt); /* Ask user for a directory */
+void PyMac_PromptGetFile(short numTypes, ConstSFTypeListPtr typeList,
+ StandardFileReply *reply, char *prompt); /* Ask user for file, with prompt */
+#endif /* TARGET_API_MAC_OS8 */
+
+int PyMac_GetOSType(PyObject *, OSType *); /* argument parser for OSType */
+PyObject *PyMac_BuildOSType(OSType); /* Convert OSType to PyObject */
+
+PyObject *PyMac_BuildNumVersion(NumVersion); /* Convert NumVersion to PyObject */
+
+int PyMac_GetStr255(PyObject *, Str255); /* argument parser for Str255 */
+PyObject *PyMac_BuildStr255(Str255); /* Convert Str255 to PyObject */
+PyObject *PyMac_BuildOptStr255(Str255); /* Convert Str255 to PyObject, NULL to None */
+
+int PyMac_GetRect(PyObject *, Rect *); /* argument parser for Rect */
+PyObject *PyMac_BuildRect(Rect *); /* Convert Rect to PyObject */
+
+int PyMac_GetPoint(PyObject *, Point *); /* argument parser for Point */
+PyObject *PyMac_BuildPoint(Point); /* Convert Point to PyObject */
+
+int PyMac_GetEventRecord(PyObject *, EventRecord *); /* argument parser for EventRecord */
+PyObject *PyMac_BuildEventRecord(EventRecord *); /* Convert EventRecord to PyObject */
+
+int PyMac_GetFixed(PyObject *, Fixed *); /* argument parser for Fixed */
+PyObject *PyMac_BuildFixed(Fixed); /* Convert Fixed to PyObject */
+int PyMac_Getwide(PyObject *, wide *); /* argument parser for wide */
+PyObject *PyMac_Buildwide(wide *); /* Convert wide to PyObject */
+void PyMac_InitApplet(void); /* Initialize and run an Applet */
+void PyMac_Initialize(void); /* Initialize function for embedding Python */
+
+#ifdef USE_GUSI2
+short PyMac_OpenPrefFile(void); /* From macgetpath.c, open and return preference file */
+#endif
+
+/* from macfsmodule.c: */
+int PyMac_GetFSSpec(PyObject *, FSSpec *); /* argument parser for FSSpec */
+PyObject *PyMac_BuildFSSpec(FSSpec *); /* Convert FSSpec to PyObject */
+
+int PyMac_GetFSRef(PyObject *, FSRef *); /* argument parser for FSRef */
+PyObject *PyMac_BuildFSRef(FSRef *); /* Convert FSRef to PyObject */
+
+
+/* From macfiletype.c: */
+
+long PyMac_getfiletype(char *); /* Get file type */
+int PyMac_setfiletype(char *, long, long); /* Set file creator and type */
+
+/* from macmain.c: */
+void PyMac_Exit(int);
+void PyMac_InitApplication(void);
+void PyMac_OutputSeen(void);
+void PyMac_OutputNotSeen(void);
+int PyMac_GetDelayConsoleFlag(void);
+#ifdef USE_MAC_APPLET_SUPPORT
+void PyMac_InitApplet(void);
+#endif
+
+/* from macgetargv: */
+OSErr PyMac_init_process_location(void);
+#ifndef HAVE_STRDUP
+char * strdup(const char *str);
+#endif
+
+#ifdef __cplusplus
+ }
+#endif
--- /dev/null
+"""Easy to use dialogs.
+
+Message(msg) -- display a message and an OK button.
+AskString(prompt, default) -- ask for a string, display OK and Cancel buttons.
+AskPassword(prompt, default) -- like AskString(), but shows text as bullets.
+AskYesNoCancel(question, default) -- display a question and Yes, No and Cancel buttons.
+bar = Progress(label, maxvalue) -- Display a progress bar
+bar.set(value) -- Set value
+bar.inc( *amount ) -- increment value by amount (default=1)
+bar.label( *newlabel ) -- get or set text label.
+
+More documentation in each function.
+This module uses DLOG resources 260 and on.
+Based upon STDWIN dialogs with the same names and functions.
+"""
+
+from Dlg import GetNewDialog, SetDialogItemText, GetDialogItemText, ModalDialog
+import Qd
+import QuickDraw
+import Dialogs
+import Windows
+import Dlg,Win,Evt,Events # sdm7g
+import Ctl
+import Controls
+import Menu
+import MacOS
+import string
+from ControlAccessor import * # Also import Controls constants
+import macfs
+
+def cr2lf(text):
+ if '\r' in text:
+ text = string.join(string.split(text, '\r'), '\n')
+ return text
+
+def lf2cr(text):
+ if '\n' in text:
+ text = string.join(string.split(text, '\n'), '\r')
+ if len(text) > 253:
+ text = text[:253] + '\311'
+ return text
+
+def Message(msg, id=260, ok=None):
+ """Display a MESSAGE string.
+
+ Return when the user clicks the OK button or presses Return.
+
+ The MESSAGE string can be at most 255 characters long.
+ """
+
+ d = GetNewDialog(id, -1)
+ if not d:
+ print "Can't get DLOG resource with id =", id
+ return
+ h = d.GetDialogItemAsControl(2)
+ SetDialogItemText(h, lf2cr(msg))
+ if ok != None:
+ h = d.GetDialogItemAsControl(1)
+ h.SetControlTitle(ok)
+ d.SetDialogDefaultItem(1)
+ d.AutoSizeDialog()
+ d.GetDialogWindow().ShowWindow()
+ while 1:
+ n = ModalDialog(None)
+ if n == 1:
+ return
+
+
+def AskString(prompt, default = "", id=261, ok=None, cancel=None):
+ """Display a PROMPT string and a text entry field with a DEFAULT string.
+
+ Return the contents of the text entry field when the user clicks the
+ OK button or presses Return.
+ Return None when the user clicks the Cancel button.
+
+ If omitted, DEFAULT is empty.
+
+ The PROMPT and DEFAULT strings, as well as the return value,
+ can be at most 255 characters long.
+ """
+
+ d = GetNewDialog(id, -1)
+ if not d:
+ print "Can't get DLOG resource with id =", id
+ return
+ h = d.GetDialogItemAsControl(3)
+ SetDialogItemText(h, lf2cr(prompt))
+ h = d.GetDialogItemAsControl(4)
+ SetDialogItemText(h, lf2cr(default))
+ d.SelectDialogItemText(4, 0, 999)
+# d.SetDialogItem(4, 0, 255)
+ if ok != None:
+ h = d.GetDialogItemAsControl(1)
+ h.SetControlTitle(ok)
+ if cancel != None:
+ h = d.GetDialogItemAsControl(2)
+ h.SetControlTitle(cancel)
+ d.SetDialogDefaultItem(1)
+ d.SetDialogCancelItem(2)
+ d.AutoSizeDialog()
+ d.GetDialogWindow().ShowWindow()
+ while 1:
+ n = ModalDialog(None)
+ if n == 1:
+ h = d.GetDialogItemAsControl(4)
+ return cr2lf(GetDialogItemText(h))
+ if n == 2: return None
+
+def AskPassword(prompt, default='', id=264, ok=None, cancel=None):
+ """Display a PROMPT string and a text entry field with a DEFAULT string.
+ The string is displayed as bullets only.
+
+ Return the contents of the text entry field when the user clicks the
+ OK button or presses Return.
+ Return None when the user clicks the Cancel button.
+
+ If omitted, DEFAULT is empty.
+
+ The PROMPT and DEFAULT strings, as well as the return value,
+ can be at most 255 characters long.
+ """
+ d = GetNewDialog(id, -1)
+ if not d:
+ print "Can't get DLOG resource with id =", id
+ return
+ h = d.GetDialogItemAsControl(3)
+ SetDialogItemText(h, lf2cr(prompt))
+ pwd = d.GetDialogItemAsControl(4)
+ bullets = '\245'*len(default)
+## SetControlData(pwd, kControlEditTextPart, kControlEditTextTextTag, bullets)
+ SetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag, default)
+ d.SelectDialogItemText(4, 0, 999)
+ Ctl.SetKeyboardFocus(d.GetDialogWindow(), pwd, kControlEditTextPart)
+ if ok != None:
+ h = d.GetDialogItemAsControl(1)
+ h.SetControlTitle(ok)
+ if cancel != None:
+ h = d.GetDialogItemAsControl(2)
+ h.SetControlTitle(cancel)
+ d.SetDialogDefaultItem(Dialogs.ok)
+ d.SetDialogCancelItem(Dialogs.cancel)
+ d.AutoSizeDialog()
+ d.GetDialogWindow().ShowWindow()
+ while 1:
+ n = ModalDialog(None)
+ if n == 1:
+ h = d.GetDialogItemAsControl(4)
+ return cr2lf(GetControlData(pwd, kControlEditTextPart, kControlEditTextPasswordTag))
+ if n == 2: return None
+
+def AskYesNoCancel(question, default = 0, yes=None, no=None, cancel=None, id=262):
+ """Display a QUESTION string which can be answered with Yes or No.
+
+ Return 1 when the user clicks the Yes button.
+ Return 0 when the user clicks the No button.
+ Return -1 when the user clicks the Cancel button.
+
+ When the user presses Return, the DEFAULT value is returned.
+ If omitted, this is 0 (No).
+
+ The QUESTION string can be at most 255 characters.
+ """
+
+ d = GetNewDialog(id, -1)
+ if not d:
+ print "Can't get DLOG resource with id =", id
+ return
+ # Button assignments:
+ # 1 = default (invisible)
+ # 2 = Yes
+ # 3 = No
+ # 4 = Cancel
+ # The question string is item 5
+ h = d.GetDialogItemAsControl(5)
+ SetDialogItemText(h, lf2cr(question))
+ if yes != None:
+ if yes == '':
+ d.HideDialogItem(2)
+ else:
+ h = d.GetDialogItemAsControl(2)
+ h.SetControlTitle(yes)
+ if no != None:
+ if no == '':
+ d.HideDialogItem(3)
+ else:
+ h = d.GetDialogItemAsControl(3)
+ h.SetControlTitle(no)
+ if cancel != None:
+ if cancel == '':
+ d.HideDialogItem(4)
+ else:
+ h = d.GetDialogItemAsControl(4)
+ h.SetControlTitle(cancel)
+ d.SetDialogCancelItem(4)
+ if default == 1:
+ d.SetDialogDefaultItem(2)
+ elif default == 0:
+ d.SetDialogDefaultItem(3)
+ elif default == -1:
+ d.SetDialogDefaultItem(4)
+ d.AutoSizeDialog()
+ d.GetDialogWindow().ShowWindow()
+ while 1:
+ n = ModalDialog(None)
+ if n == 1: return default
+ if n == 2: return 1
+ if n == 3: return 0
+ if n == 4: return -1
+
+
+
+
+screenbounds = Qd.qd.screenBits.bounds
+screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
+ screenbounds[2]-4, screenbounds[3]-4
+
+
+class ProgressBar:
+ def __init__(self, title="Working...", maxval=100, label="", id=263):
+ self.w = None
+ self.d = None
+ self.maxval = maxval
+ self.curval = -1
+ self.d = GetNewDialog(id, -1)
+ self.w = self.d.GetDialogWindow()
+ self.label(label)
+ self._update(0)
+ self.d.AutoSizeDialog()
+ self.title(title)
+ self.w.ShowWindow()
+ self.d.DrawDialog()
+
+ def __del__( self ):
+ if self.w:
+ self.w.BringToFront()
+ self.w.HideWindow()
+ del self.w
+ del self.d
+
+ def title(self, newstr=""):
+ """title(text) - Set title of progress window"""
+ self.w.BringToFront()
+ self.w.SetWTitle(newstr)
+
+ def label( self, *newstr ):
+ """label(text) - Set text in progress box"""
+ self.w.BringToFront()
+ if newstr:
+ self._label = lf2cr(newstr[0])
+ text_h = self.d.GetDialogItemAsControl(2)
+ SetDialogItemText(text_h, self._label)
+
+ def _update(self, value):
+ maxval = self.maxval
+ if maxval == 0:
+ # XXXX Quick fix. Should probably display an unknown duration
+ value = 0
+ maxval = 1
+ if maxval > 32767:
+ value = int(value/(maxval/32767.0))
+ maxval = 32767
+ progbar = self.d.GetDialogItemAsControl(3)
+ progbar.SetControlMaximum(maxval)
+ progbar.SetControlValue(value)
+ # Test for cancel button
+
+ ready, ev = Evt.WaitNextEvent( Events.mDownMask, 1 )
+ if ready :
+ what,msg,when,where,mod = ev
+ part = Win.FindWindow(where)[0]
+ if Dlg.IsDialogEvent(ev):
+ ds = Dlg.DialogSelect(ev)
+ if ds[0] and ds[1] == self.d and ds[-1] == 1:
+ self.w.HideWindow()
+ self.w = None
+ self.d = None
+ raise KeyboardInterrupt, ev
+ else:
+ if part == 4: # inDrag
+ self.d.DragWindow(where, screenbounds)
+ else:
+ MacOS.HandleEvent(ev)
+
+
+ def set(self, value, max=None):
+ """set(value) - Set progress bar position"""
+ if max != None:
+ self.maxval = max
+ if value < 0: value = 0
+ if value > self.maxval: value = self.maxval
+ self.curval = value
+ self._update(value)
+
+ def inc(self, n=1):
+ """inc(amt) - Increment progress bar position"""
+ self.set(self.curval + n)
+
+ARGV_ID=265
+ARGV_ITEM_OK=1
+ARGV_ITEM_CANCEL=2
+ARGV_OPTION_GROUP=3
+ARGV_OPTION_EXPLAIN=4
+ARGV_OPTION_VALUE=5
+ARGV_OPTION_ADD=6
+ARGV_COMMAND_GROUP=7
+ARGV_COMMAND_EXPLAIN=8
+ARGV_COMMAND_ADD=9
+ARGV_ADD_OLDFILE=10
+ARGV_ADD_NEWFILE=11
+ARGV_ADD_FOLDER=12
+ARGV_CMDLINE_GROUP=13
+ARGV_CMDLINE_DATA=14
+
+##def _myModalDialog(d):
+## while 1:
+## ready, ev = Evt.WaitNextEvent(0xffff, -1)
+## print 'DBG: WNE', ready, ev
+## if ready :
+## what,msg,when,where,mod = ev
+## part, window = Win.FindWindow(where)
+## if Dlg.IsDialogEvent(ev):
+## didit, dlgdone, itemdone = Dlg.DialogSelect(ev)
+## print 'DBG: DialogSelect', didit, dlgdone, itemdone, d
+## if didit and dlgdone == d:
+## return itemdone
+## elif window == d.GetDialogWindow():
+## d.GetDialogWindow().SelectWindow()
+## if part == 4: # inDrag
+## d.DragWindow(where, screenbounds)
+## else:
+## MacOS.HandleEvent(ev)
+## else:
+## MacOS.HandleEvent(ev)
+##
+def _setmenu(control, items):
+ mhandle = control.GetControlData_Handle(Controls.kControlMenuPart,
+ Controls.kControlPopupButtonMenuHandleTag)
+ menu = Menu.as_Menu(mhandle)
+ for item in items:
+ if type(item) == type(()):
+ label = item[0]
+ else:
+ label = item
+ if label[-1] == '=' or label[-1] == ':':
+ label = label[:-1]
+ menu.AppendMenu(label)
+## mhandle, mid = menu.getpopupinfo()
+## control.SetControlData_Handle(Controls.kControlMenuPart,
+## Controls.kControlPopupButtonMenuHandleTag, mhandle)
+ control.SetControlMinimum(1)
+ control.SetControlMaximum(len(items)+1)
+
+def _selectoption(d, optionlist, idx):
+ if idx < 0 or idx >= len(optionlist):
+ MacOS.SysBeep()
+ return
+ option = optionlist[idx]
+ if type(option) == type(()) and \
+ len(option) > 1:
+ help = option[-1]
+ else:
+ help = ''
+ h = d.GetDialogItemAsControl(ARGV_OPTION_EXPLAIN)
+ Dlg.SetDialogItemText(h, help)
+ hasvalue = 0
+ if type(option) == type(()):
+ label = option[0]
+ else:
+ label = option
+ if label[-1] == '=' or label[-1] == ':':
+ hasvalue = 1
+ h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
+ Dlg.SetDialogItemText(h, '')
+ if hasvalue:
+ d.ShowDialogItem(ARGV_OPTION_VALUE)
+ d.SelectDialogItemText(ARGV_OPTION_VALUE, 0, 0)
+ else:
+ d.HideDialogItem(ARGV_OPTION_VALUE)
+
+
+def GetArgv(optionlist=None, commandlist=None, addoldfile=1, addnewfile=1, addfolder=1, id=ARGV_ID):
+ d = GetNewDialog(id, -1)
+ if not d:
+ print "Can't get DLOG resource with id =", id
+ return
+# h = d.GetDialogItemAsControl(3)
+# SetDialogItemText(h, lf2cr(prompt))
+# h = d.GetDialogItemAsControl(4)
+# SetDialogItemText(h, lf2cr(default))
+# d.SelectDialogItemText(4, 0, 999)
+# d.SetDialogItem(4, 0, 255)
+ if optionlist:
+ _setmenu(d.GetDialogItemAsControl(ARGV_OPTION_GROUP), optionlist)
+ _selectoption(d, optionlist, 0)
+ else:
+ d.GetDialogItemAsControl(ARGV_OPTION_GROUP).DeactivateControl()
+ if commandlist:
+ _setmenu(d.GetDialogItemAsControl(ARGV_COMMAND_GROUP), commandlist)
+ if type(commandlist[0]) == type(()) and len(commandlist[0]) > 1:
+ help = commandlist[0][-1]
+ h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
+ Dlg.SetDialogItemText(h, help)
+ else:
+ d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).DeactivateControl()
+ if not addoldfile:
+ d.GetDialogItemAsControl(ARGV_ADD_OLDFILE).DeactivateControl()
+ if not addnewfile:
+ d.GetDialogItemAsControl(ARGV_ADD_NEWFILE).DeactivateControl()
+ if not addfolder:
+ d.GetDialogItemAsControl(ARGV_ADD_FOLDER).DeactivateControl()
+ d.SetDialogDefaultItem(ARGV_ITEM_OK)
+ d.SetDialogCancelItem(ARGV_ITEM_CANCEL)
+ d.GetDialogWindow().ShowWindow()
+ d.DrawDialog()
+ appsw = MacOS.SchedParams(1, 0)
+ try:
+ while 1:
+ stringstoadd = []
+ n = ModalDialog(None)
+ if n == ARGV_ITEM_OK:
+ break
+ elif n == ARGV_ITEM_CANCEL:
+ raise SystemExit
+ elif n == ARGV_OPTION_GROUP:
+ idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
+ _selectoption(d, optionlist, idx)
+ elif n == ARGV_OPTION_VALUE:
+ pass
+ elif n == ARGV_OPTION_ADD:
+ idx = d.GetDialogItemAsControl(ARGV_OPTION_GROUP).GetControlValue()-1
+ if 0 <= idx < len(optionlist):
+ option = optionlist[idx]
+ if type(option) == type(()):
+ option = option[0]
+ if option[-1] == '=' or option[-1] == ':':
+ option = option[:-1]
+ h = d.GetDialogItemAsControl(ARGV_OPTION_VALUE)
+ value = Dlg.GetDialogItemText(h)
+ else:
+ value = ''
+ if len(option) == 1:
+ stringtoadd = '-' + option
+ else:
+ stringtoadd = '--' + option
+ stringstoadd = [stringtoadd]
+ if value:
+ stringstoadd.append(value)
+ else:
+ MacOS.SysBeep()
+ elif n == ARGV_COMMAND_GROUP:
+ idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
+ if 0 <= idx < len(commandlist) and type(commandlist[idx]) == type(()) and \
+ len(commandlist[idx]) > 1:
+ help = commandlist[idx][-1]
+ h = d.GetDialogItemAsControl(ARGV_COMMAND_EXPLAIN)
+ Dlg.SetDialogItemText(h, help)
+ elif n == ARGV_COMMAND_ADD:
+ idx = d.GetDialogItemAsControl(ARGV_COMMAND_GROUP).GetControlValue()-1
+ if 0 <= idx < len(commandlist):
+ command = commandlist[idx]
+ if type(command) == type(()):
+ command = command[0]
+ stringstoadd = [command]
+ else:
+ MacOS.SysBeep()
+ elif n == ARGV_ADD_OLDFILE:
+ fss, ok = macfs.StandardGetFile()
+ if ok:
+ stringstoadd = [fss.as_pathname()]
+ elif n == ARGV_ADD_NEWFILE:
+ fss, ok = macfs.StandardPutFile('')
+ if ok:
+ stringstoadd = [fss.as_pathname()]
+ elif n == ARGV_ADD_FOLDER:
+ fss, ok = macfs.GetDirectory()
+ if ok:
+ stringstoadd = [fss.as_pathname()]
+ elif n == ARGV_CMDLINE_DATA:
+ pass # Nothing to do
+ else:
+ raise RuntimeError, "Unknown dialog item %d"%n
+
+ for stringtoadd in stringstoadd:
+ if '"' in stringtoadd or "'" in stringtoadd or " " in stringtoadd:
+ stringtoadd = `stringtoadd`
+ h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
+ oldstr = GetDialogItemText(h)
+ if oldstr and oldstr[-1] != ' ':
+ oldstr = oldstr + ' '
+ oldstr = oldstr + stringtoadd
+ if oldstr[-1] != ' ':
+ oldstr = oldstr + ' '
+ SetDialogItemText(h, oldstr)
+ d.SelectDialogItemText(ARGV_CMDLINE_DATA, 0x7fff, 0x7fff)
+ h = d.GetDialogItemAsControl(ARGV_CMDLINE_DATA)
+ oldstr = GetDialogItemText(h)
+ tmplist = string.split(oldstr)
+ newlist = []
+ while tmplist:
+ item = tmplist[0]
+ del tmplist[0]
+ if item[0] == '"':
+ while item[-1] != '"':
+ if not tmplist:
+ raise RuntimeError, "Unterminated quoted argument"
+ item = item + ' ' + tmplist[0]
+ del tmplist[0]
+ item = item[1:-1]
+ if item[0] == "'":
+ while item[-1] != "'":
+ if not tmplist:
+ raise RuntimeError, "Unterminated quoted argument"
+ item = item + ' ' + tmplist[0]
+ del tmplist[0]
+ item = item[1:-1]
+ newlist.append(item)
+ return newlist
+ finally:
+ apply(MacOS.SchedParams, appsw)
+ del d
+
+def test():
+ import time, sys
+
+ Message("Testing EasyDialogs.")
+ optionlist = (('v', 'Verbose'), ('verbose', 'Verbose as long option'),
+ ('flags=', 'Valued option'), ('f:', 'Short valued option'))
+ commandlist = (('start', 'Start something'), ('stop', 'Stop something'))
+ argv = GetArgv(optionlist=optionlist, commandlist=commandlist, addoldfile=0)
+ for i in range(len(argv)):
+ print 'arg[%d] = %s'%(i, `argv[i]`)
+ print 'Type return to continue - ',
+ sys.stdin.readline()
+ ok = AskYesNoCancel("Do you want to proceed?")
+ ok = AskYesNoCancel("Do you want to identify?", yes="Identify", no="No")
+ if ok > 0:
+ s = AskString("Enter your first name", "Joe")
+ s2 = AskPassword("Okay %s, tell us your nickname"%s, s, cancel="None")
+ if not s2:
+ Message("%s has no secret nickname"%s)
+ else:
+ Message("Hello everybody!!\nThe secret nickname of %s is %s!!!"%(s, s2))
+ text = ( "Working Hard...", "Hardly Working..." ,
+ "So far, so good!", "Keep on truckin'" )
+ bar = ProgressBar("Progress, progress...", 100)
+ try:
+ appsw = MacOS.SchedParams(1, 0)
+ for i in range(100):
+ bar.set(i)
+ time.sleep(0.1)
+ if i % 10 == 0:
+ bar.label(text[(i/10) % 4])
+ bar.label("Done.")
+ time.sleep(0.3) # give'em a chance to see the done.
+ finally:
+ del bar
+ apply(MacOS.SchedParams, appsw)
+
+if __name__ == '__main__':
+ try:
+ test()
+ except KeyboardInterrupt:
+ Message("Operation Canceled.")
+
--- /dev/null
+/***********************************************************
+Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+#include "Python.h"
+#include "macglue.h"
+
+#ifdef WITHOUT_FRAMEWORKS
+#include <Memory.h>
+#include <Files.h>
+#include <Folders.h>
+#include <StandardFile.h>
+#include <Aliases.h>
+#include <LowMem.h>
+#else
+#include <Carbon/Carbon.h>
+#endif
+
+#include "getapplbycreator.h"
+
+
+static PyObject *ErrorObject;
+
+/* ----------------------------------------------------- */
+/* Declarations for objects of type Alias */
+
+typedef struct {
+ PyObject_HEAD
+ AliasHandle alias;
+} mfsaobject;
+
+staticforward PyTypeObject Mfsatype;
+
+#define is_mfsaobject(v) ((v)->ob_type == &Mfsatype)
+
+/* ---------------------------------------------------------------- */
+/* Declarations for objects of type FSSpec */
+
+typedef struct {
+ PyObject_HEAD
+ FSSpec fsspec;
+} mfssobject;
+
+staticforward PyTypeObject Mfsstype;
+
+#define is_mfssobject(v) ((v)->ob_type == &Mfsstype)
+
+/* ---------------------------------------------------------------- */
+/* Declarations for objects of type FSRef */
+
+typedef struct {
+ PyObject_HEAD
+ FSRef fsref;
+} mfsrobject;
+
+staticforward PyTypeObject Mfsrtype;
+
+#define is_mfsrobject(v) ((v)->ob_type == &Mfsrtype)
+
+
+/* ---------------------------------------------------------------- */
+/* Declarations for objects of type FInfo */
+
+typedef struct {
+ PyObject_HEAD
+ FInfo finfo;
+} mfsiobject;
+
+staticforward PyTypeObject Mfsitype;
+
+#define is_mfsiobject(v) ((v)->ob_type == &Mfsitype)
+
+
+staticforward mfssobject *newmfssobject(FSSpec *fss); /* Forward */
+staticforward mfsrobject *newmfsrobject(FSRef *fsr); /* Forward */
+
+/* ---------------------------------------------------------------- */
+
+static PyObject *
+mfsa_Resolve(self, args)
+ mfsaobject *self;
+ PyObject *args;
+{
+ FSSpec from, *fromp, result;
+ Boolean changed;
+ OSErr err;
+
+ from.name[0] = 0;
+ if (!PyArg_ParseTuple(args, "|O&", PyMac_GetFSSpec, &from))
+ return NULL;
+ if (from.name[0] )
+ fromp = &from;
+ else
+ fromp = NULL;
+ err = ResolveAlias(fromp, self->alias, &result, &changed);
+ if ( err && err != fnfErr ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ return Py_BuildValue("(Oi)", newmfssobject(&result), (int)changed);
+}
+
+static PyObject *
+mfsa_GetInfo(self, args)
+ mfsaobject *self;
+ PyObject *args;
+{
+ Str63 value;
+ int i;
+ OSErr err;
+
+ if (!PyArg_ParseTuple(args, "i", &i))
+ return NULL;
+ err = GetAliasInfo(self->alias, (AliasInfoType)i, value);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return 0;
+ }
+ return PyString_FromStringAndSize((char *)&value[1], value[0]);
+}
+
+static PyObject *
+mfsa_Update(self, args)
+ mfsaobject *self;
+ PyObject *args;
+{
+ FSSpec target, fromfile, *fromfilep;
+ OSErr err;
+ Boolean changed;
+
+ fromfile.name[0] = 0;
+ if (!PyArg_ParseTuple(args, "O&|O&", PyMac_GetFSSpec, &target,
+ PyMac_GetFSSpec, &fromfile))
+ return NULL;
+ if ( fromfile.name[0] )
+ fromfilep = &fromfile;
+ else
+ fromfilep = NULL;
+ err = UpdateAlias(fromfilep, &target, self->alias, &changed);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return 0;
+ }
+ return Py_BuildValue("i", (int)changed);
+}
+
+static struct PyMethodDef mfsa_methods[] = {
+ {"Resolve", (PyCFunction)mfsa_Resolve, 1},
+ {"GetInfo", (PyCFunction)mfsa_GetInfo, 1},
+ {"Update", (PyCFunction)mfsa_Update, 1},
+
+ {NULL, NULL} /* sentinel */
+};
+
+/* ---------- */
+
+static PyObject *
+mfsa_getattr(self, name)
+ mfsaobject *self;
+ char *name;
+{
+ if ( strcmp(name, "data") == 0 ) {
+ int size;
+ PyObject *rv;
+
+ size = GetHandleSize((Handle)self->alias);
+ HLock((Handle)self->alias);
+ rv = PyString_FromStringAndSize(*(Handle)self->alias, size);
+ HUnlock((Handle)self->alias);
+ return rv;
+ }
+ return Py_FindMethod(mfsa_methods, (PyObject *)self, name);
+}
+
+static mfsaobject *
+newmfsaobject(AliasHandle alias)
+{
+ mfsaobject *self;
+
+ self = PyObject_NEW(mfsaobject, &Mfsatype);
+ if (self == NULL)
+ return NULL;
+ self->alias = alias;
+ return self;
+}
+
+
+static void
+mfsa_dealloc(self)
+ mfsaobject *self;
+{
+#if 0
+ if ( self->alias ) {
+ should we do something here?
+ }
+#endif
+
+ PyMem_DEL(self);
+}
+
+statichere PyTypeObject Mfsatype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "Alias", /*tp_name*/
+ sizeof(mfsaobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)mfsa_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)mfsa_getattr, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+};
+
+/* End of code for Alias objects */
+/* -------------------------------------------------------- */
+
+/* ---------------------------------------------------------------- */
+
+static struct PyMethodDef mfsi_methods[] = {
+
+ {NULL, NULL} /* sentinel */
+};
+
+/* ---------- */
+
+static mfsiobject *
+newmfsiobject()
+{
+ mfsiobject *self;
+
+ self = PyObject_NEW(mfsiobject, &Mfsitype);
+ if (self == NULL)
+ return NULL;
+ memset((char *)&self->finfo, '\0', sizeof(self->finfo));
+ return self;
+}
+
+static void
+mfsi_dealloc(self)
+ mfsiobject *self;
+{
+ PyMem_DEL(self);
+}
+
+static PyObject *
+mfsi_getattr(self, name)
+ mfsiobject *self;
+ char *name;
+{
+ if ( strcmp(name, "Type") == 0 )
+ return PyMac_BuildOSType(self->finfo.fdType);
+ else if ( strcmp(name, "Creator") == 0 )
+ return PyMac_BuildOSType(self->finfo.fdCreator);
+ else if ( strcmp(name, "Flags") == 0 )
+ return Py_BuildValue("i", (int)self->finfo.fdFlags);
+ else if ( strcmp(name, "Location") == 0 )
+ return PyMac_BuildPoint(self->finfo.fdLocation);
+ else if ( strcmp(name, "Fldr") == 0 )
+ return Py_BuildValue("i", (int)self->finfo.fdFldr);
+ else
+ return Py_FindMethod(mfsi_methods, (PyObject *)self, name);
+}
+
+
+static int
+mfsi_setattr(self, name, v)
+ mfsiobject *self;
+ char *name;
+ PyObject *v;
+{
+ int rv;
+ int i;
+
+ if ( v == NULL ) {
+ PyErr_SetString(PyExc_AttributeError, "Cannot delete attribute");
+ return -1;
+ }
+ if ( strcmp(name, "Type") == 0 )
+ rv = PyMac_GetOSType(v, &self->finfo.fdType);
+ else if ( strcmp(name, "Creator") == 0 )
+ rv = PyMac_GetOSType(v, &self->finfo.fdCreator);
+ else if ( strcmp(name, "Flags") == 0 ) {
+ rv = PyArg_Parse(v, "i", &i);
+ self->finfo.fdFlags = (short)i;
+ } else if ( strcmp(name, "Location") == 0 )
+ rv = PyMac_GetPoint(v, &self->finfo.fdLocation);
+ else if ( strcmp(name, "Fldr") == 0 ) {
+ rv = PyArg_Parse(v, "i", &i);
+ self->finfo.fdFldr = (short)i;
+ } else {
+ PyErr_SetString(PyExc_AttributeError, "No such attribute");
+ return -1;
+ }
+ if (rv)
+ return 0;
+ return -1;
+}
+
+
+static PyTypeObject Mfsitype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "FInfo", /*tp_name*/
+ sizeof(mfsiobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)mfsi_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)mfsi_getattr, /*tp_getattr*/
+ (setattrfunc)mfsi_setattr, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+};
+
+/* End of code for FInfo object objects */
+/* -------------------------------------------------------- */
+
+
+/*
+** Helper routines for the FSRef and FSSpec creators in macglue.c
+** They return an FSSpec/FSRef if the Python object encapsulating
+** either is passed. They return a boolean success indicator.
+** Note that they do not set an exception on failure, they're only
+** helper routines.
+*/
+static int
+_mfs_GetFSSpecFromFSSpec(PyObject *self, FSSpec *fssp)
+{
+ if ( is_mfssobject(self) ) {
+ *fssp = ((mfssobject *)self)->fsspec;
+ return 1;
+ }
+ return 0;
+}
+
+/* Return an FSSpec if this is an FSref */
+static int
+_mfs_GetFSSpecFromFSRef(PyObject *self, FSSpec *fssp)
+{
+ static FSRef *fsrp;
+
+ if ( is_mfsrobject(self) ) {
+ fsrp = &((mfsrobject *)self)->fsref;
+ if ( FSGetCatalogInfo(&((mfsrobject *)self)->fsref, kFSCatInfoNone, NULL, NULL, fssp, NULL) == noErr )
+ return 1;
+ }
+ return 0;
+}
+
+/* Return an FSRef if this is an FSRef */
+static int
+_mfs_GetFSRefFromFSRef(PyObject *self, FSRef *fsrp)
+{
+ if ( is_mfsrobject(self) ) {
+ *fsrp = ((mfsrobject *)self)->fsref;
+ return 1;
+ }
+ return 0;
+}
+
+/* Return an FSRef if this is an FSSpec */
+static int
+_mfs_GetFSRefFromFSSpec(PyObject *self, FSRef *fsrp)
+{
+ if ( is_mfssobject(self) ) {
+ if ( FSpMakeFSRef(&((mfssobject *)self)->fsspec, fsrp) == noErr )
+ return 1;
+ }
+ return 0;
+}
+
+/*
+** Two generally useful routines
+*/
+static OSErr
+PyMac_GetFileDates(fss, crdat, mddat, bkdat)
+ FSSpec *fss;
+ unsigned long *crdat, *mddat, *bkdat;
+{
+ CInfoPBRec pb;
+ OSErr error;
+
+ pb.dirInfo.ioNamePtr = fss->name;
+ pb.dirInfo.ioFDirIndex = 0;
+ pb.dirInfo.ioVRefNum = fss->vRefNum;
+ pb.dirInfo.ioDrDirID = fss->parID;
+ error = PBGetCatInfoSync(&pb);
+ if ( error ) return error;
+ *crdat = pb.hFileInfo.ioFlCrDat;
+ *mddat = pb.hFileInfo.ioFlMdDat;
+ *bkdat = pb.hFileInfo.ioFlBkDat;
+ return 0;
+}
+
+static OSErr
+PyMac_SetFileDates(fss, crdat, mddat, bkdat)
+ FSSpec *fss;
+ unsigned long crdat, mddat, bkdat;
+{
+ CInfoPBRec pb;
+ OSErr error;
+
+ pb.dirInfo.ioNamePtr = fss->name;
+ pb.dirInfo.ioFDirIndex = 0;
+ pb.dirInfo.ioVRefNum = fss->vRefNum;
+ pb.dirInfo.ioDrDirID = fss->parID;
+ error = PBGetCatInfoSync(&pb);
+ if ( error ) return error;
+ pb.dirInfo.ioNamePtr = fss->name;
+ pb.dirInfo.ioFDirIndex = 0;
+ pb.dirInfo.ioVRefNum = fss->vRefNum;
+ pb.dirInfo.ioDrDirID = fss->parID;
+ pb.hFileInfo.ioFlCrDat = crdat;
+ pb.hFileInfo.ioFlMdDat = mddat;
+ pb.hFileInfo.ioFlBkDat = bkdat;
+ error = PBSetCatInfoSync(&pb);
+ return error;
+}
+
+static PyObject *
+mfss_as_pathname(self, args)
+ mfssobject *self;
+ PyObject *args;
+{
+ char strbuf[257];
+ OSErr err;
+
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+ err = PyMac_GetFullPath(&self->fsspec, strbuf);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ return PyString_FromString(strbuf);
+}
+
+static PyObject *
+mfss_as_tuple(self, args)
+ mfssobject *self;
+ PyObject *args;
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+ return Py_BuildValue("(iis#)", self->fsspec.vRefNum, self->fsspec.parID,
+ &self->fsspec.name[1], self->fsspec.name[0]);
+}
+
+static PyObject *
+mfss_NewAlias(self, args)
+ mfssobject *self;
+ PyObject *args;
+{
+ FSSpec src, *srcp;
+ OSErr err;
+ AliasHandle alias;
+
+ src.name[0] = 0;
+ if (!PyArg_ParseTuple(args, "|O&", PyMac_GetFSSpec, &src))
+ return NULL;
+ if ( src.name[0] )
+ srcp = &src;
+ else
+ srcp = NULL;
+ err = NewAlias(srcp, &self->fsspec, &alias);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+
+ return (PyObject *)newmfsaobject(alias);
+}
+
+static PyObject *
+mfss_NewAliasMinimal(self, args)
+ mfssobject *self;
+ PyObject *args;
+{
+ OSErr err;
+ AliasHandle alias;
+
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+ err = NewAliasMinimal(&self->fsspec, &alias);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ return (PyObject *)newmfsaobject(alias);
+}
+
+static PyObject *
+mfss_FSpMakeFSRef(self, args)
+ mfssobject *self;
+ PyObject *args;
+{
+ OSErr err;
+ FSRef fsref;
+
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+ err = FSpMakeFSRef(&self->fsspec, &fsref);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ return (PyObject *)newmfsrobject(&fsref);
+}
+
+/* XXXX These routines should be replaced by a wrapper to the *FInfo routines */
+static PyObject *
+mfss_GetCreatorType(self, args)
+ mfssobject *self;
+ PyObject *args;
+{
+ OSErr err;
+ FInfo info;
+
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+ err = FSpGetFInfo(&self->fsspec, &info);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ return Py_BuildValue("(O&O&)",
+ PyMac_BuildOSType, info.fdCreator, PyMac_BuildOSType, info.fdType);
+}
+
+static PyObject *
+mfss_SetCreatorType(self, args)
+ mfssobject *self;
+ PyObject *args;
+{
+ OSErr err;
+ OSType creator, type;
+ FInfo info;
+
+ if (!PyArg_ParseTuple(args, "O&O&", PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
+ return NULL;
+ err = FSpGetFInfo(&self->fsspec, &info);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ info.fdType = type;
+ info.fdCreator = creator;
+ err = FSpSetFInfo(&self->fsspec, &info);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+mfss_GetFInfo(self, args)
+ mfssobject *self;
+ PyObject *args;
+{
+ OSErr err;
+ mfsiobject *fip;
+
+
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+ if ( (fip=newmfsiobject()) == NULL )
+ return NULL;
+ err = FSpGetFInfo(&self->fsspec, &fip->finfo);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ Py_DECREF(fip);
+ return NULL;
+ }
+ return (PyObject *)fip;
+}
+
+static PyObject *
+mfss_SetFInfo(self, args)
+ mfssobject *self;
+ PyObject *args;
+{
+ OSErr err;
+ mfsiobject *fip;
+
+ if (!PyArg_ParseTuple(args, "O!", &Mfsitype, &fip))
+ return NULL;
+ err = FSpSetFInfo(&self->fsspec, &fip->finfo);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+mfss_GetDates(self, args)
+ mfssobject *self;
+ PyObject *args;
+{
+ OSErr err;
+ unsigned long crdat, mddat, bkdat;
+
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+ err = PyMac_GetFileDates(&self->fsspec, &crdat, &mddat, &bkdat);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ return Py_BuildValue("ddd", (double)crdat, (double)mddat, (double)bkdat);
+}
+
+static PyObject *
+mfss_SetDates(self, args)
+ mfssobject *self;
+ PyObject *args;
+{
+ OSErr err;
+ double crdat, mddat, bkdat;
+
+ if (!PyArg_ParseTuple(args, "ddd", &crdat, &mddat, &bkdat))
+ return NULL;
+ err = PyMac_SetFileDates(&self->fsspec, (unsigned long)crdat,
+ (unsigned long)mddat, (unsigned long)bkdat);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static struct PyMethodDef mfss_methods[] = {
+ {"as_pathname", (PyCFunction)mfss_as_pathname, 1},
+ {"as_tuple", (PyCFunction)mfss_as_tuple, 1},
+ {"as_fsref", (PyCFunction)mfss_FSpMakeFSRef, 1},
+ {"FSpMakeFSRef", (PyCFunction)mfss_FSpMakeFSRef, 1},
+ {"NewAlias", (PyCFunction)mfss_NewAlias, 1},
+ {"NewAliasMinimal", (PyCFunction)mfss_NewAliasMinimal, 1},
+ {"GetCreatorType", (PyCFunction)mfss_GetCreatorType, 1},
+ {"SetCreatorType", (PyCFunction)mfss_SetCreatorType, 1},
+ {"GetFInfo", (PyCFunction)mfss_GetFInfo, 1},
+ {"SetFInfo", (PyCFunction)mfss_SetFInfo, 1},
+ {"GetDates", (PyCFunction)mfss_GetDates, 1},
+ {"SetDates", (PyCFunction)mfss_SetDates, 1},
+
+ {NULL, NULL} /* sentinel */
+};
+
+/* ---------- */
+
+static PyObject *
+mfss_getattr(self, name)
+ mfssobject *self;
+ char *name;
+{
+ if ( strcmp(name, "data") == 0)
+ return PyString_FromStringAndSize((char *)&self->fsspec, sizeof(FSSpec));
+ return Py_FindMethod(mfss_methods, (PyObject *)self, name);
+}
+
+mfssobject *
+newmfssobject(fss)
+ FSSpec *fss;
+{
+ mfssobject *self;
+
+ self = PyObject_NEW(mfssobject, &Mfsstype);
+ if (self == NULL)
+ return NULL;
+ self->fsspec = *fss;
+ return self;
+}
+
+static void
+mfss_dealloc(self)
+ mfssobject *self;
+{
+ PyMem_DEL(self);
+}
+
+static PyObject *
+mfss_repr(self)
+ mfssobject *self;
+{
+ char buf[512];
+
+ sprintf(buf, "FSSpec((%d, %d, '%.*s'))",
+ self->fsspec.vRefNum,
+ self->fsspec.parID,
+ self->fsspec.name[0], self->fsspec.name+1);
+ return PyString_FromString(buf);
+}
+
+static int
+mfss_compare(v, w)
+ mfssobject *v, *w;
+{
+ int minlen;
+ int res;
+
+ if ( v->fsspec.vRefNum < w->fsspec.vRefNum ) return -1;
+ if ( v->fsspec.vRefNum > w->fsspec.vRefNum ) return 1;
+ if ( v->fsspec.parID < w->fsspec.parID ) return -1;
+ if ( v->fsspec.parID > w->fsspec.parID ) return 1;
+ minlen = v->fsspec.name[0];
+ if ( w->fsspec.name[0] < minlen ) minlen = w->fsspec.name[0];
+ res = strncmp((char *)v->fsspec.name+1, (char *)w->fsspec.name+1, minlen);
+ if ( res ) return res;
+ if ( v->fsspec.name[0] < w->fsspec.name[0] ) return -1;
+ if ( v->fsspec.name[0] > w->fsspec.name[0] ) return 1;
+ return res;
+}
+
+statichere PyTypeObject Mfsstype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "FSSpec", /*tp_name*/
+ sizeof(mfssobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)mfss_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)mfss_getattr, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc)mfss_compare, /*tp_compare*/
+ (reprfunc)mfss_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+};
+
+/* End of code for FSSpec objects */
+/* -------------------------------------------------------- */
+
+static PyObject *
+mfsr_as_fsspec(self, args)
+ mfsrobject *self;
+ PyObject *args;
+{
+ OSErr err;
+ FSSpec fss;
+
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+ err = FSGetCatalogInfo(&self->fsref, kFSCatInfoNone, NULL, NULL, &fss, NULL);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return (PyObject *)newmfssobject(&fss);
+}
+
+static struct PyMethodDef mfsr_methods[] = {
+ {"as_fsspec", (PyCFunction)mfsr_as_fsspec, 1},
+#if 0
+ {"as_pathname", (PyCFunction)mfss_as_pathname, 1},
+ {"as_tuple", (PyCFunction)mfss_as_tuple, 1},
+ {"NewAlias", (PyCFunction)mfss_NewAlias, 1},
+ {"NewAliasMinimal", (PyCFunction)mfss_NewAliasMinimal, 1},
+ {"GetCreatorType", (PyCFunction)mfss_GetCreatorType, 1},
+ {"SetCreatorType", (PyCFunction)mfss_SetCreatorType, 1},
+ {"GetFInfo", (PyCFunction)mfss_GetFInfo, 1},
+ {"SetFInfo", (PyCFunction)mfss_SetFInfo, 1},
+ {"GetDates", (PyCFunction)mfss_GetDates, 1},
+ {"SetDates", (PyCFunction)mfss_SetDates, 1},
+#endif
+
+ {NULL, NULL} /* sentinel */
+};
+
+/* ---------- */
+
+static PyObject *
+mfsr_getattr(self, name)
+ mfsrobject *self;
+ char *name;
+{
+ if ( strcmp(name, "data") == 0)
+ return PyString_FromStringAndSize((char *)&self->fsref, sizeof(FSRef));
+ return Py_FindMethod(mfsr_methods, (PyObject *)self, name);
+}
+
+mfsrobject *
+newmfsrobject(fsr)
+ FSRef *fsr;
+{
+ mfsrobject *self;
+
+ self = PyObject_NEW(mfsrobject, &Mfsrtype);
+ if (self == NULL)
+ return NULL;
+ self->fsref = *fsr;
+ return self;
+}
+
+static int
+mfsr_compare(v, w)
+ mfsrobject *v, *w;
+{
+ OSErr err;
+
+ if ( v == w ) return 0;
+ err = FSCompareFSRefs(&v->fsref, &w->fsref);
+ if ( err == 0 )
+ return 0;
+ if (v < w )
+ return -1;
+ return 1;
+}
+
+static void
+mfsr_dealloc(self)
+ mfsrobject *self;
+{
+ PyMem_DEL(self);
+}
+
+statichere PyTypeObject Mfsrtype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "FSRef", /*tp_name*/
+ sizeof(mfsrobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)mfsr_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)mfsr_getattr, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc)mfsr_compare, /*tp_compare*/
+ (reprfunc)0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+};
+
+/* End of code for FSRef objects */
+/* -------------------------------------------------------- */
+
+static PyObject *
+mfs_ResolveAliasFile(self, args)
+ PyObject *self; /* Not used */
+ PyObject *args;
+{
+ FSSpec fss;
+ Boolean chain = 1, isfolder, wasaliased;
+ OSErr err;
+
+ if (!PyArg_ParseTuple(args, "O&|i", PyMac_GetFSSpec, &fss, &chain))
+ return NULL;
+ err = ResolveAliasFile(&fss, chain, &isfolder, &wasaliased);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ return Py_BuildValue("Oii", newmfssobject(&fss), (int)isfolder, (int)wasaliased);
+}
+
+#if !TARGET_API_MAC_CARBON
+static PyObject *
+mfs_StandardGetFile(self, args)
+ PyObject *self; /* Not used */
+ PyObject *args;
+{
+ SFTypeList list;
+ short numtypes;
+ StandardFileReply reply;
+
+ list[0] = list[1] = list[2] = list[3] = 0;
+ numtypes = 0;
+ if (!PyArg_ParseTuple(args, "|O&O&O&O&", PyMac_GetOSType, &list[0],
+ PyMac_GetOSType, &list[1], PyMac_GetOSType, &list[2],
+ PyMac_GetOSType, &list[3]) )
+ return NULL;
+ while ( numtypes < 4 && list[numtypes] ) {
+ numtypes++;
+ }
+ if ( numtypes == 0 )
+ numtypes = -1;
+ StandardGetFile((FileFilterUPP)0, numtypes, list, &reply);
+ return Py_BuildValue("(Oi)", newmfssobject(&reply.sfFile), reply.sfGood);
+}
+
+static PyObject *
+mfs_PromptGetFile(self, args)
+ PyObject *self; /* Not used */
+ PyObject *args;
+{
+ SFTypeList list;
+ short numtypes;
+ StandardFileReply reply;
+ char *prompt = NULL;
+
+ list[0] = list[1] = list[2] = list[3] = 0;
+ numtypes = 0;
+ if (!PyArg_ParseTuple(args, "s|O&O&O&O&", &prompt, PyMac_GetOSType, &list[0],
+ PyMac_GetOSType, &list[1], PyMac_GetOSType, &list[2],
+ PyMac_GetOSType, &list[3]) )
+ return NULL;
+ while ( numtypes < 4 && list[numtypes] ) {
+ numtypes++;
+ }
+ if ( numtypes == 0 )
+ numtypes = -1;
+ PyMac_PromptGetFile(numtypes, list, &reply, prompt);
+ return Py_BuildValue("(Oi)", newmfssobject(&reply.sfFile), reply.sfGood);
+}
+
+static PyObject *
+mfs_StandardPutFile(self, args)
+ PyObject *self; /* Not used */
+ PyObject *args;
+{
+ Str255 prompt, dft;
+ StandardFileReply reply;
+
+ dft[0] = 0;
+ if (!PyArg_ParseTuple(args, "O&|O&", PyMac_GetStr255, &prompt, PyMac_GetStr255, &dft) )
+ return NULL;
+ StandardPutFile(prompt, dft, &reply);
+ return Py_BuildValue("(Oi)",newmfssobject(&reply.sfFile), reply.sfGood);
+}
+
+/*
+** Set initial directory for file dialogs */
+static PyObject *
+mfs_SetFolder(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ FSSpec spec;
+ FSSpec ospec;
+ short orefnum;
+ long oparid;
+
+ /* Get old values */
+ orefnum = -LMGetSFSaveDisk();
+ oparid = LMGetCurDirStore();
+ (void)FSMakeFSSpec(orefnum, oparid, "\pplaceholder", &ospec);
+
+ /* Go to working directory by default */
+ (void)FSMakeFSSpec(0, 0, "\p:placeholder", &spec);
+ if (!PyArg_ParseTuple(args, "|O&", PyMac_GetFSSpec, &spec))
+ return NULL;
+ /* Set standard-file working directory */
+ LMSetSFSaveDisk(-spec.vRefNum);
+ LMSetCurDirStore(spec.parID);
+ return (PyObject *)newmfssobject(&ospec);
+}
+#endif
+
+static PyObject *
+mfs_FSSpec(self, args)
+ PyObject *self; /* Not used */
+ PyObject *args;
+{
+ FSSpec fss;
+
+ if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSSpec, &fss))
+ return NULL;
+ return (PyObject *)newmfssobject(&fss);
+}
+
+static PyObject *
+mfs_FSRef(self, args)
+ PyObject *self; /* Not used */
+ PyObject *args;
+{
+ FSRef fsr;
+
+ if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSRef, &fsr))
+ return NULL;
+ return (PyObject *)newmfsrobject(&fsr);
+}
+
+static PyObject *
+mfs_RawFSSpec(self, args)
+ PyObject *self; /* Not used */
+ PyObject *args;
+{
+ FSSpec *fssp;
+ int size;
+
+ if (!PyArg_ParseTuple(args, "s#", &fssp, &size))
+ return NULL;
+ if ( size != sizeof(FSSpec) ) {
+ PyErr_SetString(PyExc_TypeError, "Incorrect size for FSSpec record");
+ return NULL;
+ }
+ return (PyObject *)newmfssobject(fssp);
+}
+
+static PyObject *
+mfs_RawAlias(self, args)
+ PyObject *self; /* Not used */
+ PyObject *args;
+{
+ char *dataptr;
+ Handle h;
+ int size;
+
+ if (!PyArg_ParseTuple(args, "s#", &dataptr, &size))
+ return NULL;
+ h = NewHandle(size);
+ if ( h == NULL ) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ HLock(h);
+ memcpy((char *)*h, dataptr, size);
+ HUnlock(h);
+ return (PyObject *)newmfsaobject((AliasHandle)h);
+}
+
+#if !TARGET_API_MAC_CARBON
+static PyObject *
+mfs_GetDirectory(self, args)
+ PyObject *self; /* Not used */
+ PyObject *args;
+{
+ FSSpec fsdir;
+ int ok;
+ char *prompt = NULL;
+
+ if (!PyArg_ParseTuple(args, "|s", &prompt) )
+ return NULL;
+
+ ok = PyMac_GetDirectory(&fsdir, prompt);
+ return Py_BuildValue("(Oi)", newmfssobject(&fsdir), ok);
+}
+#endif
+
+static PyObject *
+mfs_FindFolder(self, args)
+ PyObject *self; /* Not used */
+ PyObject *args;
+{
+ OSErr err;
+ short where;
+ OSType which;
+ int create;
+ short refnum;
+ long dirid;
+
+ if (!PyArg_ParseTuple(args, "hO&i", &where, PyMac_GetOSType, &which, &create) )
+ return NULL;
+ err = FindFolder(where, which, (Boolean)create, &refnum, &dirid);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ return Py_BuildValue("(ii)", refnum, dirid);
+}
+
+static PyObject *
+mfs_FindApplication(self, args)
+ PyObject *self; /* Not used */
+ PyObject *args;
+{
+ OSErr err;
+ OSType which;
+ FSSpec fss;
+
+ if (!PyArg_ParseTuple(args, "O&", PyMac_GetOSType, &which) )
+ return NULL;
+ err = FindApplicationFromCreator(which, &fss);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ return (PyObject *)newmfssobject(&fss);
+}
+
+static PyObject *
+mfs_FInfo(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ return (PyObject *)newmfsiobject();
+}
+
+static PyObject *
+mfs_NewAliasMinimalFromFullPath(self, args)
+ PyObject *self; /* Not used */
+ PyObject *args;
+{
+ OSErr err;
+ char *fullpath;
+ int fullpathlen;
+ AliasHandle alias;
+ Str32 zonename;
+ Str31 servername;
+
+ if (!PyArg_ParseTuple(args, "s#", &fullpath, &fullpathlen) )
+ return NULL;
+ zonename[0] = 0;
+ servername[0] = 0;
+ err = NewAliasMinimalFromFullPath(fullpathlen, (Ptr)fullpath, zonename,
+ servername, &alias);
+ if ( err ) {
+ PyErr_Mac(ErrorObject, err);
+ return NULL;
+ }
+ return (PyObject *)newmfsaobject(alias);
+}
+
+
+/* List of methods defined in the module */
+
+static struct PyMethodDef mfs_methods[] = {
+ {"ResolveAliasFile", mfs_ResolveAliasFile, 1},
+#if !TARGET_API_MAC_CARBON
+ {"StandardGetFile", mfs_StandardGetFile, 1},
+ {"PromptGetFile", mfs_PromptGetFile, 1},
+ {"StandardPutFile", mfs_StandardPutFile, 1},
+ {"GetDirectory", mfs_GetDirectory, 1},
+ {"SetFolder", mfs_SetFolder, 1},
+#endif
+ {"FSSpec", mfs_FSSpec, 1},
+ {"FSRef", mfs_FSRef, 1},
+ {"RawFSSpec", mfs_RawFSSpec, 1},
+ {"RawAlias", mfs_RawAlias, 1},
+ {"FindFolder", mfs_FindFolder, 1},
+ {"FindApplication", mfs_FindApplication, 1},
+ {"FInfo", mfs_FInfo, 1},
+ {"NewAliasMinimalFromFullPath", mfs_NewAliasMinimalFromFullPath, 1},
+
+ {NULL, NULL} /* sentinel */
+};
+
+/*
+** Convert a Python object to an FSSpec.
+** The object may either be a full pathname, an FSSpec, an FSRef or a triple
+** (vrefnum, dirid, path).
+*/
+int
+PyMac_GetFSRef(PyObject *v, FSRef *fsr)
+{
+ OSErr err;
+
+ /* If it's an FSRef we're also okay. */
+ if (_mfs_GetFSRefFromFSRef(v, fsr))
+ return 1;
+ /* first check whether it already is an FSSpec */
+ if ( _mfs_GetFSRefFromFSSpec(v, fsr) )
+ return 1;
+ if ( PyString_Check(v) ) {
+ PyErr_SetString(PyExc_NotImplementedError, "Cannot create an FSRef from a pathname on this platform");
+ return 0;
+ }
+ PyErr_SetString(PyExc_TypeError, "FSRef argument should be existing FSRef, FSSpec or (OSX only) pathname");
+ return 0;
+}
+
+/* Convert FSSpec to PyObject */
+PyObject *PyMac_BuildFSRef(FSRef *v)
+{
+ return (PyObject *)newmfsrobject(v);
+}
+
+/*
+** Convert a Python object to an FSRef.
+** The object may either be a full pathname (OSX only), an FSSpec or an FSRef.
+*/
+int
+PyMac_GetFSSpec(PyObject *v, FSSpec *fs)
+{
+ Str255 path;
+ short refnum;
+ long parid;
+ OSErr err;
+
+ /* first check whether it already is an FSSpec */
+ if ( _mfs_GetFSSpecFromFSSpec(v, fs) )
+ return 1;
+ /* If it's an FSRef we're also okay. */
+ if (_mfs_GetFSSpecFromFSRef(v, fs))
+ return 1;
+ if ( PyString_Check(v) ) {
+ /* It's a pathname */
+ if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) )
+ return 0;
+ refnum = 0; /* XXXX Should get CurWD here?? */
+ parid = 0;
+ } else {
+ if( !PyArg_Parse(v, "(hlO&); FSSpec should be FSSpec, FSRef, fullpath or (vrefnum,dirid,path)",
+ &refnum, &parid, PyMac_GetStr255, &path)) {
+ return 0;
+ }
+ }
+ err = FSMakeFSSpec(refnum, parid, path, fs);
+ if ( err && err != fnfErr ) {
+ PyMac_Error(err);
+ return 0;
+ }
+ return 1;
+}
+
+/* Convert FSSpec to PyObject */
+PyObject *PyMac_BuildFSSpec(FSSpec *v)
+{
+ return (PyObject *)newmfssobject(v);
+}
+
+/* Initialization function for the module (*must* be called initmacfs) */
+
+void
+initmacfs()
+{
+ PyObject *m, *d;
+
+ /* Create the module and add the functions */
+ m = Py_InitModule("macfs", mfs_methods);
+
+ /* Add some symbolic constants to the module */
+ d = PyModule_GetDict(m);
+ ErrorObject = PyMac_GetOSErrException();
+ PyDict_SetItemString(d, "error", ErrorObject);
+
+ Mfsatype.ob_type = &PyType_Type;
+ Py_INCREF(&Mfsatype);
+ PyDict_SetItemString(d, "AliasType", (PyObject *)&Mfsatype);
+ Mfsstype.ob_type = &PyType_Type;
+ Py_INCREF(&Mfsstype);
+ PyDict_SetItemString(d, "FSSpecType", (PyObject *)&Mfsstype);
+ Mfsitype.ob_type = &PyType_Type;
+ Py_INCREF(&Mfsitype);
+ PyDict_SetItemString(d, "FInfoType", (PyObject *)&Mfsitype);
+ /* XXXX Add constants here */
+}
--- /dev/null
+/***********************************************************
+Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+
+#include "Python.h"
+
+#include "macglue.h"
+#include "marshal.h"
+#include "import.h"
+#include "importdl.h"
+
+#include "pythonresources.h"
+
+#include <Types.h>
+#include <Files.h>
+#include <Resources.h>
+#if 0
+#include <OSUtils.h> /* for Set(Current)A5 */
+#include <StandardFile.h>
+#include <Memory.h>
+#include <Windows.h>
+#include <Traps.h>
+#include <Processes.h>
+#include <Fonts.h>
+#include <Menus.h>
+#include <TextUtils.h>
+#endif
+#include <CodeFragments.h>
+#include <StringCompare.h>
+
+#ifdef USE_GUSI1
+#include "TFileSpec.h" /* for Path2FSSpec() */
+#endif
+
+typedef void (*dl_funcptr)();
+#define FUNCNAME_PATTERN "init%.200s"
+
+static int
+fssequal(FSSpec *fs1, FSSpec *fs2)
+{
+ if ( fs1->vRefNum != fs2->vRefNum || fs1->parID != fs2->parID )
+ return 0;
+ return EqualString(fs1->name, fs2->name, false, true);
+}
+/*
+** findnamedresource - Common code for the various *ResourceModule functions.
+** Check whether a file contains a resource of the correct name and type, and
+** optionally return the value in it.
+*/
+static int
+findnamedresource(
+ PyStringObject *obj,
+ char *module,
+ char *filename,
+ OSType restype,
+ StringPtr dataptr)
+{
+ FSSpec fss;
+ FInfo finfo;
+ short oldrh, filerh;
+ int ok;
+ Handle h;
+
+#ifdef INTERN_STRINGS
+ /*
+ ** If we have interning find_module takes care of interning all
+ ** sys.path components. We then keep a record of all sys.path
+ ** components for which GetFInfo has failed (usually because the
+ ** component in question is a folder), and we don't try opening these
+ ** as resource files again.
+ */
+#define MAXPATHCOMPONENTS 32
+ static PyStringObject *not_a_file[MAXPATHCOMPONENTS];
+ static int max_not_a_file = 0;
+ int i;
+
+ if (obj && obj->ob_sinterned ) {
+ for( i=0; i< max_not_a_file; i++ )
+ if ( obj == not_a_file[i] )
+ return 0;
+ }
+#endif /* INTERN_STRINGS */
+#ifdef USE_GUSI1
+ if ( Path2FSSpec(filename, &fss) != noErr ) {
+#else
+ if ( FSMakeFSSpec(0, 0, Pstring(filename), &fss) != noErr ) {
+#endif
+#ifdef INTERN_STRINGS
+ if ( obj && max_not_a_file < MAXPATHCOMPONENTS && obj->ob_sinterned )
+ not_a_file[max_not_a_file++] = obj;
+#endif /* INTERN_STRINGS */
+ /* doesn't exist or is folder */
+ return 0;
+ }
+ if ( fssequal(&fss, &PyMac_ApplicationFSSpec) ) {
+ /*
+ ** Special case: the application itself. Use a shortcut to
+ ** forestall opening and closing the application numerous times
+ ** (which is dead slow when running from CDROM)
+ */
+ oldrh = CurResFile();
+ UseResFile(PyMac_AppRefNum);
+ filerh = -1;
+ } else {
+#ifdef INTERN_STRINGS
+ if ( FSpGetFInfo(&fss, &finfo) != noErr ) {
+ if ( obj && max_not_a_file < MAXPATHCOMPONENTS && obj->ob_sinterned )
+ not_a_file[max_not_a_file++] = obj;
+ /* doesn't exist or is folder */
+ return 0;
+ }
+#endif /* INTERN_STRINGS */
+ oldrh = CurResFile();
+ filerh = FSpOpenResFile(&fss, fsRdPerm);
+ if ( filerh == -1 )
+ return 0;
+ UseResFile(filerh);
+ }
+ if ( dataptr == NULL )
+ SetResLoad(0);
+ h = Get1NamedResource(restype, Pstring(module));
+ SetResLoad(1);
+ ok = (h != NULL);
+ if ( ok && dataptr != NULL ) {
+ HLock(h);
+ /* XXXX Unsafe if resource not correctly formatted! */
+#ifdef __CFM68K__
+ /* for cfm68k we take the second pstring */
+ *dataptr = *((*h)+(**h)+1);
+ memcpy(dataptr+1, (*h)+(**h)+2, (int)*dataptr);
+#else
+ /* for ppc we take the first pstring */
+ *dataptr = **h;
+ memcpy(dataptr+1, (*h)+1, (int)*dataptr);
+#endif
+ HUnlock(h);
+ }
+ if ( filerh != -1 )
+ CloseResFile(filerh);
+ UseResFile(oldrh);
+ return ok;
+}
+
+/*
+** Returns true if the argument has a resource fork, and it contains
+** a 'PYC ' resource of the correct name
+*/
+int
+PyMac_FindResourceModule(obj, module, filename)
+PyStringObject *obj;
+char *module;
+char *filename;
+{
+ int ok;
+
+ ok = findnamedresource(obj, module, filename, 'PYC ', (StringPtr)0);
+ return ok;
+}
+
+/*
+** Returns true if the argument has a resource fork, and it contains
+** a 'PYD ' resource of the correct name
+*/
+int
+PyMac_FindCodeResourceModule(obj, module, filename)
+PyStringObject *obj;
+char *module;
+char *filename;
+{
+ int ok;
+
+ ok = findnamedresource(obj, module, filename, 'PYD ', (StringPtr)0);
+ return ok;
+}
+
+
+/*
+** Load the specified module from a code resource
+*/
+PyObject *
+PyMac_LoadCodeResourceModule(name, pathname)
+ char *name;
+ char *pathname;
+{
+ PyObject *m, *d, *s;
+ char funcname[258];
+ char *lastdot, *shortname, *packagecontext;
+ dl_funcptr p = NULL;
+ Str255 fragmentname;
+ CFragConnectionID connID;
+ Ptr mainAddr;
+ Str255 errMessage;
+ OSErr err;
+ char buf[512];
+ Ptr symAddr;
+ CFragSymbolClass class;
+
+ if ((m = _PyImport_FindExtension(name, name)) != NULL) {
+ Py_INCREF(m);
+ return m;
+ }
+ lastdot = strrchr(name, '.');
+ if (lastdot == NULL) {
+ packagecontext = NULL;
+ shortname = name;
+ }
+ else {
+ packagecontext = name;
+ shortname = lastdot+1;
+ }
+ sprintf(funcname, FUNCNAME_PATTERN, shortname);
+ if( !findnamedresource((PyStringObject *)0, name, pathname, 'PYD ', fragmentname)) {
+ PyErr_SetString(PyExc_ImportError, "PYD resource not found");
+ return NULL;
+ }
+
+ /* Load the fragment
+ (or return the connID if it is already loaded */
+ err = GetSharedLibrary(fragmentname, kCompiledCFragArch,
+ kLoadCFrag, &connID, &mainAddr,
+ errMessage);
+ if ( err ) {
+ sprintf(buf, "%.*s: %.200s",
+ errMessage[0], errMessage+1,
+ PyMac_StrError(err));
+ PyErr_SetString(PyExc_ImportError, buf);
+ return NULL;
+ }
+ /* Locate the address of the correct init function */
+ err = FindSymbol(connID, Pstring(funcname), &symAddr, &class);
+ if ( err ) {
+ sprintf(buf, "%s: %.200s",
+ funcname, PyMac_StrError(err));
+ PyErr_SetString(PyExc_ImportError, buf);
+ return NULL;
+ }
+ p = (dl_funcptr)symAddr;
+ if (p == NULL) {
+ PyErr_Format(PyExc_ImportError,
+ "dynamic module does not define init function (%.200s)",
+ funcname);
+ return NULL;
+ }
+ _Py_PackageContext = packagecontext;
+ (*p)();
+ _Py_PackageContext = NULL;
+ if (PyErr_Occurred())
+ return NULL;
+ if (_PyImport_FixupExtension(name, name) == NULL)
+ return NULL;
+
+ m = PyDict_GetItemString(PyImport_GetModuleDict(), name);
+ if (m == NULL) {
+ PyErr_SetString(PyExc_SystemError,
+ "dynamic module not initialized properly");
+ return NULL;
+ }
+#if 1
+ /* Remember the filename as the __file__ attribute */
+ d = PyModule_GetDict(m);
+ s = PyString_FromString(pathname);
+ if (s == NULL || PyDict_SetItemString(d, "__file__", s) != 0)
+ PyErr_Clear(); /* Not important enough to report */
+ Py_XDECREF(s);
+#endif
+ if (Py_VerboseFlag)
+ PySys_WriteStderr("import %s # pyd fragment %#s loaded from %s\n",
+ name, fragmentname, pathname);
+ Py_INCREF(m);
+ return m;
+}
+
+/*
+** Load the specified module from a resource
+*/
+PyObject *
+PyMac_LoadResourceModule(module, filename)
+char *module;
+char *filename;
+{
+ FSSpec fss;
+ FInfo finfo;
+ short oldrh, filerh;
+ Handle h;
+ OSErr err;
+ PyObject *m, *co;
+ long num, size;
+
+#ifdef USE_GUSI1
+ if ( (err=Path2FSSpec(filename, &fss)) != noErr ||
+ FSpGetFInfo(&fss, &finfo) != noErr )
+#else
+ if ( (err=FSMakeFSSpec(0, 0, Pstring(filename), &fss)) != noErr )
+#endif
+ goto error;
+ if ( fssequal(&fss, &PyMac_ApplicationFSSpec) ) {
+ /*
+ ** Special case: the application itself. Use a shortcut to
+ ** forestall opening and closing the application numerous times
+ ** (which is dead slow when running from CDROM)
+ */
+ oldrh = CurResFile();
+ UseResFile(PyMac_AppRefNum);
+ filerh = -1;
+ } else {
+ if ( (err=FSpGetFInfo(&fss, &finfo)) != noErr )
+ goto error;
+ oldrh = CurResFile();
+ filerh = FSpOpenResFile(&fss, fsRdPerm);
+ if ( filerh == -1 ) {
+ err = ResError();
+ goto error;
+ }
+ UseResFile(filerh);
+ }
+ h = Get1NamedResource('PYC ', Pstring(module));
+ if ( h == NULL ) {
+ err = ResError();
+ goto error;
+ }
+ HLock(h);
+ /*
+ ** XXXX The next few lines are intimately tied to the format of pyc
+ ** files. I'm not sure whether this code should be here or in import.c -- Jack
+ */
+ size = GetHandleSize(h);
+ if ( size < 8 ) {
+ PyErr_SetString(PyExc_ImportError, "Resource too small");
+ co = NULL;
+ } else {
+ num = (*h)[0] & 0xff;
+ num = num | (((*h)[1] & 0xff) << 8);
+ num = num | (((*h)[2] & 0xff) << 16);
+ num = num | (((*h)[3] & 0xff) << 24);
+ if ( num != PyImport_GetMagicNumber() ) {
+ PyErr_SetString(PyExc_ImportError, "Bad MAGIC in resource");
+ co = NULL;
+ } else {
+ co = PyMarshal_ReadObjectFromString((*h)+8, size-8);
+ /*
+ ** Normally, byte 4-7 are the time stamp, but that is not used
+ ** for 'PYC ' resources. We abuse byte 4 as a flag to indicate
+ ** that it is a package rather than an ordinary module.
+ ** See also py_resource.py. (jvr)
+ */
+ if ((*h)[4] & 0xff) {
+ /* it's a package */
+ /* Set __path__ to the package name */
+ PyObject *d, *s;
+ int err;
+
+ m = PyImport_AddModule(module);
+ if (m == NULL) {
+ co = NULL;
+ goto packageerror;
+ }
+ d = PyModule_GetDict(m);
+ s = PyString_InternFromString(module);
+ if (s == NULL) {
+ co = NULL;
+ goto packageerror;
+ }
+ err = PyDict_SetItemString(d, "__path__", s);
+ Py_DECREF(s);
+ if (err != 0) {
+ co = NULL;
+ goto packageerror;
+ }
+ }
+ }
+ }
+packageerror:
+ HUnlock(h);
+ if ( filerh != -1 )
+ CloseResFile(filerh);
+ else
+ ReleaseResource(h);
+ UseResFile(oldrh);
+ if ( co ) {
+ m = PyImport_ExecCodeModuleEx(module, co, "<pyc resource>");
+ Py_DECREF(co);
+ } else {
+ m = NULL;
+ }
+ if (Py_VerboseFlag)
+ PySys_WriteStderr("import %s # pyc resource from %s\n",
+ module, filename);
+ return m;
+error:
+ {
+ char buf[512];
+
+ sprintf(buf, "%s: %s", filename, PyMac_StrError(err));
+ PyErr_SetString(PyExc_ImportError, buf);
+ return NULL;
+ }
+}
+
+/*
+** Look for a module in a single folder. Upon entry buf and len
+** point to the folder to search, upon exit they refer to the full
+** pathname of the module found (if any).
+*/
+struct filedescr *
+PyMac_FindModuleExtension(char *buf, size_t *lenp, char *module)
+{
+ struct filedescr *fdp;
+ unsigned char fnbuf[64];
+ int modnamelen = strlen(module);
+ FSSpec fss;
+#ifdef USE_GUSI1
+ FInfo finfo;
+#endif
+ short refnum;
+ long dirid;
+
+ /*
+ ** Copy the module name to the buffer (already :-terminated)
+ ** We also copy the first suffix, if this matches immedeately we're
+ ** lucky and return immedeately.
+ */
+ if ( !_PyImport_Filetab[0].suffix )
+ return 0;
+
+#if 0
+ /* Pre 1.5a4 */
+ strcpy(buf+*lenp, module);
+ strcpy(buf+*lenp+modnamelen, _PyImport_Filetab[0].suffix);
+#else
+ strcpy(buf+*lenp, _PyImport_Filetab[0].suffix);
+#endif
+#ifdef USE_GUSI1
+ if ( Path2FSSpec(buf, &fss) == noErr &&
+ FSpGetFInfo(&fss, &finfo) == noErr)
+ return _PyImport_Filetab;
+#else
+ if ( FSMakeFSSpec(0, 0, Pstring(buf), &fss) == noErr )
+ return _PyImport_Filetab;
+#endif
+ /*
+ ** We cannot check for fnfErr (unfortunately), it can mean either that
+ ** the file doesn't exist (fine, we try others) or the path leading to it.
+ */
+ refnum = fss.vRefNum;
+ dirid = fss.parID;
+ if ( refnum == 0 || dirid == 0 ) /* Fail on nonexistent dir */
+ return 0;
+ /*
+ ** We now have the folder parameters. Setup the field for the filename
+ */
+ if ( modnamelen > 54 ) return 0; /* Leave room for extension */
+ strcpy((char *)fnbuf+1, module);
+
+ for( fdp = _PyImport_Filetab+1; fdp->suffix; fdp++ ) {
+ strcpy((char *)fnbuf+1+modnamelen, fdp->suffix);
+ fnbuf[0] = strlen((char *)fnbuf+1);
+ if (Py_VerboseFlag > 1)
+ PySys_WriteStderr("# trying %s%s\n", buf, fdp->suffix);
+ if ( FSMakeFSSpec(refnum, dirid, fnbuf, &fss) == noErr ) {
+ /* Found it. */
+#if 0
+ strcpy(buf+*lenp+modnamelen, fdp->suffix);
+#else
+ strcpy(buf+*lenp, fdp->suffix);
+#endif
+ *lenp = strlen(buf);
+ return fdp;
+ }
+ }
+ return 0;
+}
--- /dev/null
+/***********************************************************
+Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/* Python interpreter main program */
+
+#include "Python.h"
+#include "pythonresources.h"
+#include "import.h"
+#include "marshal.h"
+#include "macglue.h"
+
+#include <Memory.h>
+#include <Resources.h>
+#include <stdio.h>
+#include <Events.h>
+#include <Windows.h>
+#include <Fonts.h>
+#include <Balloons.h>
+#ifdef USE_APPEARANCE
+#include <Gestalt.h>
+#include <Appearance.h>
+#endif /* USE_APPEARANCE */
+#ifdef __MWERKS__
+#include <SIOUX.h>
+#define USE_SIOUX
+extern int ccommand(char ***);
+#if __profile__ == 1
+#include <profiler.h>
+#endif
+#endif
+#include <unistd.h>
+#ifdef USE_MAC_SHARED_LIBRARY
+extern PyMac_AddLibResources(void);
+#endif
+//#ifdef USE_GUSI
+//#include "GUSISIOUX.h"
+//#endif
+
+#define STARTUP "PythonStartup"
+
+#define COPYRIGHT \
+ "Type \"copyright\", \"credits\" or \"license\" for more information."
+
+
+extern int Py_DebugFlag; /* For parser.c, declared in pythonrun.c */
+extern int Py_VerboseFlag; /* For import.c, declared in pythonrun.c */
+short PyMac_AppRefNum; /* RefNum of application resource fork */
+
+/* For Py_GetArgcArgv(); set by main() */
+static char **orig_argv;
+static int orig_argc;
+
+/* A flag which remembers whether the user has acknowledged all the console
+** output (by typing something)
+*/
+#define STATE_UNKNOWN 0
+#define STATE_LASTREAD 1
+#define STATE_LASTWRITE 2
+int console_output_state = STATE_UNKNOWN;
+
+PyMac_PrefRecord PyMac_options;
+
+static void Py_Main(int, char **); /* Forward */
+void PyMac_Exit(int); /* Forward */
+
+static void init_appearance()
+{
+#ifdef USE_APPEARANCE
+ OSErr err;
+ SInt32 response;
+
+ err = Gestalt(gestaltAppearanceAttr,&response);
+ if ( err ) goto no_appearance;
+ if ( !(response&(1<<gestaltAppearanceExists)) ) goto no_appearance;
+ /* XXXX Should we check the version? Compat-mode? */
+ PyMac_AppearanceCompliant = 1;
+no_appearance:
+ return;
+#endif /* USE_APPEARANCE */
+}
+/* Initialize the Mac toolbox world */
+
+static void
+init_mac_world()
+{
+#if !TARGET_API_MAC_CARBON
+ /* These aren't needed for carbon */
+ MaxApplZone();
+ InitGraf(&qd.thePort);
+ InitFonts();
+ InitWindows();
+ TEInit();
+ InitDialogs((long)0);
+ InitMenus();
+#endif
+ InitCursor();
+ init_appearance();
+}
+
+/*
+** PyMac_InteractiveOptions - Allow user to set options if option key is pressed
+*/
+static void
+PyMac_InteractiveOptions(PyMac_PrefRecord *p, int *argcp, char ***argvp)
+{
+ KeyMap rmap;
+ unsigned char *map;
+ short item, type;
+ ControlHandle handle;
+ DialogPtr dialog;
+ Rect rect;
+ int old_argc = *argcp;
+ int i;
+
+ /*
+ ** If the preferences disallows interactive options we return,
+ ** similarly of <option> isn't pressed.
+ */
+ if (p->nointopt) return;
+
+ GetKeys(rmap);
+ map = (unsigned char *)rmap;
+ if ( ( map[0x3a>>3] & (1<<(0x3a&7)) ) == 0 ) /* option key is 3a */
+ return;
+
+ dialog = GetNewDialog(OPT_DIALOG, NULL, (WindowPtr)-1);
+ if ( dialog == NULL ) {
+ printf("Option dialog not found - cannot set options\n");
+ return;
+ }
+ SetDialogDefaultItem(dialog, OPT_OK);
+ SetDialogCancelItem(dialog, OPT_CANCEL);
+
+ /* Set default values */
+#define SET_OPT_ITEM(num, var) \
+ GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
+ SetControlValue(handle, (short)p->var);
+
+ SET_OPT_ITEM(OPT_INSPECT, inspect);
+ SET_OPT_ITEM(OPT_VERBOSE, verbose);
+ SET_OPT_ITEM(OPT_OPTIMIZE, optimize);
+ SET_OPT_ITEM(OPT_UNBUFFERED, unbuffered);
+ SET_OPT_ITEM(OPT_DEBUGGING, debugging);
+ GetDialogItem(dialog, OPT_KEEPALWAYS, &type, (Handle *)&handle, &rect);
+ SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ALWAYS));
+ GetDialogItem(dialog, OPT_KEEPOUTPUT, &type, (Handle *)&handle, &rect);
+ SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_OUTPUT));
+ GetDialogItem(dialog, OPT_KEEPERROR, &type, (Handle *)&handle, &rect);
+ SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ERROR));
+ GetDialogItem(dialog, OPT_KEEPNEVER, &type, (Handle *)&handle, &rect);
+ SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_NEVER));
+/* SET_OPT_ITEM(OPT_KEEPCONSOLE, keep_console); */
+ SET_OPT_ITEM(OPT_TABWARN, tabwarn);
+ SET_OPT_ITEM(OPT_NOSITE, nosite);
+ SET_OPT_ITEM(OPT_NONAVSERV, nonavservice);
+ /* The rest are not settable interactively */
+
+#undef SET_OPT_ITEM
+
+ while (1) {
+ handle = NULL;
+ ModalDialog(NULL, &item);
+ if ( item == OPT_OK )
+ break;
+ if ( item == OPT_CANCEL ) {
+ DisposeDialog(dialog);
+ exit(0);
+ }
+#if !TARGET_API_MAC_CARBON
+ if ( item == OPT_HELP ) {
+ HMSetBalloons(!HMGetBalloons());
+ }
+#endif
+ if ( item == OPT_CMDLINE ) {
+ int new_argc, newer_argc;
+ char **new_argv, **newer_argv;
+
+ new_argc = ccommand(&new_argv);
+ newer_argc = (new_argc-1) + old_argc;
+ newer_argv = malloc((newer_argc+1)*sizeof(char *));
+ if( !newer_argv )
+ Py_FatalError("Cannot malloc argv\n");
+ for(i=0; i<old_argc; i++)
+ newer_argv[i] = (*argvp)[i];
+ for(i=old_argc; i<=newer_argc; i++) /* Copy the NULL too */
+ newer_argv[i] = new_argv[i-old_argc+1];
+ *argvp = newer_argv;
+ *argcp = newer_argc;
+
+ /* XXXX Is it not safe to use free() here, apparently */
+ }
+#define OPT_ITEM(num, var) \
+ if ( item == (num) ) { \
+ p->var = !p->var; \
+ GetDialogItem(dialog, (num), &type, (Handle *)&handle, &rect); \
+ SetControlValue(handle, (short)p->var); \
+ }
+
+ OPT_ITEM(OPT_INSPECT, inspect);
+ OPT_ITEM(OPT_VERBOSE, verbose);
+ OPT_ITEM(OPT_OPTIMIZE, optimize);
+ OPT_ITEM(OPT_UNBUFFERED, unbuffered);
+ OPT_ITEM(OPT_DEBUGGING, debugging);
+ if ( item == OPT_KEEPALWAYS ) p->keep_console = POPT_KEEPCONSOLE_ALWAYS;
+ if ( item == OPT_KEEPOUTPUT ) p->keep_console = POPT_KEEPCONSOLE_OUTPUT;
+ if ( item == OPT_KEEPERROR ) p->keep_console = POPT_KEEPCONSOLE_ERROR;
+ if ( item == OPT_KEEPNEVER ) p->keep_console = POPT_KEEPCONSOLE_NEVER;
+ GetDialogItem(dialog, OPT_KEEPALWAYS, &type, (Handle *)&handle, &rect);
+ SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ALWAYS));
+ GetDialogItem(dialog, OPT_KEEPOUTPUT, &type, (Handle *)&handle, &rect);
+ SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_OUTPUT));
+ GetDialogItem(dialog, OPT_KEEPERROR, &type, (Handle *)&handle, &rect);
+ SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_ERROR));
+ GetDialogItem(dialog, OPT_KEEPNEVER, &type, (Handle *)&handle, &rect);
+ SetControlValue(handle, (short)(p->keep_console == POPT_KEEPCONSOLE_NEVER));
+ OPT_ITEM(OPT_TABWARN, tabwarn);
+ OPT_ITEM(OPT_NOSITE, nosite);
+ OPT_ITEM(OPT_NONAVSERV, nonavservice);
+
+#undef OPT_ITEM
+ }
+ DisposeDialog(dialog);
+}
+
+/*
+** Initialization code, shared by interpreter and applets
+*/
+static void
+init_common(int *argcp, char ***argvp, int embedded)
+{
+ /* Remember resource fork refnum, for later */
+ PyMac_AppRefNum = CurResFile();
+
+ /* Initialize toolboxes */
+ init_mac_world();
+
+#ifdef USE_MAC_SHARED_LIBRARY
+ /* Add the shared library to the stack of resource files */
+ (void)PyMac_init_process_location();
+ PyMac_AddLibResources();
+#endif
+
+#if defined(USE_GUSI1)
+ /* Setup GUSI */
+ GUSIDefaultSetup();
+ PyMac_SetGUSISpin();
+ PyMac_SetGUSIOptions();
+#endif
+#if defined(USE_GUSI)
+ atexit(PyMac_StopGUSISpin);
+#endif
+
+#ifdef USE_SIOUX
+ /* Set various SIOUX flags. Some are changed later based on options */
+/* SIOUXSettings.standalone = 0; /* XXXX Attempting to keep sioux from eating events */
+ SIOUXSettings.asktosaveonclose = 0;
+ SIOUXSettings.showstatusline = 0;
+ SIOUXSettings.tabspaces = 4;
+#endif
+
+ /* Get options from preference file (or from applet resource fork) */
+ PyMac_options.keep_console = POPT_KEEPCONSOLE_OUTPUT; /* default-default */
+ PyMac_PreferenceOptions(&PyMac_options);
+
+ if ( embedded ) {
+ static char *emb_argv[] = {"embedded-python", 0};
+
+ *argcp = 1;
+ *argvp = emb_argv;
+ } else {
+ /* Create argc/argv. Do it before we go into the options event loop. */
+ *argcp = PyMac_GetArgv(argvp, PyMac_options.noargs);
+#ifndef NO_ARGV0_CHDIR
+ if (*argcp >= 1 && (*argvp)[0] && (*argvp)[0][0]) {
+ /* Workaround for MacOS X, which currently (DP4) doesn't set
+ ** the working folder correctly
+ */
+ char app_wd[256], *p;
+
+ strncpy(app_wd, (*argvp)[0], 256);
+ p = strrchr(app_wd, ':');
+ if ( p ) *p = 0;
+ chdir(app_wd);
+ }
+#endif
+ /* Do interactive option setting, if allowed and <option> depressed */
+ PyMac_InteractiveOptions(&PyMac_options, argcp, argvp);
+ }
+
+ /* Copy selected options to where the machine-independent stuff wants it */
+ Py_VerboseFlag = PyMac_options.verbose;
+/* Py_SuppressPrintingFlag = PyMac_options.suppress_print; */
+ Py_OptimizeFlag = PyMac_options.optimize;
+ Py_DebugFlag = PyMac_options.debugging;
+ Py_NoSiteFlag = PyMac_options.nosite;
+ Py_TabcheckFlag = PyMac_options.tabwarn;
+ if ( PyMac_options.noargs ) {
+ /* don't process events at all without the scripts permission */
+ PyMacSchedParams scp;
+
+ PyMac_GetSchedParams(&scp);
+ scp.process_events = 0;
+ /* Should we disable command-dot as well? */
+ PyMac_SetSchedParams(&scp);
+ }
+ /* XXXX dispatch oldexc and nosite */
+
+ /* Set buffering */
+ if (PyMac_options.unbuffered) {
+#ifndef MPW
+ setbuf(stdout, (char *)NULL);
+ setbuf(stderr, (char *)NULL);
+#else
+ /* On MPW (3.2) unbuffered seems to hang */
+ setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
+ setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ);
+#endif
+ }
+#if __profile__ == 1
+ /* collectSummary or collectDetailed, timebase, #routines, max stack depth */
+ ProfilerInit(collectSummary, bestTimeBase, 8000, 250);
+#endif
+
+ /* Tell the rest of python about our argc/argv */
+ orig_argc = *argcp; /* For Py_GetArgcArgv() */
+ orig_argv = *argvp;
+ Py_SetProgramName((*argvp)[0]);
+}
+
+/*
+** Inspection mode after script/applet termination
+*/
+static int
+run_inspect()
+{
+ int sts = 0;
+
+ if (PyMac_options.inspect && isatty((int)fileno(stdin)))
+ sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
+ return sts;
+}
+
+/*
+** Import the macfsn module, which will override the Standard File
+** calls in the macfs builtin module by Navigation Services versions,
+** if available on this machine.
+*/
+static void
+PyMac_InstallNavServicesForSF()
+{
+ if ( !PyMac_options.nonavservice ) {
+ PyObject *m = PyImport_ImportModule("macfsn");
+
+ if ( m == NULL ) {
+ PySys_WriteStderr("'import macfsn' failed; ");
+ if (Py_VerboseFlag) {
+ PySys_WriteStderr("traceback:\n");
+ PyErr_Print();
+ }
+ else {
+ PySys_WriteStderr("use -v for traceback\n");
+ }
+ }
+ }
+}
+
+#ifdef USE_MAC_APPLET_SUPPORT
+/* Applet support */
+
+/* Run a compiled Python Python script from 'PYC ' resource __main__ */
+static int
+run_main_resource()
+{
+ Handle h;
+ long size;
+ PyObject *code;
+ PyObject *result;
+
+ h = GetNamedResource('PYC ', "\p__main__");
+ if (h == NULL) {
+ Alert(NOPYC_ALERT, NULL);
+ return 1;
+ }
+ size = GetResourceSizeOnDisk(h);
+ HLock(h);
+ code = PyMarshal_ReadObjectFromString(*h + 8, (int)(size - 8));
+ HUnlock(h);
+ ReleaseResource(h);
+ if (code == NULL) {
+ PyErr_Print();
+ return 1;
+ }
+ result = PyImport_ExecCodeModule("__main__", code);
+ Py_DECREF(code);
+ if (result == NULL) {
+ PyErr_Print();
+ return 1;
+ }
+ Py_DECREF(result);
+ return 0;
+}
+
+/* Initialization sequence for applets */
+void
+PyMac_InitApplet()
+{
+ int argc;
+ char **argv;
+ int err;
+
+ init_common(&argc, &argv, 0);
+
+ Py_Initialize();
+ PyMac_InstallNavServicesForSF();
+ PySys_SetArgv(argc, argv);
+
+ err = run_main_resource();
+
+ err = (run_inspect() || err);
+
+ fflush(stderr);
+ fflush(stdout);
+ PyMac_Exit(err);
+ /* XXX Should we bother to Py_Exit(sts)? */
+}
+
+/*
+** Hook for embedding python.
+*/
+void
+PyMac_Initialize()
+{
+ int argc;
+ char **argv;
+
+ init_common(&argc, &argv, 1);
+ Py_Initialize();
+ PyMac_InstallNavServicesForSF();
+ PySys_SetArgv(argc, argv);
+}
+
+#endif /* USE_MAC_APPLET_SUPPORT */
+
+/* For normal application */
+void
+PyMac_InitApplication()
+{
+ int argc;
+ char **argv;
+
+ init_common(&argc, &argv, 0);
+
+ if ( argc > 1 ) {
+ /* We're running a script. Attempt to change current directory */
+ char curwd[256], *endp;
+
+ strcpy(curwd, argv[1]);
+ endp = strrchr(curwd, ':');
+ if ( endp && endp > curwd ) {
+ *endp = '\0';
+
+ chdir(curwd);
+#ifdef USE_GUSI1
+ /* Change MacOS's idea of wd too */
+ PyMac_FixGUSIcd();
+#endif
+ }
+ }
+ Py_Main(argc, argv);
+}
+
+/* Main program */
+
+static void
+Py_Main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int sts;
+ char *command = NULL;
+ char *filename = NULL;
+ FILE *fp = stdin;
+
+ filename = argv[1];
+
+ if (Py_VerboseFlag ||
+ command == NULL && filename == NULL && isatty((int)fileno(fp)))
+ fprintf(stderr, "Python %s on %s\n%s\n",
+ Py_GetVersion(), Py_GetPlatform(), COPYRIGHT);
+
+ if (filename != NULL) {
+ if ((fp = fopen(filename, "r")) == NULL) {
+ fprintf(stderr, "%s: can't open file '%s'\n",
+ argv[0], filename);
+ PyMac_Exit(2);
+ }
+ }
+
+ /* We initialize the menubar here, hoping SIOUX is initialized by now */
+ PyMac_InitMenuBar();
+
+ Py_Initialize();
+
+ PyUnicode_SetDefaultEncoding(PyMac_getscript());
+
+ PyMac_InstallNavServicesForSF();
+
+ PySys_SetArgv(argc-1, argv+1);
+
+ if (filename == NULL && isatty((int)fileno(fp))) {
+ FILE *fp = fopen(STARTUP, "r");
+ if (fp != NULL) {
+ (void) PyRun_SimpleFile(fp, STARTUP);
+ PyErr_Clear();
+ fclose(fp);
+ }
+ }
+ sts = PyRun_AnyFile(
+ fp, filename == NULL ? "<stdin>" : filename) != 0;
+ if (filename != NULL)
+ fclose(fp);
+
+ if ( filename != NULL || command != NULL )
+ sts = (run_inspect() || sts);
+
+ Py_Exit(sts);
+ /*NOTREACHED*/
+}
+
+/*
+** Reset the "unseen output" flag
+*/
+void
+PyMac_OutputSeen()
+{
+ if ( console_output_state == STATE_UNKNOWN )
+ PyMac_InitMenuBar();
+ console_output_state = STATE_LASTREAD;
+}
+
+/*
+** Set the "unseen output" flag
+*/
+void
+PyMac_OutputNotSeen()
+{
+ if ( console_output_state == STATE_UNKNOWN )
+ PyMac_InitMenuBar();
+ console_output_state = STATE_LASTWRITE;
+}
+
+/*
+** Override abort() - The default one is not what we want.
+*/
+void
+abort()
+{
+ console_output_state = STATE_LASTWRITE;
+ PyMac_Exit(1);
+}
+
+/*
+** Terminate application
+*/
+void
+PyMac_Exit(status)
+ int status;
+{
+ int keep = 0;
+
+#if __profile__ == 1
+ ProfilerDump("\pPython Profiler Results");
+ ProfilerTerm();
+#endif
+
+#ifdef USE_SIOUX
+ switch (PyMac_options.keep_console) {
+ case POPT_KEEPCONSOLE_NEVER:
+ keep = 0;
+ break;
+ case POPT_KEEPCONSOLE_OUTPUT:
+ if (console_output_state == STATE_LASTWRITE ||
+ console_output_state == STATE_UNKNOWN )
+ keep = 1;
+ else
+ keep = 0;
+ break;
+ case POPT_KEEPCONSOLE_ERROR:
+ keep = (status != 0);
+ break;
+ default:
+ keep = 1;
+ }
+ if (keep) {
+ SIOUXSettings.standalone = 1;
+ SIOUXSettings.autocloseonquit = 0;
+ SIOUXSetTitle("\p\307terminated\310");
+ PyMac_RaiseConsoleWindow();
+ PyMac_RestoreMenuBar();
+#ifdef USE_MSL
+ /*
+ ** Temporary workaround: autocloseonquit clearing does not
+ ** currently work for the MSL/GUSI combo.
+ */
+ while(getchar() > 0);
+#endif
+ }
+ else
+ SIOUXSettings.autocloseonquit = 1;
+#endif /* USE_SIOUX */
+
+ exit(status);
+}
+
+/* Return the program name -- some code out there needs this. */
+char *
+Py_GetProgramFullPath()
+{
+ return orig_argv[0];
+}
+
+
+/* Make the *original* argc/argv available to other modules.
+ This is rare, but it is needed by the secureware extension. */
+
+void
+Py_GetArgcArgv(int *argc,char ***argv)
+{
+ *argc = orig_argc;
+ *argv = orig_argv;
+}
+
+/* More cruft that shouldn't really be here, used in sysmodule.c */
+
+char *
+Py_GetPrefix()
+{
+ return PyMac_GetPythonDir();
+}
+
+char *
+Py_GetExecPrefix()
+{
+ return PyMac_GetPythonDir();
+}
+
+int
+PyMac_GetDelayConsoleFlag()
+{
+ return (int)PyMac_options.delayconsole;
+}
\ No newline at end of file
--- /dev/null
+import macfs
+import marshal
+import types
+
+from MACFS import kOnSystemDisk
+
+class PrefObject:
+
+ def __init__(self, dict = None):
+ if dict == None:
+ self._prefsdict = {}
+ else:
+ self._prefsdict = dict
+
+ def __len__(self):
+ return len(self._prefsdict)
+
+ def __delattr__(self, attr):
+ if self._prefsdict.has_key(attr):
+ del self._prefsdict[attr]
+ else:
+ raise AttributeError, 'delete non-existing instance attribute'
+
+ def __getattr__(self, attr):
+ if attr == '__members__':
+ keys = self._prefsdict.keys()
+ keys.sort()
+ return keys
+ try:
+ return self._prefsdict[attr]
+ except KeyError:
+ raise AttributeError, attr
+
+ def __setattr__(self, attr, value):
+ if attr[0] <> '_':
+ self._prefsdict[attr] = value
+ else:
+ self.__dict__[attr] = value
+
+ def getprefsdict(self):
+ return self._prefsdict
+
+
+class PrefFile(PrefObject):
+
+ def __init__(self, path, creator = 'Pyth'):
+ # Find the preferences folder and our prefs file, create if needed.
+ self.__path = path
+ self.__creator = creator
+ self._prefsdict = {}
+ try:
+ prefdict = marshal.load(open(self.__path, 'rb'))
+ except (IOError, ValueError):
+ # file not found, or currupt marshal data
+ pass
+ else:
+ for key, value in prefdict.items():
+ if type(value) == types.DictType:
+ self._prefsdict[key] = PrefObject(value)
+ else:
+ self._prefsdict[key] = value
+
+ def save(self):
+ prefdict = {}
+ for key, value in self._prefsdict.items():
+ if type(value) == types.InstanceType:
+ prefdict[key] = value.getprefsdict()
+ if not prefdict[key]:
+ del prefdict[key]
+ else:
+ prefdict[key] = value
+ marshal.dump(prefdict, open(self.__path, 'wb'))
+ fss = macfs.FSSpec(self.__path)
+ fss.SetCreatorType(self.__creator, 'pref')
+
+ def __getattr__(self, attr):
+ if attr == '__members__':
+ keys = self._prefsdict.keys()
+ keys.sort()
+ return keys
+ try:
+ return self._prefsdict[attr]
+ except KeyError:
+ if attr[0] <> '_':
+ self._prefsdict[attr] = PrefObject()
+ return self._prefsdict[attr]
+ else:
+ raise AttributeError, attr
+
+
+_prefscache = {}
+
+def GetPrefs(prefname, creator = 'Pyth'):
+ import macostools, os
+ if _prefscache.has_key(prefname):
+ return _prefscache[prefname]
+ # Find the preferences folder and our prefs file, create if needed.
+ vrefnum, dirid = macfs.FindFolder(kOnSystemDisk, 'pref', 0)
+ prefsfolder_fss = macfs.FSSpec((vrefnum, dirid, ''))
+ prefsfolder = prefsfolder_fss.as_pathname()
+ path = os.path.join(prefsfolder, prefname)
+ head, tail = os.path.split(path)
+ # make sure the folder(s) exist
+ macostools.mkdirs(head)
+
+ preffile = PrefFile(path, creator)
+ _prefscache[prefname] = preffile
+ return preffile
--- /dev/null
+import W
+import Wkeys
+import struct
+import string
+import types
+import re
+
+nullid = '\0\0'
+closedid = struct.pack('h', 468)
+openid = struct.pack('h', 469)
+closedsolidid = struct.pack('h', 470)
+opensolidid = struct.pack('h', 471)
+
+arrows = (nullid, closedid, openid, closedsolidid, opensolidid)
+
+has_ctlcharsRE = re.compile(r'[\000-\037\177-\377]')
+def ctlcharsREsearch(str):
+ if has_ctlcharsRE.search(str) is None:
+ return -1
+ return 1
+
+def double_repr(key, value, truncvalue = 0,
+ type = type, StringType = types.StringType,
+ has_ctlchars = ctlcharsREsearch, _repr = repr, str = str):
+ if type(key) == StringType and has_ctlchars(key) < 0:
+ key = str(key)
+ else:
+ key = _repr(key)
+ if key == '__builtins__':
+ value = "<" + type(value).__name__ + " '__builtin__'>"
+ elif key == '__return__':
+ # bleh, when returning from a class codeblock we get infinite recursion in repr.
+ # Use safe repr instead.
+ import repr
+ value = repr.repr(value)
+ else:
+ try:
+ value = _repr(value)
+ '' + value # test to see if it is a string, in case a __repr__ method is buggy
+ except:
+ value = '\xa5\xa5\xa5 exception in repr()'
+ if truncvalue:
+ return key + '\t' + value[:255]
+ return key + '\t' + value
+
+
+class BrowserWidget(W.List):
+
+ LDEF_ID = 471
+
+ def __init__(self, possize, object = None, col = 100, closechildren = 0):
+ W.List.__init__(self, possize, callback = self.listhit)
+ self.object = (None,)
+ self.indent = 16
+ self.lastmaxindent = 0
+ self.closechildren = closechildren
+ self.children = []
+ self.mincol = 64
+ self.setcolumn(col)
+ self.bind('return', self.openselection)
+ self.bind('enter', self.openselection)
+ if object is not None:
+ self.set(object)
+
+ def set(self, object):
+ if self.object[0] is not object:
+ self.object = object,
+ self[:] = self.unpack(object, 0)
+ elif self._parentwindow is not None and self._parentwindow.wid:
+ self.update()
+
+ def unpack(self, object, indent):
+ return unpack_object(object, indent)
+
+ def update(self):
+ # for now...
+ W.SetCursor('watch')
+ self.setdrawingmode(0)
+ sel = self.getselectedobjects()
+ fold = self.getunfoldedobjects()
+ topcell = self.gettopcell()
+ self[:] = self.unpack(self.object[0], 0)
+ self.unfoldobjects(fold)
+ self.setselectedobjects(sel)
+ self.settopcell(topcell)
+ self.setdrawingmode(1)
+
+ def setcolumn(self, col):
+ self.col = col
+ self.colstr = struct.pack('h', col)
+ if self._list:
+ sel = self.getselection()
+ self.setitems(self.items)
+ self.setselection(sel)
+
+ def key(self, char, event):
+ if char in (Wkeys.leftarrowkey, Wkeys.rightarrowkey):
+ sel = self.getselection()
+ sel.reverse()
+ self.setdrawingmode(0)
+ for index in sel:
+ self.fold(index, char == Wkeys.rightarrowkey)
+ self.setdrawingmode(1)
+ else:
+ W.List.key(self, char, event)
+
+ def rollover(self, (x, y), onoff):
+ if onoff:
+ if self.incolumn((x, y)):
+ W.SetCursor('hmover')
+ else:
+ W.SetCursor('arrow')
+
+ def inarrow(self, (x, y)):
+ cl, ct, cr, cb = self._list.LRect((0, 0))
+ l, t, r, b = self._bounds
+ if (x - cl) < 16:
+ cellheight = cb - ct
+ index = (y - ct) / cellheight
+ if index < len(self.items):
+ return 1, index
+ return None, None
+
+ def incolumn(self, (x, y)):
+ l, t, r, b = self._list.LRect((0, 0))
+ abscol = l + self.col
+ return abs(abscol - x) < 3
+
+ def trackcolumn(self, (x, y)):
+ import Qd, QuickDraw, Evt
+ self.SetPort()
+ l, t, r, b = self._bounds
+ bounds = l, t, r, b = l + 1, t + 1, r - 16, b - 1
+ abscol = l + self.col
+ mincol = l + self.mincol
+ maxcol = r - 10
+ diff = abscol - x
+ Qd.PenPat('\000\377\000\377\000\377\000\377')
+ Qd.PenMode(QuickDraw.srcXor)
+ rect = abscol - 1, t, abscol, b
+ Qd.PaintRect(rect)
+ lastpoint = (x, y)
+ newcol = -1
+ #W.SetCursor('fist')
+ while Evt.Button():
+ (x, y) = Evt.GetMouse()
+ if (x, y) <> lastpoint:
+ newcol = x + diff
+ newcol = max(newcol, mincol)
+ newcol = min(newcol, maxcol)
+ Qd.PaintRect(rect)
+ rect = newcol - 1, t, newcol, b
+ Qd.PaintRect(rect)
+ lastpoint = (x, y)
+ Qd.PaintRect(rect)
+ Qd.PenPat(Qd.qd.black)
+ Qd.PenNormal()
+ if newcol > 0 and newcol <> abscol:
+ self.setcolumn(newcol - l)
+
+ def click(self, point, modifiers):
+ if point == (-1, -1): # gross.
+ W.List.click(self, point ,modifiers)
+ return
+ hit, index = self.inarrow(point)
+ if hit:
+ (key, value, arrow, indent) = self.items[index]
+ self.fold(index, arrow == 1)
+ elif self.incolumn(point):
+ self.trackcolumn(point)
+ else:
+ W.List.click(self, point, modifiers)
+
+ # for W.List.key
+ def findmatch(self, tag):
+ lower = string.lower
+ items = self.items
+ taglen = len(tag)
+ match = '\377' * 100
+ match_i = -1
+ for i in range(len(items)):
+ item = lower(str(items[i][0]))
+ if tag <= item < match:
+ match = item
+ match_i = i
+ if match_i >= 0:
+ return match_i
+ else:
+ return len(items) - 1
+
+ def close(self):
+ if self.closechildren:
+ for window in self.children:
+ window.close()
+ self.children = []
+ W.List.close(self)
+
+ def fold(self, index, onoff):
+ (key, value, arrow, indent) = self.items[index]
+ if arrow == 0 or (onoff and arrow == 2) or (not onoff and arrow == 1):
+ return
+ W.SetCursor('watch')
+ topcell = self.gettopcell()
+ if onoff:
+ self[index] = (key, value, 4, indent)
+ self.setdrawingmode(0)
+ self[index+1:index+1] = self.unpack(value, indent + 1)
+ self[index] = (key, value, 2, indent)
+ else:
+ self[index] = (key, value, 3, indent)
+ self.setdrawingmode(0)
+ count = 0
+ for i in range(index + 1, len(self.items)):
+ (dummy, dummy, dummy, subindent) = self.items[i]
+ if subindent <= indent:
+ break
+ count = count + 1
+ self[index+1:index+1+count] = []
+ self[index] = (key, value, 1, indent)
+ maxindent = self.getmaxindent()
+ if maxindent <> self.lastmaxindent:
+ newabsindent = self.col + (maxindent - self.lastmaxindent) * self.indent
+ if newabsindent >= self.mincol:
+ self.setcolumn(newabsindent)
+ self.lastmaxindent = maxindent
+ self.settopcell(topcell)
+ self.setdrawingmode(1)
+
+ def unfoldobjects(self, objects):
+ for obj in objects:
+ try:
+ index = self.items.index(obj)
+ except ValueError:
+ pass
+ else:
+ self.fold(index, 1)
+
+ def getunfoldedobjects(self):
+ curindent = 0
+ objects = []
+ for index in range(len(self.items)):
+ (key, value, arrow, indent) = self.items[index]
+ if indent > curindent:
+ (k, v, a, i) = self.items[index - 1]
+ objects.append((k, v, 1, i))
+ curindent = indent
+ elif indent < curindent:
+ curindent = indent
+ return objects
+
+ def listhit(self, isdbl):
+ if isdbl:
+ self.openselection()
+
+ def openselection(self):
+ import os
+ sel = self.getselection()
+ for index in sel:
+ (key, value, arrow, indent) = self[index]
+ if arrow:
+ self.children.append(Browser(value))
+ elif type(value) == types.StringType and '\0' not in value:
+ editor = self._parentwindow.parent.getscript(value)
+ if editor:
+ editor.select()
+ return
+ elif os.path.exists(value) and os.path.isfile(value):
+ import macfs
+ fss = macfs.FSSpec(value)
+ if fss.GetCreatorType()[1] == 'TEXT':
+ W.getapplication().openscript(value)
+
+ def itemrepr(self, (key, value, arrow, indent), str = str, double_repr = double_repr,
+ arrows = arrows, pack = struct.pack):
+ arrow = arrows[arrow]
+ return arrow + pack('h', self.indent * indent) + self.colstr + \
+ double_repr(key, value, 1)
+
+ def getmaxindent(self, max = max):
+ maxindent = 0
+ for item in self.items:
+ maxindent = max(maxindent, item[3])
+ return maxindent
+
+ def domenu_copy(self, *args):
+ sel = self.getselectedobjects()
+ selitems = []
+ for key, value, dummy, dummy in sel:
+ selitems.append(double_repr(key, value))
+ text = string.join(selitems, '\r')
+ if text:
+ import Scrap
+ Scrap.ZeroScrap()
+ Scrap.PutScrap('TEXT', text)
+
+
+class Browser:
+
+ def __init__(self, object = None, title = None, closechildren = 0):
+ if hasattr(object, '__name__'):
+ name = object.__name__
+ else:
+ name = ''
+ if title is None:
+ title = 'Object browser'
+ if name:
+ title = title + ': ' + name
+ self.w = w = W.Window((300, 400), title, minsize = (100, 100))
+ w.info = W.TextBox((18, 8, -70, 15))
+ w.updatebutton = W.Button((-64, 4, 50, 16), 'Update', self.update)
+ w.browser = BrowserWidget((-1, 24, 1, -14), None)
+ w.bind('cmdu', w.updatebutton.push)
+ w.open()
+ self.set(object, name)
+
+ def close(self):
+ if self.w.wid:
+ self.w.close()
+
+ def set(self, object, name = ''):
+ W.SetCursor('watch')
+ tp = type(object).__name__
+ try:
+ length = len(object)
+ except:
+ length = -1
+ if not name and hasattr(object, '__name__'):
+ name = object.__name__
+ if name:
+ info = name + ': ' + tp
+ else:
+ info = tp
+ if length >= 0:
+ if length == 1:
+ info = info + ' (%d element)' % length
+ else:
+ info = info + ' (%d elements)' % length
+ self.w.info.set(info)
+ self.w.browser.set(object)
+
+ def update(self):
+ self.w.browser.update()
+
+
+SIMPLE_TYPES = (
+ types.NoneType,
+ types.IntType,
+ types.LongType,
+ types.FloatType,
+ types.ComplexType,
+ types.StringType
+)
+
+INDEXING_TYPES = (
+ types.TupleType,
+ types.ListType,
+ types.DictionaryType
+)
+
+def unpack_object(object, indent = 0):
+ tp = type(object)
+ if tp in SIMPLE_TYPES and tp is not types.NoneType:
+ raise TypeError, "can't browse simple type: %s" % tp.__name__
+ elif tp == types.DictionaryType:
+ return unpack_dict(object, indent)
+ elif tp in (types.TupleType, types.ListType):
+ return unpack_sequence(object, indent)
+ elif tp == types.InstanceType:
+ return unpack_instance(object, indent)
+ elif tp == types.ClassType:
+ return unpack_class(object, indent)
+ elif tp == types.ModuleType:
+ return unpack_dict(object.__dict__, indent)
+ else:
+ return unpack_other(object, indent)
+
+def unpack_sequence(seq, indent = 0):
+ items = map(None, range(len(seq)), seq)
+ items = map(lambda (k, v), type = type, simp = SIMPLE_TYPES, indent = indent:
+ (k, v, not type(v) in simp, indent), items)
+ return items
+
+def unpack_dict(dict, indent = 0):
+ items = dict.items()
+ return pack_items(items, indent)
+
+def unpack_instance(inst, indent = 0):
+ if hasattr(inst, '__pybrowse_unpack__'):
+ return unpack_object(inst.__pybrowse_unpack__(), indent)
+ else:
+ items = [('__class__', inst.__class__)] + inst.__dict__.items()
+ return pack_items(items, indent)
+
+def unpack_class(clss, indent = 0):
+ items = [('__bases__', clss.__bases__), ('__name__', clss.__name__)] + clss.__dict__.items()
+ return pack_items(items, indent)
+
+def unpack_other(object, indent = 0):
+ attrs = []
+ if hasattr(object, '__members__'):
+ attrs = attrs + object.__members__
+ if hasattr(object, '__methods__'):
+ attrs = attrs + object.__methods__
+ items = []
+ for attr in attrs:
+ items.append((attr, getattr(object, attr)))
+ return pack_items(items, indent)
+
+def pack_items(items, indent = 0):
+ items = map(lambda (k, v), type = type, simp = SIMPLE_TYPES, indent = indent:
+ (k, v, not type(v) in simp, indent),
+ items)
+ return tuple_caselesssort(items)
+
+def caselesssort(alist):
+ """Return a sorted copy of a list. If there are only strings in the list,
+ it will not consider case"""
+
+ try:
+ # turn ['FOO', 'aaBc', 'ABcD'] into [('foo', 'FOO'), ('aabc', 'aaBc'), ('abcd', 'ABcD')], if possible
+ tupledlist = map(lambda item, lower = string.lower: (lower(item), item), alist)
+ except TypeError:
+ # at least one element in alist is not a string, proceed the normal way...
+ alist = alist[:]
+ alist.sort()
+ return alist
+ else:
+ tupledlist.sort()
+ # turn [('aabc', 'aaBc'), ('abcd', 'ABcD'), ('foo', 'FOO')] into ['aaBc', 'ABcD', 'FOO']
+ return map(lambda x: x[1], tupledlist)
+
+def tuple_caselesssort(items):
+ try:
+ tupledlist = map(lambda tuple, lower = string.lower: (lower(tuple[0]), tuple), items)
+ except (AttributeError, TypeError):
+ items = items[:]
+ items.sort()
+ return items
+ else:
+ tupledlist.sort()
+ return map(lambda (low, tuple): tuple, tupledlist)
+
--- /dev/null
+"""A (less & less) simple Python editor"""
+
+import W
+import Wtraceback
+from Wkeys import *
+
+import macfs
+import MACFS
+import MacOS
+import Win
+import Res
+import Evt
+import os
+import imp
+import sys
+import string
+import marshal
+import re
+
+try:
+ import Wthreading
+except ImportError:
+ haveThreading = 0
+else:
+ haveThreading = Wthreading.haveThreading
+
+_scriptuntitledcounter = 1
+# _wordchars = string.letters + string.digits + "_"
+_wordchars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'
+
+
+runButtonLabels = ["Run all", "Stop!"]
+runSelButtonLabels = ["Run selection", "Pause!", "Resume"]
+
+
+class Editor(W.Window):
+
+ def __init__(self, path = "", title = ""):
+ defaultfontsettings, defaulttabsettings, defaultwindowsize = geteditorprefs()
+ global _scriptuntitledcounter
+ if not path:
+ if title:
+ self.title = title
+ else:
+ self.title = "Untitled Script " + `_scriptuntitledcounter`
+ _scriptuntitledcounter = _scriptuntitledcounter + 1
+ text = ""
+ self._creator = W._signature
+ elif os.path.exists(path):
+ path = resolvealiases(path)
+ dir, name = os.path.split(path)
+ self.title = name
+ f = open(path, "rb")
+ text = f.read()
+ f.close()
+ fss = macfs.FSSpec(path)
+ self._creator, filetype = fss.GetCreatorType()
+ else:
+ raise IOError, "file '%s' does not exist" % path
+ self.path = path
+
+ if '\n' in text:
+ import EasyDialogs
+ if string.find(text, '\r\n') >= 0:
+ sourceOS = 'DOS'
+ searchString = '\r\n'
+ else:
+ sourceOS = 'UNIX'
+ searchString = '\n'
+ change = EasyDialogs.AskYesNoCancel('"%s" contains %s-style line feeds. '
+ 'Change them to MacOS carriage returns?' % (self.title, sourceOS), 1)
+ # bug: Cancel is treated as No
+ if change > 0:
+ text = string.replace(text, searchString, '\r')
+ else:
+ change = 0
+
+ self.settings = {}
+ if self.path:
+ self.readwindowsettings()
+ if self.settings.has_key("windowbounds"):
+ bounds = self.settings["windowbounds"]
+ else:
+ bounds = defaultwindowsize
+ if self.settings.has_key("fontsettings"):
+ self.fontsettings = self.settings["fontsettings"]
+ else:
+ self.fontsettings = defaultfontsettings
+ if self.settings.has_key("tabsize"):
+ try:
+ self.tabsettings = (tabsize, tabmode) = self.settings["tabsize"]
+ except:
+ self.tabsettings = defaulttabsettings
+ else:
+ self.tabsettings = defaulttabsettings
+
+ W.Window.__init__(self, bounds, self.title, minsize = (330, 120), tabbable = 0)
+ self.setupwidgets(text)
+ if change > 0:
+ self.editgroup.editor.changed = 1
+
+ if self.settings.has_key("selection"):
+ selstart, selend = self.settings["selection"]
+ self.setselection(selstart, selend)
+ self.open()
+ self.setinfotext()
+ self.globals = {}
+ self._buf = "" # for write method
+ self.debugging = 0
+ self.profiling = 0
+ if self.settings.has_key("run_as_main"):
+ self.run_as_main = self.settings["run_as_main"]
+ else:
+ self.run_as_main = 0
+ if self.settings.has_key("run_with_interpreter"):
+ self.run_with_interpreter = self.settings["run_with_interpreter"]
+ else:
+ self.run_with_interpreter = 0
+ self._threadstate = (0, 0)
+ self._thread = None
+
+ def readwindowsettings(self):
+ try:
+ resref = Res.FSpOpenResFile(self.path, 1)
+ except Res.Error:
+ return
+ try:
+ Res.UseResFile(resref)
+ data = Res.Get1Resource('PyWS', 128)
+ self.settings = marshal.loads(data.data)
+ except:
+ pass
+ Res.CloseResFile(resref)
+
+ def writewindowsettings(self):
+ try:
+ resref = Res.FSpOpenResFile(self.path, 3)
+ except Res.Error:
+ Res.FSpCreateResFile(self.path, self._creator, 'TEXT', MACFS.smAllScripts)
+ resref = Res.FSpOpenResFile(self.path, 3)
+ try:
+ data = Res.Resource(marshal.dumps(self.settings))
+ Res.UseResFile(resref)
+ try:
+ temp = Res.Get1Resource('PyWS', 128)
+ temp.RemoveResource()
+ except Res.Error:
+ pass
+ data.AddResource('PyWS', 128, "window settings")
+ finally:
+ Res.UpdateResFile(resref)
+ Res.CloseResFile(resref)
+
+ def getsettings(self):
+ self.settings = {}
+ self.settings["windowbounds"] = self.getbounds()
+ self.settings["selection"] = self.getselection()
+ self.settings["fontsettings"] = self.editgroup.editor.getfontsettings()
+ self.settings["tabsize"] = self.editgroup.editor.gettabsettings()
+ self.settings["run_as_main"] = self.run_as_main
+ self.settings["run_with_interpreter"] = self.run_with_interpreter
+
+ def get(self):
+ return self.editgroup.editor.get()
+
+ def getselection(self):
+ return self.editgroup.editor.ted.WEGetSelection()
+
+ def setselection(self, selstart, selend):
+ self.editgroup.editor.setselection(selstart, selend)
+
+ def getfilename(self):
+ if self.path:
+ return self.path
+ return '<%s>' % self.title
+
+ def setupwidgets(self, text):
+ topbarheight = 24
+ popfieldwidth = 80
+ self.lastlineno = None
+
+ # make an editor
+ self.editgroup = W.Group((0, topbarheight + 1, 0, 0))
+ editor = W.PyEditor((0, 0, -15,-15), text,
+ fontsettings = self.fontsettings,
+ tabsettings = self.tabsettings,
+ file = self.getfilename())
+
+ # make the widgets
+ self.popfield = ClassFinder((popfieldwidth - 17, -15, 16, 16), [], self.popselectline)
+ self.linefield = W.EditText((-1, -15, popfieldwidth - 15, 16), inset = (6, 1))
+ self.editgroup._barx = W.Scrollbar((popfieldwidth - 2, -15, -14, 16), editor.hscroll, max = 32767)
+ self.editgroup._bary = W.Scrollbar((-15, 14, 16, -14), editor.vscroll, max = 32767)
+ self.editgroup.editor = editor # add editor *after* scrollbars
+
+ self.editgroup.optionsmenu = W.PopupMenu((-15, -1, 16, 16), [])
+ self.editgroup.optionsmenu.bind('<click>', self.makeoptionsmenu)
+
+ self.bevelbox = W.BevelBox((0, 0, 0, topbarheight))
+ self.hline = W.HorizontalLine((0, topbarheight, 0, 0))
+ self.infotext = W.TextBox((175, 6, -4, 14), backgroundcolor = (0xe000, 0xe000, 0xe000))
+ self.runbutton = W.Button((5, 4, 80, 16), runButtonLabels[0], self.run)
+ self.runselbutton = W.Button((90, 4, 80, 16), runSelButtonLabels[0], self.runselection)
+
+ # bind some keys
+ editor.bind("cmdr", self.runbutton.push)
+ editor.bind("enter", self.runselbutton.push)
+ editor.bind("cmdj", self.domenu_gotoline)
+ editor.bind("cmdd", self.domenu_toggledebugger)
+ editor.bind("<idle>", self.updateselection)
+
+ editor.bind("cmde", searchengine.setfindstring)
+ editor.bind("cmdf", searchengine.show)
+ editor.bind("cmdg", searchengine.findnext)
+ editor.bind("cmdshiftr", searchengine.replace)
+ editor.bind("cmdt", searchengine.replacefind)
+
+ self.linefield.bind("return", self.dolinefield)
+ self.linefield.bind("enter", self.dolinefield)
+ self.linefield.bind("tab", self.dolinefield)
+
+ # intercept clicks
+ editor.bind("<click>", self.clickeditor)
+ self.linefield.bind("<click>", self.clicklinefield)
+
+ def makeoptionsmenu(self):
+ menuitems = [('Font settings\xc9', self.domenu_fontsettings),
+ ("Save options\xc9", self.domenu_options),
+ '-',
+ ('\0' + chr(self.run_as_main) + 'Run as __main__', self.domenu_toggle_run_as_main),
+ #('\0' + chr(self.run_with_interpreter) + 'Run with Interpreter', self.domenu_toggle_run_with_interpreter),
+ #'-',
+ ('Modularize', self.domenu_modularize),
+ ('Browse namespace\xc9', self.domenu_browsenamespace),
+ '-']
+ if self.profiling:
+ menuitems = menuitems + [('Disable profiler', self.domenu_toggleprofiler)]
+ else:
+ menuitems = menuitems + [('Enable profiler', self.domenu_toggleprofiler)]
+ if self.editgroup.editor._debugger:
+ menuitems = menuitems + [('Disable debugger', self.domenu_toggledebugger),
+ ('Clear breakpoints', self.domenu_clearbreakpoints),
+ ('Edit breakpoints\xc9', self.domenu_editbreakpoints)]
+ else:
+ menuitems = menuitems + [('Enable debugger', self.domenu_toggledebugger)]
+ self.editgroup.optionsmenu.set(menuitems)
+
+ def domenu_toggle_run_as_main(self):
+ self.run_as_main = not self.run_as_main
+ self.run_with_interpreter = 0
+ self.editgroup.editor.selchanged = 1
+
+ def domenu_toggle_run_with_interpreter(self):
+ self.run_with_interpreter = not self.run_with_interpreter
+ self.run_as_main = 0
+ self.editgroup.editor.selchanged = 1
+
+ def showbreakpoints(self, onoff):
+ self.editgroup.editor.showbreakpoints(onoff)
+ self.debugging = onoff
+
+ def domenu_clearbreakpoints(self, *args):
+ self.editgroup.editor.clearbreakpoints()
+
+ def domenu_editbreakpoints(self, *args):
+ self.editgroup.editor.editbreakpoints()
+
+ def domenu_toggledebugger(self, *args):
+ if not self.debugging:
+ W.SetCursor('watch')
+ self.debugging = not self.debugging
+ self.editgroup.editor.togglebreakpoints()
+
+ def domenu_toggleprofiler(self, *args):
+ self.profiling = not self.profiling
+
+ def domenu_browsenamespace(self, *args):
+ import PyBrowser, W
+ W.SetCursor('watch')
+ globals, file, modname = self.getenvironment()
+ if not modname:
+ modname = self.title
+ PyBrowser.Browser(globals, "Object browser: " + modname)
+
+ def domenu_modularize(self, *args):
+ modname = _filename_as_modname(self.title)
+ if not modname:
+ raise W.AlertError, "Can't modularize \"%s\"" % self.title
+ run_as_main = self.run_as_main
+ self.run_as_main = 0
+ self.run()
+ self.run_as_main = run_as_main
+ if self.path:
+ file = self.path
+ else:
+ file = self.title
+
+ if self.globals and not sys.modules.has_key(modname):
+ module = imp.new_module(modname)
+ for attr in self.globals.keys():
+ setattr(module,attr,self.globals[attr])
+ sys.modules[modname] = module
+ self.globals = {}
+
+ def domenu_fontsettings(self, *args):
+ import FontSettings
+ fontsettings = self.editgroup.editor.getfontsettings()
+ tabsettings = self.editgroup.editor.gettabsettings()
+ settings = FontSettings.FontDialog(fontsettings, tabsettings)
+ if settings:
+ fontsettings, tabsettings = settings
+ self.editgroup.editor.setfontsettings(fontsettings)
+ self.editgroup.editor.settabsettings(tabsettings)
+
+ def domenu_options(self, *args):
+ rv = SaveOptions(self._creator)
+ if rv:
+ self.editgroup.editor.selchanged = 1 # ouch...
+ self._creator = rv
+
+ def clicklinefield(self):
+ if self._currentwidget <> self.linefield:
+ self.linefield.select(1)
+ self.linefield.selectall()
+ return 1
+
+ def clickeditor(self):
+ if self._currentwidget <> self.editgroup.editor:
+ self.dolinefield()
+ return 1
+
+ def updateselection(self, force = 0):
+ sel = min(self.editgroup.editor.getselection())
+ lineno = self.editgroup.editor.offsettoline(sel)
+ if lineno <> self.lastlineno or force:
+ self.lastlineno = lineno
+ self.linefield.set(str(lineno + 1))
+ self.linefield.selview()
+
+ def dolinefield(self):
+ try:
+ lineno = string.atoi(self.linefield.get()) - 1
+ if lineno <> self.lastlineno:
+ self.editgroup.editor.selectline(lineno)
+ self.updateselection(1)
+ except:
+ self.updateselection(1)
+ self.editgroup.editor.select(1)
+
+ def setinfotext(self):
+ if not hasattr(self, 'infotext'):
+ return
+ if self.path:
+ self.infotext.set(self.path)
+ else:
+ self.infotext.set("")
+
+ def close(self):
+ if self.editgroup.editor.changed:
+ import EasyDialogs
+ import Qd
+ Qd.InitCursor()
+ save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?' % self.title,
+ default=1, no="Don\xd5t save")
+ if save > 0:
+ if self.domenu_save():
+ return 1
+ elif save < 0:
+ return 1
+ self.globals = None
+ W.Window.close(self)
+
+ def domenu_close(self, *args):
+ return self.close()
+
+ def domenu_save(self, *args):
+ if not self.path:
+ # Will call us recursively
+ return self.domenu_save_as()
+ data = self.editgroup.editor.get()
+ fp = open(self.path, 'wb') # open file in binary mode, data has '\r' line-endings
+ fp.write(data)
+ fp.close()
+ fss = macfs.FSSpec(self.path)
+ fss.SetCreatorType(self._creator, 'TEXT')
+ self.getsettings()
+ self.writewindowsettings()
+ self.editgroup.editor.changed = 0
+ self.editgroup.editor.selchanged = 0
+ import linecache
+ if linecache.cache.has_key(self.path):
+ del linecache.cache[self.path]
+ import macostools
+ macostools.touched(self.path)
+
+ def can_save(self, menuitem):
+ return self.editgroup.editor.changed or self.editgroup.editor.selchanged
+
+ def domenu_save_as(self, *args):
+ fss, ok = macfs.StandardPutFile('Save as:', self.title)
+ if not ok:
+ return 1
+ self.showbreakpoints(0)
+ self.path = fss.as_pathname()
+ self.setinfotext()
+ self.title = os.path.split(self.path)[-1]
+ self.wid.SetWTitle(self.title)
+ self.domenu_save()
+ self.editgroup.editor.setfile(self.getfilename())
+ app = W.getapplication()
+ app.makeopenwindowsmenu()
+ if hasattr(app, 'makescriptsmenu'):
+ app = W.getapplication()
+ fss, fss_changed = app.scriptsfolder.Resolve()
+ path = fss.as_pathname()
+ if path == self.path[:len(path)]:
+ W.getapplication().makescriptsmenu()
+
+ def domenu_save_as_applet(self, *args):
+ import buildtools
+
+ buildtools.DEBUG = 0 # ouch.
+
+ if self.title[-3:] == ".py":
+ destname = self.title[:-3]
+ else:
+ destname = self.title + ".applet"
+ fss, ok = macfs.StandardPutFile('Save as Applet:', destname)
+ if not ok:
+ return 1
+ W.SetCursor("watch")
+ destname = fss.as_pathname()
+ if self.path:
+ filename = self.path
+ if filename[-3:] == ".py":
+ rsrcname = filename[:-3] + '.rsrc'
+ else:
+ rsrcname = filename + '.rsrc'
+ else:
+ filename = self.title
+ rsrcname = ""
+
+ pytext = self.editgroup.editor.get()
+ pytext = string.split(pytext, '\r')
+ pytext = string.join(pytext, '\n') + '\n'
+ try:
+ code = compile(pytext, filename, "exec")
+ except (SyntaxError, EOFError):
+ raise buildtools.BuildError, "Syntax error in script %s" % `filename`
+
+ # Try removing the output file
+ try:
+ os.remove(destname)
+ except os.error:
+ pass
+ template = buildtools.findtemplate()
+ buildtools.process_common(template, None, code, rsrcname, destname, 0, 1)
+
+ def domenu_gotoline(self, *args):
+ self.linefield.selectall()
+ self.linefield.select(1)
+ self.linefield.selectall()
+
+ def domenu_selectline(self, *args):
+ self.editgroup.editor.expandselection()
+
+ def domenu_find(self, *args):
+ searchengine.show()
+
+ def domenu_entersearchstring(self, *args):
+ searchengine.setfindstring()
+
+ def domenu_replace(self, *args):
+ searchengine.replace()
+
+ def domenu_findnext(self, *args):
+ searchengine.findnext()
+
+ def domenu_replacefind(self, *args):
+ searchengine.replacefind()
+
+ def domenu_run(self, *args):
+ self.runbutton.push()
+
+ def domenu_runselection(self, *args):
+ self.runselbutton.push()
+
+ def run(self):
+ if self._threadstate == (0, 0):
+ self._run()
+ else:
+ lock = Wthreading.Lock()
+ lock.acquire()
+ self._thread.postException(KeyboardInterrupt)
+ if self._thread.isBlocked():
+ self._thread.start()
+ lock.release()
+
+ def _run(self):
+ if self.run_with_interpreter:
+ if self.editgroup.editor.changed:
+ import EasyDialogs
+ import Qd; Qd.InitCursor()
+ save = EasyDialogs.AskYesNoCancel('Save "%s" before running?' % self.title, 1)
+ if save > 0:
+ if self.domenu_save():
+ return
+ elif save < 0:
+ return
+ if not self.path:
+ raise W.AlertError, "Can't run unsaved file"
+ self._run_with_interpreter()
+ else:
+ pytext = self.editgroup.editor.get()
+ globals, file, modname = self.getenvironment()
+ self.execstring(pytext, globals, globals, file, modname)
+
+ def _run_with_interpreter(self):
+ interp_path = os.path.join(sys.exec_prefix, "PythonInterpreter")
+ if not os.path.exists(interp_path):
+ raise W.AlertError, "Can't find interpreter"
+ import findertools
+ XXX
+
+ def runselection(self):
+ if self._threadstate == (0, 0):
+ self._runselection()
+ elif self._threadstate == (1, 1):
+ self._thread.block()
+ self.setthreadstate((1, 2))
+ elif self._threadstate == (1, 2):
+ self._thread.start()
+ self.setthreadstate((1, 1))
+
+ def _runselection(self):
+ if self.run_with_interpreter:
+ raise W.AlertError, "Can't run selection with Interpreter"
+ globals, file, modname = self.getenvironment()
+ locals = globals
+ # select whole lines
+ self.editgroup.editor.expandselection()
+
+ # get lineno of first selected line
+ selstart, selend = self.editgroup.editor.getselection()
+ selstart, selend = min(selstart, selend), max(selstart, selend)
+ selfirstline = self.editgroup.editor.offsettoline(selstart)
+ alltext = self.editgroup.editor.get()
+ pytext = alltext[selstart:selend]
+ lines = string.split(pytext, '\r')
+ indent = getminindent(lines)
+ if indent == 1:
+ classname = ''
+ alllines = string.split(alltext, '\r')
+ for i in range(selfirstline - 1, -1, -1):
+ line = alllines[i]
+ if line[:6] == 'class ':
+ classname = string.split(string.strip(line[6:]))[0]
+ classend = identifieRE_match(classname)
+ if classend < 1:
+ raise W.AlertError, "Can't find a class."
+ classname = classname[:classend]
+ break
+ elif line and line[0] not in '\t#':
+ raise W.AlertError, "Can't find a class."
+ else:
+ raise W.AlertError, "Can't find a class."
+ if globals.has_key(classname):
+ klass = globals[classname]
+ else:
+ raise W.AlertError, "Can't find class \"%s\"." % classname
+ # add class def
+ pytext = ("class %s:\n" % classname) + pytext
+ selfirstline = selfirstline - 1
+ elif indent > 0:
+ raise W.AlertError, "Can't run indented code."
+
+ # add "newlines" to fool compile/exec:
+ # now a traceback will give the right line number
+ pytext = selfirstline * '\r' + pytext
+ self.execstring(pytext, globals, locals, file, modname)
+ if indent == 1 and globals[classname] is not klass:
+ # update the class in place
+ klass.__dict__.update(globals[classname].__dict__)
+ globals[classname] = klass
+
+ def setthreadstate(self, state):
+ oldstate = self._threadstate
+ if oldstate[0] <> state[0]:
+ self.runbutton.settitle(runButtonLabels[state[0]])
+ if oldstate[1] <> state[1]:
+ self.runselbutton.settitle(runSelButtonLabels[state[1]])
+ self._threadstate = state
+
+ def _exec_threadwrapper(self, *args, **kwargs):
+ apply(execstring, args, kwargs)
+ self.setthreadstate((0, 0))
+ self._thread = None
+
+ def execstring(self, pytext, globals, locals, file, modname):
+ tracebackwindow.hide()
+ # update windows
+ W.getapplication().refreshwindows()
+ if self.run_as_main:
+ modname = "__main__"
+ if self.path:
+ dir = os.path.dirname(self.path)
+ savedir = os.getcwd()
+ os.chdir(dir)
+ sys.path.insert(0, dir)
+ else:
+ cwdindex = None
+ try:
+ if haveThreading:
+ self._thread = Wthreading.Thread(os.path.basename(file),
+ self._exec_threadwrapper, pytext, globals, locals, file, self.debugging,
+ modname, self.profiling)
+ self.setthreadstate((1, 1))
+ self._thread.start()
+ else:
+ execstring(pytext, globals, locals, file, self.debugging,
+ modname, self.profiling)
+ finally:
+ if self.path:
+ os.chdir(savedir)
+ del sys.path[0]
+
+ def getenvironment(self):
+ if self.path:
+ file = self.path
+ dir = os.path.dirname(file)
+ # check if we're part of a package
+ modname = ""
+ while os.path.exists(os.path.join(dir, "__init__.py")):
+ dir, dirname = os.path.split(dir)
+ modname = dirname + '.' + modname
+ subname = _filename_as_modname(self.title)
+ if modname:
+ if subname == "__init__":
+ # strip trailing period
+ modname = modname[:-1]
+ else:
+ modname = modname + subname
+ else:
+ modname = subname
+ if sys.modules.has_key(modname):
+ globals = sys.modules[modname].__dict__
+ self.globals = {}
+ else:
+ globals = self.globals
+ modname = subname
+ else:
+ file = '<%s>' % self.title
+ globals = self.globals
+ modname = file
+ return globals, file, modname
+
+ def write(self, stuff):
+ """for use as stdout"""
+ self._buf = self._buf + stuff
+ if '\n' in self._buf:
+ self.flush()
+
+ def flush(self):
+ stuff = string.split(self._buf, '\n')
+ stuff = string.join(stuff, '\r')
+ end = self.editgroup.editor.ted.WEGetTextLength()
+ self.editgroup.editor.ted.WESetSelection(end, end)
+ self.editgroup.editor.ted.WEInsert(stuff, None, None)
+ self.editgroup.editor.updatescrollbars()
+ self._buf = ""
+ # ? optional:
+ #self.wid.SelectWindow()
+
+ def getclasslist(self):
+ from string import find, strip
+ methodRE = re.compile(r"\r[ \t]+def ")
+ findMethod = methodRE.search
+ editor = self.editgroup.editor
+ text = editor.get()
+ list = []
+ append = list.append
+ functag = "func"
+ classtag = "class"
+ methodtag = "method"
+ pos = -1
+ if text[:4] == 'def ':
+ append((pos + 4, functag))
+ pos = 4
+ while 1:
+ pos = find(text, '\rdef ', pos + 1)
+ if pos < 0:
+ break
+ append((pos + 5, functag))
+ pos = -1
+ if text[:6] == 'class ':
+ append((pos + 6, classtag))
+ pos = 6
+ while 1:
+ pos = find(text, '\rclass ', pos + 1)
+ if pos < 0:
+ break
+ append((pos + 7, classtag))
+ pos = 0
+ while 1:
+ m = findMethod(text, pos + 1)
+ if m is None:
+ break
+ pos = m.regs[0][0]
+ #pos = find(text, '\r\tdef ', pos + 1)
+ append((m.regs[0][1], methodtag))
+ list.sort()
+ classlist = []
+ methodlistappend = None
+ offsetToLine = editor.ted.WEOffsetToLine
+ getLineRange = editor.ted.WEGetLineRange
+ append = classlist.append
+ for pos, tag in list:
+ lineno = offsetToLine(pos)
+ lineStart, lineEnd = getLineRange(lineno)
+ line = strip(text[pos:lineEnd])
+ line = line[:identifieRE_match(line)]
+ if tag is functag:
+ append(("def " + line, lineno + 1))
+ methodlistappend = None
+ elif tag is classtag:
+ append(["class " + line])
+ methodlistappend = classlist[-1].append
+ elif methodlistappend and tag is methodtag:
+ methodlistappend(("def " + line, lineno + 1))
+ return classlist
+
+ def popselectline(self, lineno):
+ self.editgroup.editor.selectline(lineno - 1)
+
+ def selectline(self, lineno, charoffset = 0):
+ self.editgroup.editor.selectline(lineno - 1, charoffset)
+
+class _saveoptions:
+
+ def __init__(self, creator):
+ self.rv = None
+ self.w = w = W.ModalDialog((240, 140), 'Save options')
+ radiobuttons = []
+ w.label = W.TextBox((8, 8, 80, 18), "File creator:")
+ w.ide_radio = W.RadioButton((8, 22, 160, 18), "This application", radiobuttons, self.ide_hit)
+ w.interp_radio = W.RadioButton((8, 42, 160, 18), "Python Interpreter", radiobuttons, self.interp_hit)
+ w.other_radio = W.RadioButton((8, 62, 50, 18), "Other:", radiobuttons)
+ w.other_creator = W.EditText((62, 62, 40, 20), creator, self.otherselect)
+ w.cancelbutton = W.Button((-180, -30, 80, 16), "Cancel", self.cancelbuttonhit)
+ w.okbutton = W.Button((-90, -30, 80, 16), "Done", self.okbuttonhit)
+ w.setdefaultbutton(w.okbutton)
+ if creator == 'Pyth':
+ w.interp_radio.set(1)
+ elif creator == W._signature:
+ w.ide_radio.set(1)
+ else:
+ w.other_radio.set(1)
+ w.bind("cmd.", w.cancelbutton.push)
+ w.open()
+
+ def ide_hit(self):
+ self.w.other_creator.set(W._signature)
+
+ def interp_hit(self):
+ self.w.other_creator.set("Pyth")
+
+ def otherselect(self, *args):
+ sel_from, sel_to = self.w.other_creator.getselection()
+ creator = self.w.other_creator.get()[:4]
+ creator = creator + " " * (4 - len(creator))
+ self.w.other_creator.set(creator)
+ self.w.other_creator.setselection(sel_from, sel_to)
+ self.w.other_radio.set(1)
+
+ def cancelbuttonhit(self):
+ self.w.close()
+
+ def okbuttonhit(self):
+ self.rv = self.w.other_creator.get()[:4]
+ self.w.close()
+
+
+def SaveOptions(creator):
+ s = _saveoptions(creator)
+ return s.rv
+
+
+def _escape(where, what) :
+ return string.join(string.split(where, what), '\\' + what)
+
+def _makewholewordpattern(word):
+ # first, escape special regex chars
+ for esc in "\\[]()|.*^+$?":
+ word = _escape(word, esc)
+ notwordcharspat = '[^' + _wordchars + ']'
+ pattern = '(' + word + ')'
+ if word[0] in _wordchars:
+ pattern = notwordcharspat + pattern
+ if word[-1] in _wordchars:
+ pattern = pattern + notwordcharspat
+ return re.compile(pattern)
+
+class SearchEngine:
+
+ def __init__(self):
+ self.visible = 0
+ self.w = None
+ self.parms = { "find": "",
+ "replace": "",
+ "wrap": 1,
+ "casesens": 1,
+ "wholeword": 1
+ }
+ import MacPrefs
+ prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
+ if prefs.searchengine:
+ self.parms["casesens"] = prefs.searchengine.casesens
+ self.parms["wrap"] = prefs.searchengine.wrap
+ self.parms["wholeword"] = prefs.searchengine.wholeword
+
+ def show(self):
+ self.visible = 1
+ if self.w:
+ self.w.wid.ShowWindow()
+ self.w.wid.SelectWindow()
+ self.w.find.edit.select(1)
+ self.w.find.edit.selectall()
+ return
+ self.w = W.Dialog((420, 150), "Find")
+
+ self.w.find = TitledEditText((10, 4, 300, 36), "Search for:")
+ self.w.replace = TitledEditText((10, 100, 300, 36), "Replace with:")
+
+ self.w.boxes = W.Group((10, 50, 300, 40))
+ self.w.boxes.casesens = W.CheckBox((0, 0, 100, 16), "Case sensitive")
+ self.w.boxes.wholeword = W.CheckBox((0, 20, 100, 16), "Whole word")
+ self.w.boxes.wrap = W.CheckBox((110, 0, 100, 16), "Wrap around")
+
+ self.buttons = [ ("Find", "cmdf", self.find),
+ ("Replace", "cmdr", self.replace),
+ ("Replace all", None, self.replaceall),
+ ("Don't find", "cmdd", self.dont),
+ ("Cancel", "cmd.", self.cancel)
+ ]
+ for i in range(len(self.buttons)):
+ bounds = -90, 22 + i * 24, 80, 16
+ title, shortcut, callback = self.buttons[i]
+ self.w[title] = W.Button(bounds, title, callback)
+ if shortcut:
+ self.w.bind(shortcut, self.w[title].push)
+ self.w.setdefaultbutton(self.w["Don't find"])
+ self.w.find.edit.bind("<key>", self.key)
+ self.w.bind("<activate>", self.activate)
+ self.w.bind("<close>", self.close)
+ self.w.open()
+ self.setparms()
+ self.w.find.edit.select(1)
+ self.w.find.edit.selectall()
+ self.checkbuttons()
+
+ def close(self):
+ self.hide()
+ return -1
+
+ def key(self, char, modifiers):
+ self.w.find.edit.key(char, modifiers)
+ self.checkbuttons()
+ return 1
+
+ def activate(self, onoff):
+ if onoff:
+ self.checkbuttons()
+
+ def checkbuttons(self):
+ editor = findeditor(self)
+ if editor:
+ if self.w.find.get():
+ for title, cmd, call in self.buttons[:-2]:
+ self.w[title].enable(1)
+ self.w.setdefaultbutton(self.w["Find"])
+ else:
+ for title, cmd, call in self.buttons[:-2]:
+ self.w[title].enable(0)
+ self.w.setdefaultbutton(self.w["Don't find"])
+ else:
+ for title, cmd, call in self.buttons[:-2]:
+ self.w[title].enable(0)
+ self.w.setdefaultbutton(self.w["Don't find"])
+
+ def find(self):
+ self.getparmsfromwindow()
+ if self.findnext():
+ self.hide()
+
+ def replace(self):
+ editor = findeditor(self)
+ if not editor:
+ return
+ if self.visible:
+ self.getparmsfromwindow()
+ text = editor.getselectedtext()
+ find = self.parms["find"]
+ if not self.parms["casesens"]:
+ find = string.lower(find)
+ text = string.lower(text)
+ if text == find:
+ self.hide()
+ editor.insert(self.parms["replace"])
+
+ def replaceall(self):
+ editor = findeditor(self)
+ if not editor:
+ return
+ if self.visible:
+ self.getparmsfromwindow()
+ W.SetCursor("watch")
+ find = self.parms["find"]
+ if not find:
+ return
+ findlen = len(find)
+ replace = self.parms["replace"]
+ replacelen = len(replace)
+ Text = editor.get()
+ if not self.parms["casesens"]:
+ find = string.lower(find)
+ text = string.lower(Text)
+ else:
+ text = Text
+ newtext = ""
+ pos = 0
+ counter = 0
+ while 1:
+ if self.parms["wholeword"]:
+ wholewordRE = _makewholewordpattern(find)
+ match = wholewordRE.search(text, pos)
+ if match:
+ pos = match.start(1)
+ else:
+ pos = -1
+ else:
+ pos = string.find(text, find, pos)
+ if pos < 0:
+ break
+ counter = counter + 1
+ text = text[:pos] + replace + text[pos + findlen:]
+ Text = Text[:pos] + replace + Text[pos + findlen:]
+ pos = pos + replacelen
+ W.SetCursor("arrow")
+ if counter:
+ self.hide()
+ import EasyDialogs
+ import Res
+ editor.changed = 1
+ editor.selchanged = 1
+ editor.ted.WEUseText(Res.Resource(Text))
+ editor.ted.WECalText()
+ editor.SetPort()
+ editor.GetWindow().InvalWindowRect(editor._bounds)
+ #editor.ted.WEUpdate(self.w.wid.GetWindowPort().visRgn)
+ EasyDialogs.Message("Replaced %d occurrences" % counter)
+
+ def dont(self):
+ self.getparmsfromwindow()
+ self.hide()
+
+ def replacefind(self):
+ self.replace()
+ self.findnext()
+
+ def setfindstring(self):
+ editor = findeditor(self)
+ if not editor:
+ return
+ find = editor.getselectedtext()
+ if not find:
+ return
+ self.parms["find"] = find
+ if self.w:
+ self.w.find.edit.set(self.parms["find"])
+ self.w.find.edit.selectall()
+
+ def findnext(self):
+ editor = findeditor(self)
+ if not editor:
+ return
+ find = self.parms["find"]
+ if not find:
+ return
+ text = editor.get()
+ if not self.parms["casesens"]:
+ find = string.lower(find)
+ text = string.lower(text)
+ selstart, selend = editor.getselection()
+ selstart, selend = min(selstart, selend), max(selstart, selend)
+ if self.parms["wholeword"]:
+ wholewordRE = _makewholewordpattern(find)
+ match = wholewordRE.search(text, selend)
+ if match:
+ pos = match.start(1)
+ else:
+ pos = -1
+ else:
+ pos = string.find(text, find, selend)
+ if pos >= 0:
+ editor.setselection(pos, pos + len(find))
+ return 1
+ elif self.parms["wrap"]:
+ if self.parms["wholeword"]:
+ match = wholewordRE.search(text, 0)
+ if match:
+ pos = match.start(1)
+ else:
+ pos = -1
+ else:
+ pos = string.find(text, find)
+ if selstart > pos >= 0:
+ editor.setselection(pos, pos + len(find))
+ return 1
+
+ def setparms(self):
+ for key, value in self.parms.items():
+ try:
+ self.w[key].set(value)
+ except KeyError:
+ self.w.boxes[key].set(value)
+
+ def getparmsfromwindow(self):
+ if not self.w:
+ return
+ for key, value in self.parms.items():
+ try:
+ value = self.w[key].get()
+ except KeyError:
+ value = self.w.boxes[key].get()
+ self.parms[key] = value
+
+ def cancel(self):
+ self.hide()
+ self.setparms()
+
+ def hide(self):
+ if self.w:
+ self.w.wid.HideWindow()
+ self.visible = 0
+
+ def writeprefs(self):
+ import MacPrefs
+ self.getparmsfromwindow()
+ prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
+ prefs.searchengine.casesens = self.parms["casesens"]
+ prefs.searchengine.wrap = self.parms["wrap"]
+ prefs.searchengine.wholeword = self.parms["wholeword"]
+ prefs.save()
+
+
+class TitledEditText(W.Group):
+
+ def __init__(self, possize, title, text = ""):
+ W.Group.__init__(self, possize)
+ self.title = W.TextBox((0, 0, 0, 16), title)
+ self.edit = W.EditText((0, 16, 0, 0), text)
+
+ def set(self, value):
+ self.edit.set(value)
+
+ def get(self):
+ return self.edit.get()
+
+
+class ClassFinder(W.PopupWidget):
+
+ def click(self, point, modifiers):
+ W.SetCursor("watch")
+ self.set(self._parentwindow.getclasslist())
+ W.PopupWidget.click(self, point, modifiers)
+
+
+def getminindent(lines):
+ indent = -1
+ for line in lines:
+ stripped = string.strip(line)
+ if not stripped or stripped[0] == '#':
+ continue
+ if indent < 0 or line[:indent] <> indent * '\t':
+ indent = 0
+ for c in line:
+ if c <> '\t':
+ break
+ indent = indent + 1
+ return indent
+
+
+def getoptionkey():
+ return not not ord(Evt.GetKeys()[7]) & 0x04
+
+
+def execstring(pytext, globals, locals, filename="<string>", debugging=0,
+ modname="__main__", profiling=0):
+ if debugging:
+ import PyDebugger, bdb
+ BdbQuit = bdb.BdbQuit
+ else:
+ BdbQuit = 'BdbQuitDummyException'
+ pytext = string.split(pytext, '\r')
+ pytext = string.join(pytext, '\n') + '\n'
+ W.SetCursor("watch")
+ globals['__name__'] = modname
+ globals['__file__'] = filename
+ sys.argv = [filename]
+ try:
+ code = compile(pytext, filename, "exec")
+ except:
+ # XXXX BAAAADDD.... We let tracebackwindow decide to treat SyntaxError
+ # special. That's wrong because THIS case is special (could be literal
+ # overflow!) and SyntaxError could mean we need a traceback (syntax error
+ # in imported module!!!
+ tracebackwindow.traceback(1, filename)
+ return
+ try:
+ if debugging:
+ if haveThreading:
+ lock = Wthreading.Lock()
+ lock.acquire()
+ PyDebugger.startfromhere()
+ lock.release()
+ else:
+ PyDebugger.startfromhere()
+ elif not haveThreading:
+ MacOS.EnableAppswitch(0)
+ try:
+ if profiling:
+ import profile, ProfileBrowser
+ p = profile.Profile()
+ p.set_cmd(filename)
+ try:
+ p.runctx(code, globals, locals)
+ finally:
+ import pstats
+
+ stats = pstats.Stats(p)
+ ProfileBrowser.ProfileBrowser(stats)
+ else:
+ exec code in globals, locals
+ finally:
+ if not haveThreading:
+ MacOS.EnableAppswitch(-1)
+ except W.AlertError, detail:
+ raise W.AlertError, detail
+ except (KeyboardInterrupt, BdbQuit):
+ pass
+ except:
+ if haveThreading:
+ import continuation
+ lock = Wthreading.Lock()
+ lock.acquire()
+ if debugging:
+ sys.settrace(None)
+ PyDebugger.postmortem(sys.exc_type, sys.exc_value, sys.exc_traceback)
+ return
+ else:
+ tracebackwindow.traceback(1, filename)
+ if haveThreading:
+ lock.release()
+ if debugging:
+ sys.settrace(None)
+ PyDebugger.stop()
+
+
+_identifieRE = re.compile(r"[A-Za-z_][A-Za-z_0-9]*")
+
+def identifieRE_match(str):
+ match = _identifieRE.match(str)
+ if not match:
+ return -1
+ return match.end()
+
+def _filename_as_modname(fname):
+ if fname[-3:] == '.py':
+ modname = fname[:-3]
+ match = _identifieRE.match(modname)
+ if match and match.start() == 0 and match.end() == len(modname):
+ return string.join(string.split(modname, '.'), '_')
+
+def findeditor(topwindow, fromtop = 0):
+ wid = Win.FrontWindow()
+ if not fromtop:
+ if topwindow.w and wid == topwindow.w.wid:
+ wid = topwindow.w.wid.GetNextWindow()
+ if not wid:
+ return
+ app = W.getapplication()
+ if app._windows.has_key(wid): # KeyError otherwise can happen in RoboFog :-(
+ window = W.getapplication()._windows[wid]
+ else:
+ return
+ if not isinstance(window, Editor):
+ return
+ return window.editgroup.editor
+
+
+class _EditorDefaultSettings:
+
+ def __init__(self):
+ self.template = "%s, %d point"
+ self.fontsettings, self.tabsettings, self.windowsize = geteditorprefs()
+ self.w = W.Dialog((328, 120), "Editor default settings")
+ self.w.setfontbutton = W.Button((8, 8, 80, 16), "Set font\xc9", self.dofont)
+ self.w.fonttext = W.TextBox((98, 10, -8, 14), self.template % (self.fontsettings[0], self.fontsettings[2]))
+
+ self.w.picksizebutton = W.Button((8, 50, 80, 16), "Front window", self.picksize)
+ self.w.xsizelabel = W.TextBox((98, 32, 40, 14), "Width:")
+ self.w.ysizelabel = W.TextBox((148, 32, 40, 14), "Height:")
+ self.w.xsize = W.EditText((98, 48, 40, 20), `self.windowsize[0]`)
+ self.w.ysize = W.EditText((148, 48, 40, 20), `self.windowsize[1]`)
+
+ self.w.cancelbutton = W.Button((-180, -26, 80, 16), "Cancel", self.cancel)
+ self.w.okbutton = W.Button((-90, -26, 80, 16), "Done", self.ok)
+ self.w.setdefaultbutton(self.w.okbutton)
+ self.w.bind('cmd.', self.w.cancelbutton.push)
+ self.w.open()
+
+ def picksize(self):
+ app = W.getapplication()
+ editor = findeditor(self)
+ if editor is not None:
+ width, height = editor._parentwindow._bounds[2:]
+ self.w.xsize.set(`width`)
+ self.w.ysize.set(`height`)
+ else:
+ raise W.AlertError, "No edit window found"
+
+ def dofont(self):
+ import FontSettings
+ settings = FontSettings.FontDialog(self.fontsettings, self.tabsettings)
+ if settings:
+ self.fontsettings, self.tabsettings = settings
+ sys.exc_traceback = None
+ self.w.fonttext.set(self.template % (self.fontsettings[0], self.fontsettings[2]))
+
+ def close(self):
+ self.w.close()
+ del self.w
+
+ def cancel(self):
+ self.close()
+
+ def ok(self):
+ try:
+ width = string.atoi(self.w.xsize.get())
+ except:
+ self.w.xsize.select(1)
+ self.w.xsize.selectall()
+ raise W.AlertError, "Bad number for window width"
+ try:
+ height = string.atoi(self.w.ysize.get())
+ except:
+ self.w.ysize.select(1)
+ self.w.ysize.selectall()
+ raise W.AlertError, "Bad number for window height"
+ self.windowsize = width, height
+ seteditorprefs(self.fontsettings, self.tabsettings, self.windowsize)
+ self.close()
+
+def geteditorprefs():
+ import MacPrefs
+ prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
+ try:
+ fontsettings = prefs.pyedit.fontsettings
+ tabsettings = prefs.pyedit.tabsettings
+ windowsize = prefs.pyedit.windowsize
+ except:
+ fontsettings = prefs.pyedit.fontsettings = ("Python-Sans", 0, 9, (0, 0, 0))
+ tabsettings = prefs.pyedit.tabsettings = (8, 1)
+ windowsize = prefs.pyedit.windowsize = (500, 250)
+ sys.exc_traceback = None
+ return fontsettings, tabsettings, windowsize
+
+def seteditorprefs(fontsettings, tabsettings, windowsize):
+ import MacPrefs
+ prefs = MacPrefs.GetPrefs(W.getapplication().preffilepath)
+ prefs.pyedit.fontsettings = fontsettings
+ prefs.pyedit.tabsettings = tabsettings
+ prefs.pyedit.windowsize = windowsize
+ prefs.save()
+
+_defaultSettingsEditor = None
+
+def EditorDefaultSettings():
+ global _defaultSettingsEditor
+ if _defaultSettingsEditor is None or not hasattr(_defaultSettingsEditor, "w"):
+ _defaultSettingsEditor = _EditorDefaultSettings()
+ else:
+ _defaultSettingsEditor.w.select()
+
+def resolvealiases(path):
+ try:
+ return macfs.ResolveAliasFile(path)[0].as_pathname()
+ except (macfs.error, ValueError), (error, str):
+ if error <> -120:
+ raise
+ dir, file = os.path.split(path)
+ return os.path.join(resolvealiases(dir), file)
+
+searchengine = SearchEngine()
+tracebackwindow = Wtraceback.TraceBack()
--- /dev/null
+"""Module to analyze Python source code; for syntax coloring tools.
+
+Interface:
+ tags = fontify(pytext, searchfrom, searchto)
+
+The 'pytext' argument is a string containing Python source code.
+The (optional) arguments 'searchfrom' and 'searchto' may contain a slice in pytext.
+The returned value is a list of tuples, formatted like this:
+ [('keyword', 0, 6, None), ('keyword', 11, 17, None), ('comment', 23, 53, None), etc. ]
+The tuple contents are always like this:
+ (tag, startindex, endindex, sublist)
+tag is one of 'keyword', 'string', 'comment' or 'identifier'
+sublist is not used, hence always None.
+"""
+
+# Based on FontText.py by Mitchell S. Chapman,
+# which was modified by Zachary Roadhouse,
+# then un-Tk'd by Just van Rossum.
+# Many thanks for regular expression debugging & authoring are due to:
+# Tim (the-incredib-ly y'rs) Peters and Cristian Tismer
+# So, who owns the copyright? ;-) How about this:
+# Copyright 1996-2001:
+# Mitchell S. Chapman,
+# Zachary Roadhouse,
+# Tim Peters,
+# Just van Rossum
+
+__version__ = "0.4"
+
+import string
+import re
+
+# First a little helper, since I don't like to repeat things. (Tismer speaking)
+import string
+def replace(where, what, with):
+ return string.join(string.split(where, what), with)
+
+# This list of keywords is taken from ref/node13.html of the
+# Python 1.3 HTML documentation. ("access" is intentionally omitted.)
+keywordsList = [
+ "assert", "exec",
+ "del", "from", "lambda", "return",
+ "and", "elif", "global", "not", "try",
+ "break", "else", "if", "or", "while",
+ "class", "except", "import", "pass",
+ "continue", "finally", "in", "print",
+ "def", "for", "is", "raise", "yield"]
+
+# Build up a regular expression which will match anything
+# interesting, including multi-line triple-quoted strings.
+commentPat = r"#[^\n]*"
+
+pat = r"q[^\\q\n]*(\\[\000-\377][^\\q\n]*)*q"
+quotePat = replace(pat, "q", "'") + "|" + replace(pat, 'q', '"')
+
+# Way to go, Tim!
+pat = r"""
+ qqq
+ [^\\q]*
+ (
+ ( \\[\000-\377]
+ | q
+ ( \\[\000-\377]
+ | [^\q]
+ | q
+ ( \\[\000-\377]
+ | [^\\q]
+ )
+ )
+ )
+ [^\\q]*
+ )*
+ qqq
+"""
+pat = string.join(string.split(pat), '') # get rid of whitespace
+tripleQuotePat = replace(pat, "q", "'") + "|" + replace(pat, 'q', '"')
+
+# Build up a regular expression which matches all and only
+# Python keywords. This will let us skip the uninteresting
+# identifier references.
+# nonKeyPat identifies characters which may legally precede
+# a keyword pattern.
+nonKeyPat = r"(^|[^a-zA-Z0-9_.\"'])"
+
+keyPat = nonKeyPat + "(" + "|".join(keywordsList) + ")" + nonKeyPat
+
+matchPat = commentPat + "|" + keyPat + "|" + tripleQuotePat + "|" + quotePat
+matchRE = re.compile(matchPat)
+
+idKeyPat = "[ \t]*[A-Za-z_][A-Za-z_0-9.]*" # Ident w. leading whitespace.
+idRE = re.compile(idKeyPat)
+
+
+def fontify(pytext, searchfrom = 0, searchto = None):
+ if searchto is None:
+ searchto = len(pytext)
+ # Cache a few attributes for quicker reference.
+ search = matchRE.search
+ idSearch = idRE.search
+
+ tags = []
+ tags_append = tags.append
+ commentTag = 'comment'
+ stringTag = 'string'
+ keywordTag = 'keyword'
+ identifierTag = 'identifier'
+
+ start = 0
+ end = searchfrom
+ while 1:
+ m = search(pytext, end)
+ if m is None:
+ break # EXIT LOOP
+ start = m.start()
+ if start >= searchto:
+ break # EXIT LOOP
+ match = m.group(0)
+ end = start + len(match)
+ c = match[0]
+ if c not in "#'\"":
+ # Must have matched a keyword.
+ if start <> searchfrom:
+ # there's still a redundant char before and after it, strip!
+ match = match[1:-1]
+ start = start + 1
+ else:
+ # this is the first keyword in the text.
+ # Only a space at the end.
+ match = match[:-1]
+ end = end - 1
+ tags_append((keywordTag, start, end, None))
+ # If this was a defining keyword, look ahead to the
+ # following identifier.
+ if match in ["def", "class"]:
+ m = idSearch(pytext, end)
+ if m is not None:
+ start = m.start()
+ if start == end:
+ match = m.group(0)
+ end = start + len(match)
+ tags_append((identifierTag, start, end, None))
+ elif c == "#":
+ tags_append((commentTag, start, end, None))
+ else:
+ tags_append((stringTag, start, end, None))
+ return tags
+
+
+def test(path):
+ f = open(path)
+ text = f.read()
+ f.close()
+ tags = fontify(text)
+ for tag, start, end, sublist in tags:
+ print tag, `text[start:end]`
--- /dev/null
+import Ctl
+import Controls
+import Win
+import Wbase
+import Qd
+import Evt
+
+class ControlWidget(Wbase.ClickableWidget):
+
+ """Baseclass for all native controls."""
+
+ def __init__(self, possize, title = "Control", procID = 0, callback = None, value = 0, min = 0, max = 1):
+ Wbase.ClickableWidget.__init__(self, possize)
+ self._control = None
+ self._title = title
+ self._callback = callback
+ self._procID = procID
+ self._value = value
+ self._min = min
+ self._max = max
+ self._enabled = 1
+
+ def open(self):
+ self._calcbounds()
+ self._control = Ctl.NewControl(self._parentwindow.wid,
+ self._bounds,
+ self._title,
+ 1,
+ self._value,
+ self._min,
+ self._max,
+ self._procID,
+ 0)
+ self.SetPort()
+ #self.GetWindow().ValidWindowRect(self._bounds)
+ self.enable(self._enabled)
+
+ def adjust(self, oldbounds):
+ self.SetPort()
+ self._control.HideControl()
+ self._control.MoveControl(self._bounds[0], self._bounds[1])
+ self._control.SizeControl(self._bounds[2] - self._bounds[0], self._bounds[3] - self._bounds[1])
+ if self._visible:
+ Qd.EraseRect(self._bounds)
+ self._control.ShowControl()
+ self.GetWindow().ValidWindowRect(self._bounds)
+
+ def close(self):
+ self._control.HideControl()
+ self._control = None
+ Wbase.ClickableWidget.close(self)
+
+ def enable(self, onoff):
+ if self._control and self._enabled <> onoff:
+ self._control.HiliteControl((not onoff) and 255)
+ self._enabled = onoff
+
+ def show(self, onoff):
+ self._visible = onoff
+ for w in self._widgets:
+ w.show(onoff)
+ if onoff:
+ self._control.ShowControl()
+ else:
+ self._control.HideControl()
+
+ def activate(self, onoff):
+ self._activated = onoff
+ if self._enabled:
+ self._control.HiliteControl((not onoff) and 255)
+
+ def draw(self, visRgn = None):
+ if self._visible:
+ self._control.Draw1Control()
+
+ def test(self, point):
+ ctltype, control = Ctl.FindControl(point, self._parentwindow.wid)
+ if self._enabled and control == self._control:
+ return 1
+
+ def click(self, point, modifiers):
+ if not self._enabled:
+ return
+ part = self._control.TrackControl(point)
+ if part:
+ if self._callback:
+ Wbase.CallbackCall(self._callback, 0)
+
+ def settitle(self, title):
+ if self._control:
+ self._control.SetControlTitle(title)
+ self._title = title
+
+ def gettitle(self):
+ return self._title
+
+class Button(ControlWidget):
+
+ """Standard push button."""
+
+ def __init__(self, possize, title = "Button", callback = None):
+ procID = Controls.pushButProc | Controls.useWFont
+ ControlWidget.__init__(self, possize, title, procID, callback, 0, 0, 1)
+ self._isdefault = 0
+
+ def push(self):
+ if not self._enabled:
+ return
+ import time
+ self._control.HiliteControl(1)
+ time.sleep(0.1)
+ self._control.HiliteControl(0)
+ if self._callback:
+ Wbase.CallbackCall(self._callback, 0)
+
+ def enable(self, onoff):
+ if self._control and self._enabled <> onoff:
+ self._control.HiliteControl((not onoff) and 255)
+ self._enabled = onoff
+ if self._isdefault and self._visible:
+ self.SetPort()
+ self.drawfatframe(onoff)
+
+ def activate(self, onoff):
+ self._activated = onoff
+ if self._enabled:
+ self._control.HiliteControl((not onoff) and 255)
+ if self._isdefault and self._visible:
+ self.SetPort()
+ self.drawfatframe(onoff)
+
+ def show(self, onoff):
+ ControlWidget.show(self, onoff)
+ if self._isdefault:
+ self.drawfatframe(onoff and self._enabled)
+
+ def draw(self, visRgn = None):
+ if self._visible:
+ self._control.Draw1Control()
+ if self._isdefault and self._activated:
+ self.drawfatframe(self._enabled)
+
+ def drawfatframe(self, onoff):
+ state = Qd.GetPenState()
+ if onoff:
+ Qd.PenPat(Qd.qd.black)
+ else:
+ Qd.PenPat(Qd.qd.white)
+ fatrect = Qd.InsetRect(self._bounds, -4, -4)
+ Qd.PenSize(3, 3)
+ Qd.FrameRoundRect(fatrect, 16, 16)
+ Qd.SetPenState(state)
+
+ def _setdefault(self, onoff):
+ self._isdefault = onoff
+ if self._control and self._enabled:
+ self.SetPort()
+ self.drawfatframe(onoff)
+
+ def adjust(self, oldbounds):
+ if self._isdefault:
+ old = Qd.InsetRect(oldbounds, -4, -4)
+ new = Qd.InsetRect(self._bounds, -4, -4)
+ Qd.EraseRect(old)
+ self.GetWindow().InvalWindowRect(old)
+ self.GetWindow().InvalWindowRect(new)
+ ControlWidget.adjust(self, oldbounds)
+
+
+class CheckBox(ControlWidget):
+
+ """Standard checkbox."""
+
+ def __init__(self, possize, title = "Checkbox", callback = None, value = 0):
+ procID = Controls.checkBoxProc | Controls.useWFont
+ ControlWidget.__init__(self, possize, title, procID, callback, value, 0, 1)
+
+ def click(self, point, modifiers):
+ if not self._enabled:
+ return
+ part = self._control.TrackControl(point)
+ if part:
+ self.toggle()
+ if self._callback:
+ Wbase.CallbackCall(self._callback, 0, self.get())
+
+ def push(self):
+ if not self._enabled:
+ return
+ self.toggle()
+ if self._callback:
+ Wbase.CallbackCall(self._callback, 0, self.get())
+
+ def toggle(self):
+ self.set(not self.get())
+
+ def set(self, value):
+ if self._control:
+ self._control.SetControlValue(value)
+ else:
+ self._value = value
+
+ def get(self):
+ if self._control:
+ return self._control.GetControlValue()
+ else:
+ return self._value
+
+
+class RadioButton(ControlWidget):
+
+ """Standard radiobutton."""
+
+ # XXX We need a radiogroup widget; this is too kludgy.
+
+ def __init__(self, possize, title, thebuttons, callback = None, value = 0):
+ procID = Controls.radioButProc | Controls.useWFont
+ ControlWidget.__init__(self, possize, title, procID, callback, value, 0, 1)
+ self.thebuttons = thebuttons
+ thebuttons.append(self)
+
+ def close(self):
+ self.thebuttons = None
+ ControlWidget.close(self)
+
+ def click(self, point, modifiers):
+ if not self._enabled:
+ return
+ part = self._control.TrackControl(point)
+ if part:
+ self.set(1)
+ if self._callback:
+ Wbase.CallbackCall(self._callback, 0, 1)
+
+ def push(self):
+ if not self._enabled:
+ return
+ self.set(1)
+ if self._callback:
+ Wbase.CallbackCall(self._callback, 0, 1)
+
+ def set(self, value):
+ for button in self.thebuttons:
+ if button._control:
+ button._control.SetControlValue(button == self)
+ else:
+ button._value = (button == self)
+
+ def get(self):
+ if self._control:
+ return self._control.GetControlValue()
+ else:
+ return self._value
+
+
+class Scrollbar(ControlWidget):
+
+ """Standard scrollbar."""
+
+ def __init__(self, possize, callback = None, value = 0, min = 0, max = 0):
+ procID = Controls.scrollBarProc
+ ControlWidget.__init__(self, possize, "", procID, callback, value, min, max)
+
+ # interface
+ def set(self, value):
+ if self._callback:
+ Wbase.CallbackCall(self._callback, 1, value)
+
+ def up(self):
+ if self._callback:
+ Wbase.CallbackCall(self._callback, 1, '+')
+
+ def down(self):
+ if self._callback:
+ Wbase.CallbackCall(self._callback, 1, '-')
+
+ def pageup(self):
+ if self._callback:
+ Wbase.CallbackCall(self._callback, 1, '++')
+
+ def pagedown(self):
+ if self._callback:
+ Wbase.CallbackCall(self._callback, 1, '--')
+
+ def setmin(self, min):
+ self._control.SetControlMinimum(min)
+
+ def setmax(self, min):
+ self._control.SetControlMinimum(max)
+
+ def getmin(self):
+ return self._control.GetControlMinimum()
+
+ def getmax(self):
+ return self._control.GetControlMinimum()
+
+ # internals
+ def click(self, point, modifiers):
+ if not self._enabled:
+ return
+ # custom TrackControl. A mousedown in a scrollbar arrow or page area should
+ # generate _control hits as long as the mouse is a) down, b) still in the same part
+ part = self._control.TestControl(point)
+ if Controls.inUpButton <= part <= Controls.inPageDown:
+ self._control.HiliteControl(part)
+ self._hit(part)
+ oldpart = part
+ # slight delay before scrolling at top speed...
+ now = Evt.TickCount()
+ while Evt.StillDown():
+ if (Evt.TickCount() - now) > 18: # 0.3 seconds
+ break
+ while Evt.StillDown():
+ part = self._control.TestControl(point)
+ if part == oldpart:
+ self._control.HiliteControl(part)
+ self._hit(part)
+ else:
+ self._control.HiliteControl(0)
+ self.SetPort()
+ point = Evt.GetMouse()
+ self._control.HiliteControl(0)
+ elif part == Controls.inThumb:
+ part = self._control.TrackControl(point)
+ if part:
+ self._hit(part)
+
+ def _hit(self, part):
+ if part == Controls.inThumb:
+ value = self._control.GetControlValue()
+ elif part == Controls.inUpButton:
+ value = "+"
+ elif part == Controls.inDownButton:
+ value = "-"
+ elif part == Controls.inPageUp:
+ value = "++"
+ elif part == Controls.inPageDown:
+ value = "--"
+ if self._callback:
+ Wbase.CallbackCall(self._callback, 1, value)
+
+ def draw(self, visRgn = None):
+ if self._visible:
+ self._control.Draw1Control()
+ Qd.FrameRect(self._bounds)
+
+ def adjust(self, oldbounds):
+ self.SetPort()
+ self.GetWindow().InvalWindowRect(oldbounds)
+ self._control.HideControl()
+ self._control.MoveControl(self._bounds[0], self._bounds[1])
+ self._control.SizeControl(self._bounds[2] - self._bounds[0], self._bounds[3] - self._bounds[1])
+ if self._visible:
+ Qd.EraseRect(self._bounds)
+ if self._activated:
+ self._control.ShowControl()
+ else:
+ Qd.FrameRect(self._bounds)
+ self.GetWindow().ValidWindowRect(self._bounds)
+
+ def activate(self, onoff):
+ self._activated = onoff
+ if self._visible:
+ if onoff:
+ self._control.ShowControl()
+ else:
+ self._control.HideControl()
+ self.draw(None)
+ self.GetWindow().ValidWindowRect(self._bounds)
+
+ def set(self, value):
+ if self._control:
+ self._control.SetControlValue(value)
+ else:
+ self._value = value
+
+ def get(self):
+ if self._control:
+ return self._control.GetControlValue()
+ else:
+ return self._value
+
+
+def _scalebarvalue(absmin, absmax, curmin, curmax):
+ if curmin <= absmin and curmax >= absmax:
+ return None
+ if curmin <= absmin:
+ return 0
+ if curmax >= absmax:
+ return 32767
+ perc = float(curmin-absmin) / float((absmax - absmin) - (curmax - curmin))
+ return int(perc*32767)
+
--- /dev/null
+import traceback
+import sys
+import W
+import os
+import types
+import List
+
+
+class TraceBack:
+
+ def __init__(self, title = "Traceback"):
+ app = W.getapplication() # checks if W is properly initialized
+ self.title = title
+ self.w = None
+ self.closed = 1
+ self.start = 0
+ self.lastwindowtitle = ""
+ self.bounds = (360, 298)
+
+ def traceback(self, start = 0, lastwindowtitle = ""):
+ try:
+ self.lastwindowtitle = lastwindowtitle
+ self.start = start
+ self.type, self.value, self.tb = sys.exc_info()
+ if self.type is not SyntaxError:
+ self.show()
+ if type(self.type) == types.ClassType:
+ errortext = self.type.__name__
+ else:
+ errortext = str(self.type)
+ value = str(self.value)
+ if self.value and value:
+ errortext = errortext + ": " + value
+ self.w.text.set(errortext)
+ self.buildtblist()
+ self.w.list.set(self.textlist)
+ self.w.list.setselection([len(self.textlist) - 1])
+ self.w.wid.SelectWindow()
+ self.closed = 0
+ else:
+ self.syntaxerror()
+ except:
+ traceback.print_exc()
+
+ def syntaxerror(self):
+ try:
+ value, (filename, lineno, charno, line) = self.value
+ except:
+ filename = ""
+ lineno = None
+ value = self.value
+ if not filename and self.lastwindowtitle:
+ filename = self.lastwindowtitle
+ elif not filename:
+ filename = "<unknown>"
+ if filename and os.path.exists(filename):
+ filename = os.path.split(filename)[1]
+ if lineno and charno is not None:
+ charno = charno - 1
+ text = str(value) + '\rFile: "' + str(filename) + '", line ' + str(lineno) + '\r\r' + line[:charno] + "\xa5" + line[charno:-1]
+ else:
+ text = str(value) + '\rFile: "' + str(filename) + '"'
+ self.syntaxdialog = W.ModalDialog((360, 120), "Syntax Error")
+ self.syntaxdialog.text = W.TextBox((10, 10, -10, -40), text)
+ self.syntaxdialog.cancel = W.Button((-190, -32, 80, 16), "Cancel", self.syntaxclose)
+ self.syntaxdialog.edit = W.Button((-100, -32, 80, 16), "Edit", self.syntaxedit)
+ self.syntaxdialog.setdefaultbutton(self.syntaxdialog.edit)
+ self.syntaxdialog.bind("cmd.", self.syntaxdialog.cancel.push)
+ self.syntaxdialog.open()
+
+ def syntaxclose(self):
+ self.syntaxdialog.close()
+ del self.syntaxdialog
+
+ def syntaxedit(self):
+ try:
+ value, (filename, lineno, charno, line) = self.value
+ except:
+ filename = ""
+ lineno = None
+ if not filename and self.lastwindowtitle:
+ filename = self.lastwindowtitle
+ elif not filename:
+ filename = "<unknown>"
+ self.syntaxclose()
+ if lineno:
+ if charno is None:
+ charno = 1
+ W.getapplication().openscript(filename, lineno, charno - 1)
+ else:
+ W.getapplication().openscript(filename)
+
+ def show(self):
+ if self.closed:
+ self.setupwidgets()
+ self.w.open()
+ else:
+ self.w.wid.ShowWindow()
+ self.w.wid.SelectWindow()
+
+ def hide(self):
+ if self.closed:
+ return
+ self.w.close()
+
+ def close(self):
+ self.bounds = self.w.getbounds()
+ self.closed = 1
+ self.type, self.value, self.tb = None, None, None
+ self.tblist = None
+
+ def activate(self, onoff):
+ if onoff:
+ if self.closed:
+ self.traceback()
+ self.closed = 0
+ self.checkbuttons()
+
+ def setupwidgets(self):
+ self.w = W.Window(self.bounds, self.title, minsize = (316, 168))
+ self.w.text = W.TextBox((10, 10, -10, 30))
+ self.w.tbtitle = W.TextBox((10, 40, -10, 10), "Traceback (innermost last):")
+ self.w.list = W.TwoLineList((10, 60, -10, -40), callback = self.listhit)
+
+ self.w.editbutton = W.Button((10, -30, 60, 16), "Edit", self.edit)
+ self.w.editbutton.enable(0)
+
+ self.w.browselocalsbutton = W.Button((80, -30, 100, 16), "Browse locals\xc9", self.browselocals)
+ self.w.browselocalsbutton.enable(0)
+
+ self.w.postmortembutton = W.Button((190, -30, 100, 16), "Post mortem\xc9", self.postmortem)
+
+ self.w.setdefaultbutton(self.w.editbutton)
+ self.w.bind("cmdb", self.w.browselocalsbutton.push)
+ self.w.bind("<close>", self.close)
+ self.w.bind("<activate>", self.activate)
+
+ def buildtblist(self):
+ tb = self.tb
+ for i in range(self.start):
+ if tb.tb_next is None:
+ break
+ tb = tb.tb_next
+ self.tblist = traceback.extract_tb(tb)
+ self.textlist = []
+ for filename, lineno, func, line in self.tblist:
+ tbline = ""
+ if os.path.exists(filename):
+ filename = os.path.split(filename)[1]
+ tbline = 'File "' + filename + '", line ' + `lineno` + ', in ' + func
+ else:
+ tbline = 'File "' + filename + '", line ' + `lineno` + ', in ' + func
+ if line:
+ tbline = tbline + '\r ' + line
+ self.textlist.append(tbline[:255])
+
+ def edit(self):
+ sel = self.w.list.getselection()
+ for i in sel:
+ filename, lineno, func, line = self.tblist[i]
+ W.getapplication().openscript(filename, lineno)
+
+ def browselocals(self):
+ sel = self.w.list.getselection()
+ for i in sel:
+ tb = self.tb
+ for j in range(i + self.start):
+ tb = tb.tb_next
+ self.browse(tb.tb_frame.f_locals)
+
+ def browse(self, object):
+ import PyBrowser
+ PyBrowser.Browser(object)
+
+ def postmortem(self):
+ import PyDebugger
+ PyDebugger.postmortem(self.type, self.value, self.tb)
+
+ def listhit(self, isdbl):
+ if isdbl:
+ self.w.editbutton.push()
+ else:
+ self.checkbuttons()
+
+ def checkbuttons(self):
+ havefile = len(self.w.list.getselection()) > 0
+ self.w.editbutton.enable(havefile)
+ self.w.browselocalsbutton.enable(havefile)
+ self.w.setdefaultbutton(havefile and self.w.editbutton or self.w.postmortembutton)
+