Drop Mac wrappers for the WASTE library.

This commit is contained in:
Ronald Oussoren 2006-06-04 14:24:59 +00:00
parent f70b14fb30
commit fb2a169ce3
13 changed files with 1 additions and 5608 deletions

View File

@ -95,14 +95,3 @@ audio tracks.
The \module{W} widgets are used extensively in the \program{IDE}. The \module{W} widgets are used extensively in the \program{IDE}.
\section{\module{waste} --- non-Apple \program{TextEdit} replacement}
\declaremodule{standard}{waste}
\platform{Mac}
\modulesynopsis{Interface to the ``WorldScript-Aware Styled Text Engine.''}
\begin{seealso}
\seetitle[http://www.merzwaren.com/waste/]{About WASTE}{Information
about the WASTE widget and library, including
documentation and downloads.}
\end{seealso}

View File

@ -1,207 +0,0 @@
# Generated from 'WASTE.h'
kPascalStackBased = None # workaround for header parsing
def FOUR_CHAR_CODE(x): return x
weCantUndoErr = -10015
weEmptySelectionErr = -10013
weUnknownObjectTypeErr = -9478
weObjectNotFoundErr = -9477
weReadOnlyErr = -9476
weTextNotFoundErr = -9474
weInvalidTextEncodingErr = -9473
weDuplicateAttributeErr = -9472
weInvalidAttributeSizeErr = -9471
weReadOnlyAttributeErr = -9470
weOddByteCountErr = -9469
weHandlerNotFoundErr = -1717
weNotHandledErr = -1708
weNewerVersionErr = -1706
weCorruptDataErr = -1702
weProtocolErr = -603
weUndefinedSelectorErr = -50
weFlushLeft = -2
weFlushRight = -1
weFlushDefault = 0
weCenter = 1
weJustify = 2
weDirDefault = 1
weDirRightToLeft = -1
weDirLeftToRight = 0
weDoFont = 0x0001
weDoFace = 0x0002
weDoSize = 0x0004
weDoColor = 0x0008
weDoAll = weDoFont | weDoFace | weDoSize | weDoColor
weDoAddSize = 0x0010
weDoToggleFace = 0x0020
weDoReplaceFace = 0x0040
weDoPreserveScript = 0x0080
weDoExtractSubscript = 0x0100
weDoFaceMask = 0x0200
weDoDirection = 0x00000001
weDoAlignment = 0x00000002
weDoLeftIndent = 0x00000004
weDoRightIndent = 0x00000008
weDoFirstLineIndent = 0x00000010
weDoLineSpacing = 0x00000020
weDoSpaceBefore = 0x00000040
weDoSpaceAfter = 0x00000080
weDoBottomBorderStyle = 0x00000400
kLeadingEdge = -1
kTrailingEdge = 0
kObjectEdge = 2
weFAutoScroll = 0
weFOutlineHilite = 2
weFReadOnly = 5
weFUndo = 6
weFIntCutAndPaste = 7
weFDragAndDrop = 8
weFInhibitRecal = 9
weFUseTempMem = 10
weFDrawOffscreen = 11
weFInhibitRedraw = 12
weFMonoStyled = 13
weFMultipleUndo = 14
weFNoKeyboardSync = 29
weFInhibitICSupport = 30
weFInhibitColor = 31
# weDoAutoScroll = 1UL << weFAutoScroll
# weDoOutlineHilite = 1UL << weFOutlineHilite
# weDoReadOnly = 1UL << weFReadOnly
# weDoUndo = 1UL << weFUndo
# weDoIntCutAndPaste = 1UL << weFIntCutAndPaste
# weDoDragAndDrop = 1UL << weFDragAndDrop
# weDoInhibitRecal = 1UL << weFInhibitRecal
# weDoUseTempMem = 1UL << weFUseTempMem
# weDoDrawOffscreen = 1UL << weFDrawOffscreen
# weDoInhibitRedraw = 1UL << weFInhibitRedraw
# weDoMonoStyled = 1UL << weFMonoStyled
# weDoMultipleUndo = 1UL << weFMultipleUndo
# weDoNoKeyboardSync = 1UL << weFNoKeyboardSync
# weDoInhibitICSupport = 1UL << weFInhibitICSupport
# weDoInhibitColor = 1UL << weFInhibitColor
weBitToggle = -2
weBitTest = -1
weBitClear = 0
weBitSet = 1
weLowerCase = 0
weUpperCase = 1
weFindWholeWords = 0x00000001
weFindCaseInsensitive = 0x00000002
weFindDiacriticalInsensitive = 0x00000004
wePutIntCutAndPaste = 0x00000001
wePutAddToTypingSequence = 0x00000002
wePutDetectUnicodeBOM = 0x00000200
weStreamDestinationKindMask = 0x000000FF
weStreamIncludeObjects = 0x00000100
weGetAddUnicodeBOM = 0x00000200
weGetLittleEndian = 0x00000400
weTagFontFamily = FOUR_CHAR_CODE('font')
weTagFontSize = FOUR_CHAR_CODE('ptsz')
weTagPlain = FOUR_CHAR_CODE('plan')
weTagBold = FOUR_CHAR_CODE('bold')
weTagItalic = FOUR_CHAR_CODE('ital')
weTagUnderline = FOUR_CHAR_CODE('undl')
weTagOutline = FOUR_CHAR_CODE('outl')
weTagShadow = FOUR_CHAR_CODE('shad')
weTagCondensed = FOUR_CHAR_CODE('cond')
weTagExtended = FOUR_CHAR_CODE('pexp')
weTagStrikethrough = FOUR_CHAR_CODE('strk')
weTagTextColor = FOUR_CHAR_CODE('colr')
weTagBackgroundColor = FOUR_CHAR_CODE('pbcl')
weTagTransferMode = FOUR_CHAR_CODE('pptm')
weTagVerticalShift = FOUR_CHAR_CODE('xshf')
weTagAlignment = FOUR_CHAR_CODE('pjst')
weTagDirection = FOUR_CHAR_CODE('LDIR')
weTagLineSpacing = FOUR_CHAR_CODE('ledg')
weTagLeftIndent = FOUR_CHAR_CODE('lein')
weTagRightIndent = FOUR_CHAR_CODE('riin')
weTagFirstLineIndent = FOUR_CHAR_CODE('fidt')
weTagSpaceBefore = FOUR_CHAR_CODE('spbe')
weTagSpaceAfter = FOUR_CHAR_CODE('spaf')
weTagBottomBorderStyle = FOUR_CHAR_CODE('BBRD')
weTagForceFontFamily = FOUR_CHAR_CODE('ffnt')
weTagAddFontSize = FOUR_CHAR_CODE('+siz')
weTagAddVerticalShift = FOUR_CHAR_CODE('+shf')
weTagTextEncoding = FOUR_CHAR_CODE('ptxe')
weTagQDStyles = FOUR_CHAR_CODE('qdst')
weTagTETextStyle = FOUR_CHAR_CODE('tets')
weTagAlignmentDefault = FOUR_CHAR_CODE('deft')
weTagAlignmentLeft = FOUR_CHAR_CODE('left')
weTagAlignmentCenter = FOUR_CHAR_CODE('cent')
weTagAlignmentRight = FOUR_CHAR_CODE('rght')
weTagAlignmentFull = FOUR_CHAR_CODE('full')
weTagDirectionDefault = FOUR_CHAR_CODE('deft')
weTagDirectionLeftToRight = FOUR_CHAR_CODE('L->R')
weTagDirectionRightToLeft = FOUR_CHAR_CODE('R->L')
weTagBorderStyleNone = FOUR_CHAR_CODE('NONE')
weTagBorderStyleThin = FOUR_CHAR_CODE('SLDL')
weTagBorderStyleDotted = FOUR_CHAR_CODE('DTDL')
weTagBorderStyleThick = FOUR_CHAR_CODE('THKL')
weLineSpacingSingle = 0x00000000
weLineSpacingOneAndHalf = 0x00008000
weLineSpacingDouble = 0x00010000
weCharByteHook = FOUR_CHAR_CODE('cbyt')
weCharToPixelHook = FOUR_CHAR_CODE('c2p ')
weCharTypeHook = FOUR_CHAR_CODE('ctyp')
weClickLoop = FOUR_CHAR_CODE('clik')
weCurrentDrag = FOUR_CHAR_CODE('drag')
weDrawTextHook = FOUR_CHAR_CODE('draw')
weDrawTSMHiliteHook = FOUR_CHAR_CODE('dtsm')
weEraseHook = FOUR_CHAR_CODE('eras')
weFontFamilyToNameHook = FOUR_CHAR_CODE('ff2n')
weFontNameToFamilyHook = FOUR_CHAR_CODE('fn2f')
weFluxProc = FOUR_CHAR_CODE('flux')
weHiliteDropAreaHook = FOUR_CHAR_CODE('hidr')
weLineBreakHook = FOUR_CHAR_CODE('lbrk')
wePixelToCharHook = FOUR_CHAR_CODE('p2c ')
wePort = FOUR_CHAR_CODE('port')
wePreTrackDragHook = FOUR_CHAR_CODE('ptrk')
weRefCon = FOUR_CHAR_CODE('refc')
weScrollProc = FOUR_CHAR_CODE('scrl')
weText = FOUR_CHAR_CODE('text')
weTranslateDragHook = FOUR_CHAR_CODE('xdrg')
weTranslucencyThreshold = FOUR_CHAR_CODE('tluc')
weTSMDocumentID = FOUR_CHAR_CODE('tsmd')
weTSMPreUpdate = FOUR_CHAR_CODE('pre ')
weTSMPostUpdate = FOUR_CHAR_CODE('post')
weURLHint = FOUR_CHAR_CODE('urlh')
weWordBreakHook = FOUR_CHAR_CODE('wbrk')
weNewHandler = FOUR_CHAR_CODE('new ')
weDisposeHandler = FOUR_CHAR_CODE('free')
weDrawHandler = FOUR_CHAR_CODE('draw')
weClickHandler = FOUR_CHAR_CODE('clik')
weStreamHandler = FOUR_CHAR_CODE('strm')
weHoverHandler = FOUR_CHAR_CODE('hovr')
kTypeText = FOUR_CHAR_CODE('TEXT')
kTypeStyles = FOUR_CHAR_CODE('styl')
kTypeSoup = FOUR_CHAR_CODE('SOUP')
kTypeFontTable = FOUR_CHAR_CODE('FISH')
kTypeParaFormat = FOUR_CHAR_CODE('WEpf')
kTypeRulerScrap = FOUR_CHAR_CODE('WEru')
kTypeCharFormat = FOUR_CHAR_CODE('WEcf')
kTypeStyleScrap = FOUR_CHAR_CODE('WEst')
kTypeUnicodeText = FOUR_CHAR_CODE('utxt')
kTypeUTF8Text = FOUR_CHAR_CODE('UTF8')
kTypeStyledText = FOUR_CHAR_CODE('STXT')
weAKNone = 0
weAKUnspecified = 1
weAKTyping = 2
weAKCut = 3
weAKPaste = 4
weAKClear = 5
weAKDrag = 6
weAKSetStyle = 7
weAKSetRuler = 8
weAKBackspace = 9
weAKFwdDelete = 10
weAKCaseChange = 11
weAKObjectChange = 12
weToScrap = 0
weToDrag = 1
weToSoup = 2
weMouseEnter = 0
weMouseWithin = 1
weMouseLeave = 2
kCurrentSelection = -1
kNullStyle = -2

View File

@ -1,207 +0,0 @@
# Generated from 'WASTE.h'
kPascalStackBased = None # workaround for header parsing
def FOUR_CHAR_CODE(x): return x
weCantUndoErr = -10015
weEmptySelectionErr = -10013
weUnknownObjectTypeErr = -9478
weObjectNotFoundErr = -9477
weReadOnlyErr = -9476
weTextNotFoundErr = -9474
weInvalidTextEncodingErr = -9473
weDuplicateAttributeErr = -9472
weInvalidAttributeSizeErr = -9471
weReadOnlyAttributeErr = -9470
weOddByteCountErr = -9469
weHandlerNotFoundErr = -1717
weNotHandledErr = -1708
weNewerVersionErr = -1706
weCorruptDataErr = -1702
weProtocolErr = -603
weUndefinedSelectorErr = -50
weFlushLeft = -2
weFlushRight = -1
weFlushDefault = 0
weCenter = 1
weJustify = 2
weDirDefault = 1
weDirRightToLeft = -1
weDirLeftToRight = 0
weDoFont = 0x0001
weDoFace = 0x0002
weDoSize = 0x0004
weDoColor = 0x0008
weDoAll = weDoFont | weDoFace | weDoSize | weDoColor
weDoAddSize = 0x0010
weDoToggleFace = 0x0020
weDoReplaceFace = 0x0040
weDoPreserveScript = 0x0080
weDoExtractSubscript = 0x0100
weDoFaceMask = 0x0200
weDoDirection = 0x00000001
weDoAlignment = 0x00000002
weDoLeftIndent = 0x00000004
weDoRightIndent = 0x00000008
weDoFirstLineIndent = 0x00000010
weDoLineSpacing = 0x00000020
weDoSpaceBefore = 0x00000040
weDoSpaceAfter = 0x00000080
weDoBottomBorderStyle = 0x00000400
kLeadingEdge = -1
kTrailingEdge = 0
kObjectEdge = 2
weFAutoScroll = 0
weFOutlineHilite = 2
weFReadOnly = 5
weFUndo = 6
weFIntCutAndPaste = 7
weFDragAndDrop = 8
weFInhibitRecal = 9
weFUseTempMem = 10
weFDrawOffscreen = 11
weFInhibitRedraw = 12
weFMonoStyled = 13
weFMultipleUndo = 14
weFNoKeyboardSync = 29
weFInhibitICSupport = 30
weFInhibitColor = 31
weDoAutoScroll = 1 << weFAutoScroll
weDoOutlineHilite = 1 << weFOutlineHilite
weDoReadOnly = 1 << weFReadOnly
weDoUndo = 1 << weFUndo
weDoIntCutAndPaste = 1 << weFIntCutAndPaste
weDoDragAndDrop = 1 << weFDragAndDrop
weDoInhibitRecal = 1 << weFInhibitRecal
weDoUseTempMem = 1 << weFUseTempMem
weDoDrawOffscreen = 1 << weFDrawOffscreen
weDoInhibitRedraw = 1 << weFInhibitRedraw
weDoMonoStyled = 1 << weFMonoStyled
weDoMultipleUndo = 1 << weFMultipleUndo
weDoNoKeyboardSync = 1 << weFNoKeyboardSync
weDoInhibitICSupport = 1 << weFInhibitICSupport
# weDoInhibitColor = 1 << weFInhibitColor
weBitToggle = -2
weBitTest = -1
weBitClear = 0
weBitSet = 1
weLowerCase = 0
weUpperCase = 1
weFindWholeWords = 0x00000001
weFindCaseInsensitive = 0x00000002
weFindDiacriticalInsensitive = 0x00000004
wePutIntCutAndPaste = 0x00000001
wePutAddToTypingSequence = 0x00000002
wePutDetectUnicodeBOM = 0x00000200
weStreamDestinationKindMask = 0x000000FF
weStreamIncludeObjects = 0x00000100
weGetAddUnicodeBOM = 0x00000200
weGetLittleEndian = 0x00000400
weTagFontFamily = FOUR_CHAR_CODE('font')
weTagFontSize = FOUR_CHAR_CODE('ptsz')
weTagPlain = FOUR_CHAR_CODE('plan')
weTagBold = FOUR_CHAR_CODE('bold')
weTagItalic = FOUR_CHAR_CODE('ital')
weTagUnderline = FOUR_CHAR_CODE('undl')
weTagOutline = FOUR_CHAR_CODE('outl')
weTagShadow = FOUR_CHAR_CODE('shad')
weTagCondensed = FOUR_CHAR_CODE('cond')
weTagExtended = FOUR_CHAR_CODE('pexp')
weTagStrikethrough = FOUR_CHAR_CODE('strk')
weTagTextColor = FOUR_CHAR_CODE('colr')
weTagBackgroundColor = FOUR_CHAR_CODE('pbcl')
weTagTransferMode = FOUR_CHAR_CODE('pptm')
weTagVerticalShift = FOUR_CHAR_CODE('xshf')
weTagAlignment = FOUR_CHAR_CODE('pjst')
weTagDirection = FOUR_CHAR_CODE('LDIR')
weTagLineSpacing = FOUR_CHAR_CODE('ledg')
weTagLeftIndent = FOUR_CHAR_CODE('lein')
weTagRightIndent = FOUR_CHAR_CODE('riin')
weTagFirstLineIndent = FOUR_CHAR_CODE('fidt')
weTagSpaceBefore = FOUR_CHAR_CODE('spbe')
weTagSpaceAfter = FOUR_CHAR_CODE('spaf')
weTagBottomBorderStyle = FOUR_CHAR_CODE('BBRD')
weTagForceFontFamily = FOUR_CHAR_CODE('ffnt')
weTagAddFontSize = FOUR_CHAR_CODE('+siz')
weTagAddVerticalShift = FOUR_CHAR_CODE('+shf')
weTagTextEncoding = FOUR_CHAR_CODE('ptxe')
weTagQDStyles = FOUR_CHAR_CODE('qdst')
weTagTETextStyle = FOUR_CHAR_CODE('tets')
weTagAlignmentDefault = FOUR_CHAR_CODE('deft')
weTagAlignmentLeft = FOUR_CHAR_CODE('left')
weTagAlignmentCenter = FOUR_CHAR_CODE('cent')
weTagAlignmentRight = FOUR_CHAR_CODE('rght')
weTagAlignmentFull = FOUR_CHAR_CODE('full')
weTagDirectionDefault = FOUR_CHAR_CODE('deft')
weTagDirectionLeftToRight = FOUR_CHAR_CODE('L->R')
weTagDirectionRightToLeft = FOUR_CHAR_CODE('R->L')
weTagBorderStyleNone = FOUR_CHAR_CODE('NONE')
weTagBorderStyleThin = FOUR_CHAR_CODE('SLDL')
weTagBorderStyleDotted = FOUR_CHAR_CODE('DTDL')
weTagBorderStyleThick = FOUR_CHAR_CODE('THKL')
weLineSpacingSingle = 0x00000000
weLineSpacingOneAndHalf = 0x00008000
weLineSpacingDouble = 0x00010000
weCharByteHook = FOUR_CHAR_CODE('cbyt')
weCharToPixelHook = FOUR_CHAR_CODE('c2p ')
weCharTypeHook = FOUR_CHAR_CODE('ctyp')
weClickLoop = FOUR_CHAR_CODE('clik')
weCurrentDrag = FOUR_CHAR_CODE('drag')
weDrawTextHook = FOUR_CHAR_CODE('draw')
weDrawTSMHiliteHook = FOUR_CHAR_CODE('dtsm')
weEraseHook = FOUR_CHAR_CODE('eras')
weFontFamilyToNameHook = FOUR_CHAR_CODE('ff2n')
weFontNameToFamilyHook = FOUR_CHAR_CODE('fn2f')
weFluxProc = FOUR_CHAR_CODE('flux')
weHiliteDropAreaHook = FOUR_CHAR_CODE('hidr')
weLineBreakHook = FOUR_CHAR_CODE('lbrk')
wePixelToCharHook = FOUR_CHAR_CODE('p2c ')
wePort = FOUR_CHAR_CODE('port')
wePreTrackDragHook = FOUR_CHAR_CODE('ptrk')
weRefCon = FOUR_CHAR_CODE('refc')
weScrollProc = FOUR_CHAR_CODE('scrl')
weText = FOUR_CHAR_CODE('text')
weTranslateDragHook = FOUR_CHAR_CODE('xdrg')
weTranslucencyThreshold = FOUR_CHAR_CODE('tluc')
weTSMDocumentID = FOUR_CHAR_CODE('tsmd')
weTSMPreUpdate = FOUR_CHAR_CODE('pre ')
weTSMPostUpdate = FOUR_CHAR_CODE('post')
weURLHint = FOUR_CHAR_CODE('urlh')
weWordBreakHook = FOUR_CHAR_CODE('wbrk')
weNewHandler = FOUR_CHAR_CODE('new ')
weDisposeHandler = FOUR_CHAR_CODE('free')
weDrawHandler = FOUR_CHAR_CODE('draw')
weClickHandler = FOUR_CHAR_CODE('clik')
weStreamHandler = FOUR_CHAR_CODE('strm')
weHoverHandler = FOUR_CHAR_CODE('hovr')
kTypeText = FOUR_CHAR_CODE('TEXT')
kTypeStyles = FOUR_CHAR_CODE('styl')
kTypeSoup = FOUR_CHAR_CODE('SOUP')
kTypeFontTable = FOUR_CHAR_CODE('FISH')
kTypeParaFormat = FOUR_CHAR_CODE('WEpf')
kTypeRulerScrap = FOUR_CHAR_CODE('WEru')
kTypeCharFormat = FOUR_CHAR_CODE('WEcf')
kTypeStyleScrap = FOUR_CHAR_CODE('WEst')
kTypeUnicodeText = FOUR_CHAR_CODE('utxt')
kTypeUTF8Text = FOUR_CHAR_CODE('UTF8')
kTypeStyledText = FOUR_CHAR_CODE('STXT')
weAKNone = 0
weAKUnspecified = 1
weAKTyping = 2
weAKCut = 3
weAKPaste = 4
weAKClear = 5
weAKDrag = 6
weAKSetStyle = 7
weAKSetRuler = 8
weAKBackspace = 9
weAKFwdDelete = 10
weAKCaseChange = 11
weAKObjectChange = 12
weToScrap = 0
weToDrag = 1
weToSoup = 2
weMouseEnter = 0
weMouseWithin = 1
weMouseLeave = 2
kCurrentSelection = -1
kNullStyle = -2

View File

@ -73,10 +73,6 @@ with MacPython.
how to use <code>FrameWork</code> application framework and the how to use <code>FrameWork</code> application framework and the
<code>TextEdit</code> toolbox to build a text editor. <code>TextEdit</code> toolbox to build a text editor.
<LI>
<A HREF="waste.html">Using WASTE</A> expands on this editor by using
WASTE, an extended TextEdit replacement.
<LI> <LI>
<A HREF="plugins.html">Creating a C extension module on the Macintosh</A> <A HREF="plugins.html">Creating a C extension module on the Macintosh</A>
is meant for the hardcore programmer, and shows how to create an is meant for the hardcore programmer, and shows how to create an

View File

@ -80,8 +80,7 @@ A modeless dialog window initialized from a DLOG resource. See the
Let us have a look at <A HREF="textedit/ped.py">ped.py</A> (in the Demo:textedit folder), the Pathetic Let us have a look at <A HREF="textedit/ped.py">ped.py</A> (in the Demo:textedit folder), the Pathetic
EDitor. It has multiple windows, cut/copy/paste and keyboard input, but that is about all. It looks EDitor. It has multiple windows, cut/copy/paste and keyboard input, but that is about all. It looks
as if you can resize the window but it does not work. Still, it serves as an example. We will improve as if you can resize the window but it does not work. Still, it serves as an example.
on ped later, in a <A HREF="waste.html">waste-based example</A>. <p>
Ped creates two classes, <code>TEWindow</code> and <code>Ped</code>. Let us start with the latter one, Ped creates two classes, <code>TEWindow</code> and <code>Ped</code>. Let us start with the latter one,
which is a subclass of <code>FrameWork.Application</code> and our main application. The init function which is a subclass of <code>FrameWork.Application</code> and our main application. The init function

View File

@ -1,72 +0,0 @@
<HTML><HEAD><TITLE>Using WASTE</TITLE></HEAD>
<BODY>
<H1>Using WASTE</H1>
<HR>
WASTE is an almost-compatible TextEdit replacement which overcomes
some of the limitations of it (like the 32K limit) and provides some extensions
(drag and drop, images, undo support). Moreover, it has a much cleaner interface
and is therefore easier integrated in Python. <p>
WASTE is written by Marco Piovanelli, <A HREF="mailto:piovanel@kagi.com">&lt;piovanel@kagi.com&gt;</A>,
and copyrighted by him. You can always obtain the latest version (for use in C
or Pascal programs) and the documentation from
<A HREF="http://www.boingo.com/waste/">&lt;http://www.boingo.com/waste/&gt;</A>.
We explain the useage of waste here by showing how to modify the TextEdit based
<A HREF="textedit/ped.py">ped.py</A> of the
<A HREF="textedit.html">previous example</A> into the waste-based <A HREF="waste/wed.py">wed.py</A>,
so you should have both sources handy. <p>
Functionally, <code>wed.py</code> provides three new things: resizable windows, a horizontal
scroll bar and undo. <p>
Let us look at the code, first at the application class <code>Wed</code>. The only real change is that
we now handle <code>undo</code>. Aside from enabling it in the creation routine and the addition of
a callback routine there is a bit of new code in <code>updatemenubar</code>: Waste not only handles
the full details of implementing undo, it will also tell us what the next undo operation will undo
(or redo). We use this to our advantage by changing the undo menu label to tell the user. <p>
The <code>WasteWindow</code> has seen a bit more change. Initialization of the waste data structure is
a bit different, in that we can specify some options at creation time. Also, waste has no <code>SetText</code>
method but a <code>UseText</code> which expects a handle as parameter. We have to be <EM>very</EM> careful
that we keep this handle around, because Python will happily free the handle if we have no more references
to it (and I doubt that Waste would like this:-). A final difference in <code>open</code>
is that we use a large number for the destination rectangle width, because we will use a horizontal scroll
bar. <p>
The <code>idle</code> method is a bit more involved, since we also call <code>WEAdjustCursor</code> to
provide the correct cursor based on mouse-position. Users like this. <p>
<code>Getscrollbarvalues</code> is simpler than its' TextEdit counterpart because Waste correctly
updates the destination rectangle when the document changes. Also note that waste uses accessor functions
to get at internal values, as opposed to direct struct access for TextEdit. <p>
<code>Scrollbar_callback</code> on the other hand is more elaborate (but also provides more functionality).
It also handles horizontal scrolls (scrolling one-tenth and half a screenful with the buttons). This
function is also "multi-font-ready" in that scrolling one line will do the expected thing in case of multiple
fonts. We will implement a multi-font editor later. A minor annoyance of Waste is that is does not provide
a pinned scroll, so at the end of our callback routine we have to check that we have not scrolled past the
beginning or end of the document, and adjust when needed. <p>
<code>do_update</code> is also changed, because Waste is completely region-based (as opposed to rect-based).
Hence, we erase regions here and we can also return immedeately if there is nothing to update. <p>
<code>Do_postresize</code> is new: because Waste uses accessor functions we can now modify the viewRect from
Python, which is impossible in the Python TextEdit interface, and hence we can implement resize. The
<code>do_key</code> and <code>do_contentclick</code> methods have also seen minor changes, because the
corresponding waste routines need a bit more information than their TextEdit counterparts. The Cut/copy/paste
code is simplified, because Waste uses the normal desktop scrap. <p>
Implementing undo is a wonder of simplicity: Waste handles all the details for us. Also, the new
<code>can_paste</code> method (which controls greying out of the paste menu entry) is an improvement
over what <code>ped</code> did: in ped it was possible that paste was enabled but that the data on the
scrap was incompatible with TextEdit. No more such problems here. <p>
That is all for now. There is an undocumented extended version of wed, <a href="waste/swed.py">swed.py</a>,
which supports multiple fonts, sizes and faces, and uses Waste's tab-calculation to do tab characters "right".
There is also an even more elaborate example, <a href="waste/htmled.py">htmled.py</a> which extends swed with
the ability to import html files, showing the use of color and how to use embedded object (rulers, in this case).
These two programs have not been documented yet, though, so you will have to look at them without guidance. <p>
<hr>
Back to the <A HREF="index.html">index</A> to pick another example.

View File

@ -1,830 +0,0 @@
# A minimal text editor.
#
# To be done:
# - Functionality: find, etc.
from Carbon.Menu import DrawMenuBar
from FrameWork import *
from Carbon import Win
from Carbon import Qd
from Carbon import Res
from Carbon import Fm
import waste
import WASTEconst
from Carbon import Scrap
import os
import EasyDialogs
import macfs
import string
import htmllib
WATCH = Qd.GetCursor(4).data
LEFTMARGIN=0
UNDOLABELS = [ # Indexed by WEGetUndoInfo() value
None, "", "typing", "Cut", "Paste", "Clear", "Drag", "Style"]
# Style and size menu. Note that style order is important (tied to bit values)
STYLES = [
("Bold", "B"), ("Italic", "I"), ("Underline", "U"), ("Outline", "O"),
("Shadow", ""), ("Condensed", ""), ("Extended", "")
]
SIZES = [ 9, 10, 12, 14, 18, 24]
# Sizes for HTML tag types
HTML_SIZE={
'h1': 18,
'h2': 14
}
BIGREGION=Qd.NewRgn()
Qd.SetRectRgn(BIGREGION, -16000, -16000, 16000, 16000)
class WasteWindow(ScrolledWindow):
def open(self, path, name, data):
self.path = path
self.name = name
r = windowbounds(400, 400)
w = Win.NewWindow(r, name, 1, 0, -1, 1, 0)
self.wid = w
vr = LEFTMARGIN, 0, r[2]-r[0]-15, r[3]-r[1]-15
dr = (0, 0, vr[2], 0)
Qd.SetPort(w)
Qd.TextFont(4)
Qd.TextSize(9)
flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoOutlineHilite | \
WASTEconst.weDoMonoStyled | WASTEconst.weDoUndo
self.ted = waste.WENew(dr, vr, flags)
self.ted.WEInstallTabHooks()
style, soup = self.getstylesoup(self.path)
self.ted.WEInsert(data, style, soup)
self.ted.WESetSelection(0,0)
self.ted.WECalText()
self.ted.WEResetModCount()
w.DrawGrowIcon()
self.scrollbars()
self.do_postopen()
self.do_activate(1, None)
def getstylesoup(self, pathname):
if not pathname:
return None, None
oldrf = Res.CurResFile()
try:
rf = Res.FSpOpenResFile(self.path, 1)
except Res.Error:
return None, None
try:
hstyle = Res.Get1Resource('styl', 128)
hstyle.DetachResource()
except Res.Error:
hstyle = None
try:
hsoup = Res.Get1Resource('SOUP', 128)
hsoup.DetachResource()
except Res.Error:
hsoup = None
Res.CloseResFile(rf)
Res.UseResFile(oldrf)
return hstyle, hsoup
def do_idle(self, event):
(what, message, when, where, modifiers) = event
Qd.SetPort(self.wid)
self.ted.WEIdle()
if self.ted.WEAdjustCursor(where, BIGREGION):
return
Qd.SetCursor(Qd.GetQDGlobalsArrow())
def getscrollbarvalues(self):
dr = self.ted.WEGetDestRect()
vr = self.ted.WEGetViewRect()
vx = self.scalebarvalue(dr[0], dr[2], vr[0], vr[2])
vy = self.scalebarvalue(dr[1], dr[3], vr[1], vr[3])
return vx, vy
def scrollbar_callback(self, which, what, value):
if which == 'y':
#
# "line" size is minimum of top and bottom line size
#
topline_off,dummy = self.ted.WEGetOffset((1,1))
topline_num = self.ted.WEOffsetToLine(topline_off)
toplineheight = self.ted.WEGetHeight(topline_num, topline_num+1)
botlinepos = self.ted.WEGetViewRect()[3]
botline_off, dummy = self.ted.WEGetOffset((1, botlinepos-1))
botline_num = self.ted.WEOffsetToLine(botline_off)
botlineheight = self.ted.WEGetHeight(botline_num, botline_num+1)
if botlineheight == 0:
botlineheight = self.ted.WEGetHeight(botline_num-1, botline_num)
if botlineheight < toplineheight:
lineheight = botlineheight
else:
lineheight = toplineheight
if lineheight <= 0:
lineheight = 1
#
# Now do the command.
#
if what == 'set':
height = self.ted.WEGetHeight(0, 0x3fffffff)
cur = self.getscrollbarvalues()[1]
delta = (cur-value)*height/32767
if what == '-':
delta = lineheight
elif what == '--':
delta = (self.ted.WEGetViewRect()[3]-lineheight)
if delta <= 0:
delta = lineheight
elif what == '+':
delta = -lineheight
elif what == '++':
delta = -(self.ted.WEGetViewRect()[3]-lineheight)
if delta >= 0:
delta = -lineheight
self.ted.WEScroll(0, delta)
else:
if what == 'set':
return # XXXX
vr = self.ted.WEGetViewRect()
winwidth = vr[2]-vr[0]
if what == '-':
delta = winwidth/10
elif what == '--':
delta = winwidth/2
elif what == '+':
delta = -winwidth/10
elif what == '++':
delta = -winwidth/2
self.ted.WEScroll(delta, 0)
# Pin the scroll
l, t, r, b = self.ted.WEGetDestRect()
vl, vt, vr, vb = self.ted.WEGetViewRect()
if t > 0 or l > 0:
dx = dy = 0
if t > 0: dy = -t
if l > 0: dx = -l
self.ted.WEScroll(dx, dy)
elif b < vb:
self.ted.WEScroll(0, vb-b)
def do_activate(self, onoff, evt):
Qd.SetPort(self.wid)
ScrolledWindow.do_activate(self, onoff, evt)
if onoff:
self.ted.WEActivate()
self.parent.active = self
self.parent.updatemenubar()
else:
self.ted.WEDeactivate()
def do_update(self, wid, event):
region = wid.GetWindowPort().visRgn
if Qd.EmptyRgn(region):
return
Qd.EraseRgn(region)
self.ted.WEUpdate(region)
self.updatescrollbars()
def do_postresize(self, width, height, window):
l, t, r, b = self.ted.WEGetViewRect()
vr = (l, t, l+width-15, t+height-15)
self.ted.WESetViewRect(vr)
self.wid.InvalWindowRect(vr)
ScrolledWindow.do_postresize(self, width, height, window)
def do_contentclick(self, local, modifiers, evt):
(what, message, when, where, modifiers) = evt
self.ted.WEClick(local, modifiers, when)
self.updatescrollbars()
self.parent.updatemenubar()
def do_char(self, ch, event):
self.ted.WESelView()
(what, message, when, where, modifiers) = event
self.ted.WEKey(ord(ch), modifiers)
self.updatescrollbars()
self.parent.updatemenubar()
def close(self):
if self.ted.WEGetModCount():
save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?'%self.name, 1)
if save > 0:
self.menu_save()
elif save < 0:
return
if self.parent.active == self:
self.parent.active = None
self.parent.updatemenubar()
del self.ted
self.do_postclose()
def menu_save(self):
if not self.path:
self.menu_save_as()
return # Will call us recursively
#
# First save data
#
dhandle = self.ted.WEGetText()
data = dhandle.data
fp = open(self.path, 'wb') # NOTE: wb, because data has CR for end-of-line
fp.write(data)
if data[-1] <> '\r': fp.write('\r')
fp.close()
#
# Now save style and soup
#
oldresfile = Res.CurResFile()
try:
rf = Res.FSpOpenResFile(self.path, 3)
except Res.Error:
Res.FSpCreateResFile(self.path, '????', 'TEXT', macfs.smAllScripts)
rf = Res.FSpOpenResFile(self.path, 3)
styles = Res.Resource('')
soup = Res.Resource('')
self.ted.WECopyRange(0, 0x3fffffff, None, styles, soup)
styles.AddResource('styl', 128, '')
soup.AddResource('SOUP', 128, '')
Res.CloseResFile(rf)
Res.UseResFile(oldresfile)
self.ted.WEResetModCount()
def menu_save_as(self):
path = EasyDialogs.AskFileForSave(message='Save as:')
if not path: return
self.path = path
self.name = os.path.split(self.path)[-1]
self.wid.SetWTitle(self.name)
self.menu_save()
def menu_insert(self, fp):
self.ted.WESelView()
data = fp.read()
self.ted.WEInsert(data, None, None)
self.updatescrollbars()
self.parent.updatemenubar()
def menu_insert_html(self, fp):
import htmllib
import formatter
f = formatter.AbstractFormatter(self)
# Remember where we are, and don't update
Qd.SetCursor(WATCH)
start, dummy = self.ted.WEGetSelection()
self.ted.WEFeatureFlag(WASTEconst.weFInhibitRecal, 1)
self.html_init()
p = MyHTMLParser(f)
p.feed(fp.read())
# Restore updating, recalc, set focus
dummy, end = self.ted.WEGetSelection()
self.ted.WECalText()
self.ted.WESetSelection(start, end)
self.ted.WESelView()
self.ted.WEFeatureFlag(WASTEconst.weFInhibitRecal, 0)
self.wid.InvalWindowRect(self.ted.WEGetViewRect())
self.updatescrollbars()
self.parent.updatemenubar()
def menu_cut(self):
self.ted.WESelView()
if hasattr(Scrap, 'ZeroScrap'):
Scrap.ZeroScrap()
else:
Scrap.ClearCurrentScrap()
self.ted.WECut()
self.updatescrollbars()
self.parent.updatemenubar()
def menu_copy(self):
if hasattr(Scrap, 'ZeroScrap'):
Scrap.ZeroScrap()
else:
Scrap.ClearCurrentScrap()
self.ted.WECopy()
self.updatescrollbars()
self.parent.updatemenubar()
def menu_paste(self):
self.ted.WESelView()
self.ted.WEPaste()
self.updatescrollbars()
self.parent.updatemenubar()
def menu_clear(self):
self.ted.WESelView()
self.ted.WEDelete()
self.updatescrollbars()
self.parent.updatemenubar()
def menu_undo(self):
self.ted.WEUndo()
self.updatescrollbars()
self.parent.updatemenubar()
def menu_setfont(self, font):
font = Fm.GetFNum(font)
self.mysetstyle(WASTEconst.weDoFont, (font, 0, 0, (0,0,0)))
self.parent.updatemenubar()
def menu_modface(self, face):
self.mysetstyle(WASTEconst.weDoFace|WASTEconst.weDoToggleFace,
(0, face, 0, (0,0,0)))
def menu_setface(self, face):
self.mysetstyle(WASTEconst.weDoFace|WASTEconst.weDoReplaceFace,
(0, face, 0, (0,0,0)))
def menu_setsize(self, size):
self.mysetstyle(WASTEconst.weDoSize, (0, 0, size, (0,0,0)))
def menu_incsize(self, size):
self.mysetstyle(WASTEconst.weDoAddSize, (0, 0, size, (0,0,0)))
def mysetstyle(self, which, how):
self.ted.WESelView()
self.ted.WESetStyle(which, how)
self.parent.updatemenubar()
def have_selection(self):
start, stop = self.ted.WEGetSelection()
return start < stop
def can_paste(self):
return self.ted.WECanPaste()
def can_undo(self):
which, redo = self.ted.WEGetUndoInfo()
which = UNDOLABELS[which]
if which == None: return None
if redo:
return "Redo "+which
else:
return "Undo "+which
def getruninfo(self):
all = (WASTEconst.weDoFont | WASTEconst.weDoFace | WASTEconst.weDoSize)
dummy, mode, (font, face, size, color) = self.ted.WEContinuousStyle(all)
if not (mode & WASTEconst.weDoFont):
font = None
else:
font = Fm.GetFontName(font)
if not (mode & WASTEconst.weDoFace): fact = None
if not (mode & WASTEconst.weDoSize): size = None
return font, face, size
#
# Methods for writer class for html formatter
#
def html_init(self):
self.html_font = [12, 0, 0, 0]
self.html_style = 0
self.html_color = (0,0,0)
self.new_font(self.html_font)
def new_font(self, font):
if font == None:
font = (12, 0, 0, 0)
font = map(lambda x:x, font)
for i in range(len(font)):
if font[i] == None:
font[i] = self.html_font[i]
[size, italic, bold, tt] = font
self.html_font = font[:]
if tt:
font = Fm.GetFNum('Courier')
else:
font = Fm.GetFNum('Times')
if HTML_SIZE.has_key(size):
size = HTML_SIZE[size]
else:
size = 12
face = 0
if bold: face = face | 1
if italic: face = face | 2
face = face | self.html_style
self.ted.WESetStyle(WASTEconst.weDoFont | WASTEconst.weDoFace |
WASTEconst.weDoSize | WASTEconst.weDoColor,
(font, face, size, self.html_color))
def new_margin(self, margin, level):
self.ted.WEInsert('[Margin %s %s]'%(margin, level), None, None)
def new_spacing(self, spacing):
self.ted.WEInsert('[spacing %s]'%spacing, None, None)
def new_styles(self, styles):
self.html_style = 0
self.html_color = (0,0,0)
if 'anchor' in styles:
self.html_style = self.html_style | 4
self.html_color = (0xffff, 0, 0)
self.new_font(self.html_font)
def send_paragraph(self, blankline):
self.ted.WEInsert('\r'*(blankline+1), None, None)
def send_line_break(self):
self.ted.WEInsert('\r', None, None)
def send_hor_rule(self, *args, **kw):
# Ignore ruler options, for now
dummydata = Res.Resource('')
self.ted.WEInsertObject('rulr', dummydata, (0,0))
def send_label_data(self, data):
self.ted.WEInsert(data, None, None)
def send_flowing_data(self, data):
self.ted.WEInsert(data, None, None)
def send_literal_data(self, data):
data = string.replace(data, '\n', '\r')
data = string.expandtabs(data)
self.ted.WEInsert(data, None, None)
class Wed(Application):
def __init__(self):
Application.__init__(self)
self.num = 0
self.active = None
self.updatemenubar()
waste.STDObjectHandlers()
# Handler for horizontal ruler
waste.WEInstallObjectHandler('rulr', 'new ', self.newRuler)
waste.WEInstallObjectHandler('rulr', 'draw', self.drawRuler)
def makeusermenus(self):
self.filemenu = m = Menu(self.menubar, "File")
self.newitem = MenuItem(m, "New window", "N", self.open)
self.openitem = MenuItem(m, "Open...", "O", self.openfile)
self.closeitem = MenuItem(m, "Close", "W", self.closewin)
m.addseparator()
self.saveitem = MenuItem(m, "Save", "S", self.save)
self.saveasitem = MenuItem(m, "Save as...", "", self.saveas)
m.addseparator()
self.insertitem = MenuItem(m, "Insert plaintext...", "", self.insertfile)
self.htmlitem = MenuItem(m, "Insert HTML...", "", self.inserthtml)
m.addseparator()
self.quititem = MenuItem(m, "Quit", "Q", self.quit)
self.editmenu = m = Menu(self.menubar, "Edit")
self.undoitem = MenuItem(m, "Undo", "Z", self.undo)
self.cutitem = MenuItem(m, "Cut", "X", self.cut)
self.copyitem = MenuItem(m, "Copy", "C", self.copy)
self.pasteitem = MenuItem(m, "Paste", "V", self.paste)
self.clearitem = MenuItem(m, "Clear", "", self.clear)
self.makefontmenu()
# Groups of items enabled together:
self.windowgroup = [self.closeitem, self.saveitem, self.saveasitem,
self.editmenu, self.fontmenu, self.facemenu, self.sizemenu,
self.insertitem]
self.focusgroup = [self.cutitem, self.copyitem, self.clearitem]
self.windowgroup_on = -1
self.focusgroup_on = -1
self.pastegroup_on = -1
self.undo_label = "never"
self.ffs_values = ()
def makefontmenu(self):
self.fontmenu = Menu(self.menubar, "Font")
self.fontnames = getfontnames()
self.fontitems = []
for n in self.fontnames:
m = MenuItem(self.fontmenu, n, "", self.selfont)
self.fontitems.append(m)
self.facemenu = Menu(self.menubar, "Style")
self.faceitems = []
for n, shortcut in STYLES:
m = MenuItem(self.facemenu, n, shortcut, self.selface)
self.faceitems.append(m)
self.facemenu.addseparator()
self.faceitem_normal = MenuItem(self.facemenu, "Normal", "N",
self.selfacenormal)
self.sizemenu = Menu(self.menubar, "Size")
self.sizeitems = []
for n in SIZES:
m = MenuItem(self.sizemenu, repr(n), "", self.selsize)
self.sizeitems.append(m)
self.sizemenu.addseparator()
self.sizeitem_bigger = MenuItem(self.sizemenu, "Bigger", "+",
self.selsizebigger)
self.sizeitem_smaller = MenuItem(self.sizemenu, "Smaller", "-",
self.selsizesmaller)
def selfont(self, id, item, *rest):
if self.active:
font = self.fontnames[item-1]
self.active.menu_setfont(font)
else:
EasyDialogs.Message("No active window?")
def selface(self, id, item, *rest):
if self.active:
face = (1<<(item-1))
self.active.menu_modface(face)
else:
EasyDialogs.Message("No active window?")
def selfacenormal(self, *rest):
if self.active:
self.active.menu_setface(0)
else:
EasyDialogs.Message("No active window?")
def selsize(self, id, item, *rest):
if self.active:
size = SIZES[item-1]
self.active.menu_setsize(size)
else:
EasyDialogs.Message("No active window?")
def selsizebigger(self, *rest):
if self.active:
self.active.menu_incsize(2)
else:
EasyDialogs.Message("No active window?")
def selsizesmaller(self, *rest):
if self.active:
self.active.menu_incsize(-2)
else:
EasyDialogs.Message("No active window?")
def updatemenubar(self):
changed = 0
on = (self.active <> None)
if on <> self.windowgroup_on:
for m in self.windowgroup:
m.enable(on)
self.windowgroup_on = on
changed = 1
if on:
# only if we have an edit menu
on = self.active.have_selection()
if on <> self.focusgroup_on:
for m in self.focusgroup:
m.enable(on)
self.focusgroup_on = on
changed = 1
on = self.active.can_paste()
if on <> self.pastegroup_on:
self.pasteitem.enable(on)
self.pastegroup_on = on
changed = 1
on = self.active.can_undo()
if on <> self.undo_label:
if on:
self.undoitem.enable(1)
self.undoitem.settext(on)
self.undo_label = on
else:
self.undoitem.settext("Nothing to undo")
self.undoitem.enable(0)
changed = 1
if self.updatefontmenus():
changed = 1
if changed:
DrawMenuBar()
def updatefontmenus(self):
info = self.active.getruninfo()
if info == self.ffs_values:
return 0
# Remove old checkmarks
if self.ffs_values == ():
self.ffs_values = (None, None, None)
font, face, size = self.ffs_values
if font <> None:
fnum = self.fontnames.index(font)
self.fontitems[fnum].check(0)
if face <> None:
for i in range(len(self.faceitems)):
if face & (1<<i):
self.faceitems[i].check(0)
if size <> None:
for i in range(len(self.sizeitems)):
if SIZES[i] == size:
self.sizeitems[i].check(0)
self.ffs_values = info
# Set new checkmarks
font, face, size = self.ffs_values
if font <> None:
fnum = self.fontnames.index(font)
self.fontitems[fnum].check(1)
if face <> None:
for i in range(len(self.faceitems)):
if face & (1<<i):
self.faceitems[i].check(1)
if size <> None:
for i in range(len(self.sizeitems)):
if SIZES[i] == size:
self.sizeitems[i].check(1)
# Set outline/normal for sizes
if font:
exists = getfontsizes(font, SIZES)
for i in range(len(self.sizeitems)):
if exists[i]:
self.sizeitems[i].setstyle(0)
else:
self.sizeitems[i].setstyle(8)
#
# Apple menu
#
def do_about(self, id, item, window, event):
EasyDialogs.Message("A simple single-font text editor based on WASTE")
#
# File menu
#
def open(self, *args):
self._open(0)
def openfile(self, *args):
self._open(1)
def _open(self, askfile):
if askfile:
path = EasyDialogs.AskFileForOpen(typeList=('TEXT',))
if not path:
return
name = os.path.split(path)[-1]
try:
fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line
data = fp.read()
fp.close()
except IOError, arg:
EasyDialogs.Message("IOERROR: %r" % (arg,))
return
else:
path = None
name = "Untitled %d"%self.num
data = ''
w = WasteWindow(self)
w.open(path, name, data)
self.num = self.num + 1
def insertfile(self, *args):
if self.active:
path = EasyDialogs.AskFileForOpen(typeList=('TEXT',))
if not path:
return
try:
fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line
except IOError, arg:
EasyDialogs.Message("IOERROR: %r" % (args,))
return
self.active.menu_insert(fp)
else:
EasyDialogs.Message("No active window?")
def inserthtml(self, *args):
if self.active:
path = EasyDialogs.AskFileForOpen(typeList=('TEXT',))
if not path:
return
try:
fp = open(path, 'r')
except IOError, arg:
EasyDialogs.Message("IOERROR: %r" % (arg,))
return
self.active.menu_insert_html(fp)
else:
EasyDialogs.Message("No active window?")
def closewin(self, *args):
if self.active:
self.active.close()
else:
EasyDialogs.Message("No active window?")
def save(self, *args):
if self.active:
self.active.menu_save()
else:
EasyDialogs.Message("No active window?")
def saveas(self, *args):
if self.active:
self.active.menu_save_as()
else:
EasyDialogs.Message("No active window?")
def quit(self, *args):
for w in self._windows.values():
w.close()
if self._windows:
return
self._quit()
#
# Edit menu
#
def undo(self, *args):
if self.active:
self.active.menu_undo()
else:
EasyDialogs.Message("No active window?")
def cut(self, *args):
if self.active:
self.active.menu_cut()
else:
EasyDialogs.Message("No active window?")
def copy(self, *args):
if self.active:
self.active.menu_copy()
else:
EasyDialogs.Message("No active window?")
def paste(self, *args):
if self.active:
self.active.menu_paste()
else:
EasyDialogs.Message("No active window?")
def clear(self, *args):
if self.active:
self.active.menu_clear()
else:
EasyDialogs.Message("No active window?")
#
# Other stuff
#
def idle(self, event):
if self.active:
self.active.do_idle(event)
else:
Qd.SetCursor(Qd.GetQDGlobalsArrow())
def newRuler(self, obj):
"""Insert a new ruler. Make it as wide as the window minus 2 pxls"""
ted = obj.WEGetObjectOwner()
l, t, r, b = ted.WEGetDestRect()
return r-l, 4
def drawRuler(self, (l, t, r, b), obj):
y = (t+b)/2
Qd.MoveTo(l+2, y)
Qd.LineTo(r-2, y)
return 0
class MyHTMLParser(htmllib.HTMLParser):
def anchor_bgn(self, href, name, type):
self.anchor = href
if self.anchor:
self.anchorlist.append(href)
self.formatter.push_style('anchor')
def anchor_end(self):
if self.anchor:
self.anchor = None
self.formatter.pop_style()
def getfontnames():
names = []
for i in range(256):
n = Fm.GetFontName(i)
if n: names.append(n)
return names
def getfontsizes(name, sizes):
exist = []
num = Fm.GetFNum(name)
for sz in sizes:
if Fm.RealFont(num, sz):
exist.append(1)
else:
exist.append(0)
return exist
def main():
App = Wed()
App.mainloop()
if __name__ == '__main__':
main()

View File

@ -1,634 +0,0 @@
# A minimal text editor.
#
# To be done:
# - Functionality: find, etc.
from Carbon.Menu import DrawMenuBar
from FrameWork import *
from Carbon import Win
from Carbon import Qd
from Carbon import Res
from Carbon import Fm
import waste
import WASTEconst
from Carbon import Scrap
import os
import macfs
UNDOLABELS = [ # Indexed by WEGetUndoInfo() value
None, "", "typing", "Cut", "Paste", "Clear", "Drag", "Style"]
# Style and size menu. Note that style order is important (tied to bit values)
STYLES = [
("Bold", "B"), ("Italic", "I"), ("Underline", "U"), ("Outline", "O"),
("Shadow", ""), ("Condensed", ""), ("Extended", "")
]
SIZES = [ 9, 10, 12, 14, 18, 24]
BIGREGION=Qd.NewRgn()
Qd.SetRectRgn(BIGREGION, -16000, -16000, 16000, 16000)
class WasteWindow(ScrolledWindow):
def open(self, path, name, data):
self.path = path
self.name = name
r = windowbounds(400, 400)
w = Win.NewWindow(r, name, 1, 0, -1, 1, 0)
self.wid = w
vr = 0, 0, r[2]-r[0]-15, r[3]-r[1]-15
dr = (0, 0, 10240, 0)
Qd.SetPort(w)
Qd.TextFont(4)
Qd.TextSize(9)
flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoOutlineHilite | \
WASTEconst.weDoUndo
self.ted = waste.WENew(dr, vr, flags)
self.ted.WEInstallTabHooks()
style, soup = self.getstylesoup()
self.ted.WEInsert(data, style, soup)
self.ted.WESetSelection(0,0)
self.ted.WECalText()
self.ted.WEResetModCount()
w.DrawGrowIcon()
self.scrollbars()
self.do_postopen()
self.do_activate(1, None)
def getstylesoup(self):
if not self.path:
return None, None
oldrf = Res.CurResFile()
try:
rf = Res.FSpOpenResFile(self.path, 1)
except Res.Error:
return None, None
try:
hstyle = Res.Get1Resource('styl', 128)
hstyle.DetachResource()
except Res.Error:
hstyle = None
try:
hsoup = Res.Get1Resource('SOUP', 128)
hsoup.DetachResource()
except Res.Error:
hsoup = None
Res.CloseResFile(rf)
Res.UseResFile(oldrf)
return hstyle, hsoup
def do_idle(self, event):
(what, message, when, where, modifiers) = event
Qd.SetPort(self.wid)
self.ted.WEIdle()
if self.ted.WEAdjustCursor(where, BIGREGION):
return
Qd.SetCursor(Qd.GetQDGlobalsArrow())
def getscrollbarvalues(self):
dr = self.ted.WEGetDestRect()
vr = self.ted.WEGetViewRect()
vx = self.scalebarvalue(dr[0], dr[2], vr[0], vr[2])
vy = self.scalebarvalue(dr[1], dr[3], vr[1], vr[3])
return vx, vy
def scrollbar_callback(self, which, what, value):
if which == 'y':
if what == 'set':
height = self.ted.WEGetHeight(0, 0x3fffffff)
cur = self.getscrollbarvalues()[1]
delta = (cur-value)*height/32767
if what == '-':
topline_off,dummy = self.ted.WEGetOffset((1,1))
topline_num = self.ted.WEOffsetToLine(topline_off)
delta = self.ted.WEGetHeight(topline_num, topline_num+1)
elif what == '--':
delta = (self.ted.WEGetViewRect()[3]-10)
if delta <= 0:
delta = 10 # Random value
elif what == '+':
# XXXX Wrong: should be bottom line size
topline_off,dummy = self.ted.WEGetOffset((1,1))
topline_num = self.ted.WEOffsetToLine(topline_off)
delta = -self.ted.WEGetHeight(topline_num, topline_num+1)
elif what == '++':
delta = -(self.ted.WEGetViewRect()[3]-10)
if delta >= 0:
delta = -10
self.ted.WEScroll(0, delta)
else:
if what == 'set':
return # XXXX
vr = self.ted.WEGetViewRect()
winwidth = vr[2]-vr[0]
if what == '-':
delta = winwidth/10
elif what == '--':
delta = winwidth/2
elif what == '+':
delta = -winwidth/10
elif what == '++':
delta = -winwidth/2
self.ted.WEScroll(delta, 0)
# Pin the scroll
l, t, r, b = self.ted.WEGetDestRect()
vl, vt, vr, vb = self.ted.WEGetViewRect()
if t > 0 or l > 0:
dx = dy = 0
if t > 0: dy = -t
if l > 0: dx = -l
self.ted.WEScroll(dx, dy)
elif b < vb:
self.ted.WEScroll(0, b-vb)
def do_activate(self, onoff, evt):
Qd.SetPort(self.wid)
ScrolledWindow.do_activate(self, onoff, evt)
if onoff:
self.ted.WEActivate()
self.parent.active = self
self.parent.updatemenubar()
else:
self.ted.WEDeactivate()
def do_update(self, wid, event):
region = wid.GetWindowPort().visRgn
if Qd.EmptyRgn(region):
return
Qd.EraseRgn(region)
self.ted.WEUpdate(region)
self.updatescrollbars()
def do_postresize(self, width, height, window):
l, t, r, b = self.ted.WEGetViewRect()
vr = (l, t, l+width-15, t+height-15)
self.ted.WESetViewRect(vr)
self.wid.InvalWindowRect(vr)
ScrolledWindow.do_postresize(self, width, height, window)
def do_contentclick(self, local, modifiers, evt):
(what, message, when, where, modifiers) = evt
self.ted.WEClick(local, modifiers, when)
self.updatescrollbars()
self.parent.updatemenubar()
def do_char(self, ch, event):
self.ted.WESelView()
(what, message, when, where, modifiers) = event
self.ted.WEKey(ord(ch), modifiers)
self.updatescrollbars()
self.parent.updatemenubar()
def close(self):
if self.ted.WEGetModCount():
save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?'%self.name, 1)
if save > 0:
self.menu_save()
elif save < 0:
return
if self.parent.active == self:
self.parent.active = None
self.parent.updatemenubar()
del self.ted
self.do_postclose()
def menu_save(self):
if not self.path:
self.menu_save_as()
return # Will call us recursively
#
# First save data
#
dhandle = self.ted.WEGetText()
data = dhandle.data
fp = open(self.path, 'wb') # NOTE: wb, because data has CR for end-of-line
fp.write(data)
if data[-1] <> '\r': fp.write('\r')
fp.close()
#
# Now save style and soup
#
oldresfile = Res.CurResFile()
try:
rf = Res.FSpOpenResFile(self.path, 3)
except Res.Error:
Res.FSpCreateResFile(self.path, '????', 'TEXT', macfs.smAllScripts)
rf = Res.FSpOpenResFile(self.path, 3)
styles = Res.Resource('')
soup = Res.Resource('')
self.ted.WECopyRange(0, 0x3fffffff, None, styles, soup)
styles.AddResource('styl', 128, '')
soup.AddResource('SOUP', 128, '')
Res.CloseResFile(rf)
Res.UseResFile(oldresfile)
self.ted.WEResetModCount()
def menu_save_as(self):
path = EasyDialogs.AskFileForSave(message='Save as:')
if not path: return
self.path = path
self.name = os.path.split(self.path)[-1]
self.wid.SetWTitle(self.name)
self.menu_save()
def menu_cut(self):
self.ted.WESelView()
if hasattr(Scrap, 'ZeroScrap'):
Scrap.ZeroScrap()
else:
Scrap.ClearCurrentScrap()
self.ted.WECut()
self.updatescrollbars()
self.parent.updatemenubar()
def menu_copy(self):
if hasattr(Scrap, 'ZeroScrap'):
Scrap.ZeroScrap()
else:
Scrap.ClearCurrentScrap()
self.ted.WECopy()
self.updatescrollbars()
self.parent.updatemenubar()
def menu_paste(self):
self.ted.WESelView()
self.ted.WEPaste()
self.updatescrollbars()
self.parent.updatemenubar()
def menu_clear(self):
self.ted.WESelView()
self.ted.WEDelete()
self.updatescrollbars()
self.parent.updatemenubar()
def menu_undo(self):
self.ted.WEUndo()
self.updatescrollbars()
self.parent.updatemenubar()
def menu_setfont(self, font):
font = Fm.GetFNum(font)
self.mysetstyle(WASTEconst.weDoFont, (font, 0, 0, (0,0,0)))
self.parent.updatemenubar()
def menu_modface(self, face):
self.mysetstyle(WASTEconst.weDoFace|WASTEconst.weDoToggleFace,
(0, face, 0, (0,0,0)))
def menu_setface(self, face):
self.mysetstyle(WASTEconst.weDoFace|WASTEconst.weDoReplaceFace,
(0, face, 0, (0,0,0)))
def menu_setsize(self, size):
self.mysetstyle(WASTEconst.weDoSize, (0, 0, size, (0,0,0)))
def menu_incsize(self, size):
self.mysetstyle(WASTEconst.weDoAddSize, (0, 0, size, (0,0,0)))
def mysetstyle(self, which, how):
self.ted.WESelView()
self.ted.WESetStyle(which, how)
self.parent.updatemenubar()
def have_selection(self):
start, stop = self.ted.WEGetSelection()
return start < stop
def can_paste(self):
return self.ted.WECanPaste()
def can_undo(self):
which, redo = self.ted.WEGetUndoInfo()
which = UNDOLABELS[which]
if which == None: return None
if redo:
return "Redo "+which
else:
return "Undo "+which
def getruninfo(self):
all = (WASTEconst.weDoFont | WASTEconst.weDoFace | WASTEconst.weDoSize)
dummy, mode, (font, face, size, color) = self.ted.WEContinuousStyle(all)
if not (mode & WASTEconst.weDoFont):
font = None
else:
font = Fm.GetFontName(font)
if not (mode & WASTEconst.weDoFace): fact = None
if not (mode & WASTEconst.weDoSize): size = None
return font, face, size
class Wed(Application):
def __init__(self):
Application.__init__(self)
self.num = 0
self.active = None
self.updatemenubar()
waste.STDObjectHandlers()
def makeusermenus(self):
self.filemenu = m = Menu(self.menubar, "File")
self.newitem = MenuItem(m, "New window", "N", self.open)
self.openitem = MenuItem(m, "Open...", "O", self.openfile)
self.closeitem = MenuItem(m, "Close", "W", self.closewin)
m.addseparator()
self.saveitem = MenuItem(m, "Save", "S", self.save)
self.saveasitem = MenuItem(m, "Save as...", "", self.saveas)
m.addseparator()
self.quititem = MenuItem(m, "Quit", "Q", self.quit)
self.editmenu = m = Menu(self.menubar, "Edit")
self.undoitem = MenuItem(m, "Undo", "Z", self.undo)
self.cutitem = MenuItem(m, "Cut", "X", self.cut)
self.copyitem = MenuItem(m, "Copy", "C", self.copy)
self.pasteitem = MenuItem(m, "Paste", "V", self.paste)
self.clearitem = MenuItem(m, "Clear", "", self.clear)
self.makefontmenu()
# Groups of items enabled together:
self.windowgroup = [self.closeitem, self.saveitem, self.saveasitem,
self.editmenu, self.fontmenu, self.facemenu, self.sizemenu]
self.focusgroup = [self.cutitem, self.copyitem, self.clearitem]
self.windowgroup_on = -1
self.focusgroup_on = -1
self.pastegroup_on = -1
self.undo_label = "never"
self.ffs_values = ()
def makefontmenu(self):
self.fontmenu = Menu(self.menubar, "Font")
self.fontnames = getfontnames()
self.fontitems = []
for n in self.fontnames:
m = MenuItem(self.fontmenu, n, "", self.selfont)
self.fontitems.append(m)
self.facemenu = Menu(self.menubar, "Style")
self.faceitems = []
for n, shortcut in STYLES:
m = MenuItem(self.facemenu, n, shortcut, self.selface)
self.faceitems.append(m)
self.facemenu.addseparator()
self.faceitem_normal = MenuItem(self.facemenu, "Normal", "N",
self.selfacenormal)
self.sizemenu = Menu(self.menubar, "Size")
self.sizeitems = []
for n in SIZES:
m = MenuItem(self.sizemenu, repr(n), "", self.selsize)
self.sizeitems.append(m)
self.sizemenu.addseparator()
self.sizeitem_bigger = MenuItem(self.sizemenu, "Bigger", "+",
self.selsizebigger)
self.sizeitem_smaller = MenuItem(self.sizemenu, "Smaller", "-",
self.selsizesmaller)
def selfont(self, id, item, *rest):
if self.active:
font = self.fontnames[item-1]
self.active.menu_setfont(font)
else:
EasyDialogs.Message("No active window?")
def selface(self, id, item, *rest):
if self.active:
face = (1<<(item-1))
self.active.menu_modface(face)
else:
EasyDialogs.Message("No active window?")
def selfacenormal(self, *rest):
if self.active:
self.active.menu_setface(0)
else:
EasyDialogs.Message("No active window?")
def selsize(self, id, item, *rest):
if self.active:
size = SIZES[item-1]
self.active.menu_setsize(size)
else:
EasyDialogs.Message("No active window?")
def selsizebigger(self, *rest):
if self.active:
self.active.menu_incsize(2)
else:
EasyDialogs.Message("No active window?")
def selsizesmaller(self, *rest):
if self.active:
self.active.menu_incsize(-2)
else:
EasyDialogs.Message("No active window?")
def updatemenubar(self):
changed = 0
on = (self.active <> None)
if on <> self.windowgroup_on:
for m in self.windowgroup:
m.enable(on)
self.windowgroup_on = on
changed = 1
if on:
# only if we have an edit menu
on = self.active.have_selection()
if on <> self.focusgroup_on:
for m in self.focusgroup:
m.enable(on)
self.focusgroup_on = on
changed = 1
on = self.active.can_paste()
if on <> self.pastegroup_on:
self.pasteitem.enable(on)
self.pastegroup_on = on
changed = 1
on = self.active.can_undo()
if on <> self.undo_label:
if on:
self.undoitem.enable(1)
self.undoitem.settext(on)
self.undo_label = on
else:
self.undoitem.settext("Nothing to undo")
self.undoitem.enable(0)
changed = 1
if self.updatefontmenus():
changed = 1
if changed:
DrawMenuBar()
def updatefontmenus(self):
info = self.active.getruninfo()
if info == self.ffs_values:
return 0
# Remove old checkmarks
if self.ffs_values == ():
self.ffs_values = (None, None, None)
font, face, size = self.ffs_values
if font <> None:
fnum = self.fontnames.index(font)
self.fontitems[fnum].check(0)
if face <> None:
for i in range(len(self.faceitems)):
if face & (1<<i):
self.faceitems[i].check(0)
if size <> None:
for i in range(len(self.sizeitems)):
if SIZES[i] == size:
self.sizeitems[i].check(0)
self.ffs_values = info
# Set new checkmarks
font, face, size = self.ffs_values
if font <> None:
fnum = self.fontnames.index(font)
self.fontitems[fnum].check(1)
if face <> None:
for i in range(len(self.faceitems)):
if face & (1<<i):
self.faceitems[i].check(1)
if size <> None:
for i in range(len(self.sizeitems)):
if SIZES[i] == size:
self.sizeitems[i].check(1)
# Set outline/normal for sizes
if font:
exists = getfontsizes(font, SIZES)
for i in range(len(self.sizeitems)):
if exists[i]:
self.sizeitems[i].setstyle(0)
else:
self.sizeitems[i].setstyle(8)
#
# Apple menu
#
def do_about(self, id, item, window, event):
EasyDialogs.Message("A simple single-font text editor based on WASTE")
#
# File menu
#
def open(self, *args):
self._open(0)
def openfile(self, *args):
self._open(1)
def _open(self, askfile):
if askfile:
path = EasyDialogs.AskFileForOpen(typeList=('TEXT',))
if not path:
return
name = os.path.split(path)[-1]
try:
fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line
data = fp.read()
fp.close()
except IOError, arg:
EasyDialogs.Message("IOERROR: %r" % (arg,))
return
else:
path = None
name = "Untitled %d"%self.num
data = ''
w = WasteWindow(self)
w.open(path, name, data)
self.num = self.num + 1
def closewin(self, *args):
if self.active:
self.active.close()
else:
EasyDialogs.Message("No active window?")
def save(self, *args):
if self.active:
self.active.menu_save()
else:
EasyDialogs.Message("No active window?")
def saveas(self, *args):
if self.active:
self.active.menu_save_as()
else:
EasyDialogs.Message("No active window?")
def quit(self, *args):
for w in self._windows.values():
w.close()
if self._windows:
return
self._quit()
#
# Edit menu
#
def undo(self, *args):
if self.active:
self.active.menu_undo()
else:
EasyDialogs.Message("No active window?")
def cut(self, *args):
if self.active:
self.active.menu_cut()
else:
EasyDialogs.Message("No active window?")
def copy(self, *args):
if self.active:
self.active.menu_copy()
else:
EasyDialogs.Message("No active window?")
def paste(self, *args):
if self.active:
self.active.menu_paste()
else:
EasyDialogs.Message("No active window?")
def clear(self, *args):
if self.active:
self.active.menu_clear()
else:
EasyDialogs.Message("No active window?")
#
# Other stuff
#
def idle(self, event):
if self.active:
self.active.do_idle(event)
else:
Qd.SetCursor(Qd.GetQDGlobalsArrow())
def getfontnames():
names = []
for i in range(256):
n = Fm.GetFontName(i)
if n: names.append(n)
return names
def getfontsizes(name, sizes):
exist = []
num = Fm.GetFNum(name)
for sz in sizes:
if Fm.RealFont(num, sz):
exist.append(1)
else:
exist.append(0)
return exist
def main():
App = Wed()
App.mainloop()
if __name__ == '__main__':
main()

View File

@ -1,426 +0,0 @@
# A minimal text editor.
#
# To be done:
# - Functionality: find, etc.
from Carbon.Menu import DrawMenuBar
from FrameWork import *
from Carbon import Win
from Carbon import Qd
from Carbon import Res
import waste
import WASTEconst
from Carbon import Scrap
import os
import EasyDialogs
UNDOLABELS = [ # Indexed by WEGetUndoInfo() value
None, "", "typing", "Cut", "Paste", "Clear", "Drag", "Style"]
BIGREGION=Qd.NewRgn()
Qd.SetRectRgn(BIGREGION, -16000, -16000, 16000, 16000)
class WasteWindow(ScrolledWindow):
def open(self, path, name, data):
self.path = path
self.name = name
r = windowbounds(400, 400)
w = Win.NewWindow(r, name, 1, 0, -1, 1, 0)
self.wid = w
vr = 0, 0, r[2]-r[0]-15, r[3]-r[1]-15
dr = (0, 0, 10240, 0)
Qd.SetPort(w)
Qd.TextFont(4)
Qd.TextSize(9)
flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoOutlineHilite | \
WASTEconst.weDoMonoStyled | WASTEconst.weDoUndo
self.ted = waste.WENew(dr, vr, flags)
self.tedtexthandle = Res.Resource(data)
self.ted.WEUseText(self.tedtexthandle)
self.ted.WECalText()
w.DrawGrowIcon()
self.scrollbars()
self.changed = 0
self.do_postopen()
self.do_activate(1, None)
def do_idle(self, event):
(what, message, when, where, modifiers) = event
Qd.SetPort(self.wid)
self.ted.WEIdle()
if self.ted.WEAdjustCursor(where, BIGREGION):
return
Qd.SetCursor(Qd.GetQDGlobalsArrow())
def getscrollbarvalues(self):
dr = self.ted.WEGetDestRect()
vr = self.ted.WEGetViewRect()
vx = self.scalebarvalue(dr[0], dr[2], vr[0], vr[2])
vy = self.scalebarvalue(dr[1], dr[3], vr[1], vr[3])
## print dr, vr, vx, vy
return vx, vy
def scrollbar_callback(self, which, what, value):
if which == 'y':
if what == 'set':
height = self.ted.WEGetHeight(0, 0x3fffffff)
cur = self.getscrollbarvalues()[1]
delta = (cur-value)*height/32767
if what == '-':
topline_off,dummy = self.ted.WEGetOffset((1,1))
topline_num = self.ted.WEOffsetToLine(topline_off)
delta = self.ted.WEGetHeight(topline_num, topline_num+1)
elif what == '--':
delta = (self.ted.WEGetViewRect()[3]-10)
if delta <= 0:
delta = 10 # Random value
elif what == '+':
# XXXX Wrong: should be bottom line size
topline_off,dummy = self.ted.WEGetOffset((1,1))
topline_num = self.ted.WEOffsetToLine(topline_off)
delta = -self.ted.WEGetHeight(topline_num, topline_num+1)
elif what == '++':
delta = -(self.ted.WEGetViewRect()[3]-10)
if delta >= 0:
delta = -10
self.ted.WEScroll(0, delta)
## print 'SCROLL Y', delta
else:
if what == 'set':
return # XXXX
vr = self.ted.WEGetViewRect()
winwidth = vr[2]-vr[0]
if what == '-':
delta = winwidth/10
elif what == '--':
delta = winwidth/2
elif what == '+':
delta = -winwidth/10
elif what == '++':
delta = -winwidth/2
self.ted.WEScroll(delta, 0)
# Pin the scroll
l, t, r, b = self.ted.WEGetDestRect()
vl, vt, vr, vb = self.ted.WEGetViewRect()
if t > 0 or l > 0:
dx = dy = 0
if t > 0: dy = -t
if l > 0: dx = -l
## print 'Extra scroll', dx, dy
self.ted.WEScroll(dx, dy)
elif b < vb:
## print 'Extra downscroll', b-vb
self.ted.WEScroll(0, b-vb)
def do_activate(self, onoff, evt):
## print "ACTIVATE", onoff
Qd.SetPort(self.wid)
ScrolledWindow.do_activate(self, onoff, evt)
if onoff:
self.ted.WEActivate()
self.parent.active = self
self.parent.updatemenubar()
else:
self.ted.WEDeactivate()
def do_update(self, wid, event):
region = wid.GetWindowPort().visRgn
if Qd.EmptyRgn(region):
return
Qd.EraseRgn(region)
self.ted.WEUpdate(region)
self.updatescrollbars()
def do_postresize(self, width, height, window):
l, t, r, b = self.ted.WEGetViewRect()
vr = (l, t, l+width-15, t+height-15)
self.ted.WESetViewRect(vr)
self.wid.InvalWindowRect(vr)
ScrolledWindow.do_postresize(self, width, height, window)
def do_contentclick(self, local, modifiers, evt):
(what, message, when, where, modifiers) = evt
self.ted.WEClick(local, modifiers, when)
self.updatescrollbars()
self.parent.updatemenubar()
def do_char(self, ch, event):
self.ted.WESelView()
(what, message, when, where, modifiers) = event
self.ted.WEKey(ord(ch), modifiers)
self.changed = 1
self.updatescrollbars()
self.parent.updatemenubar()
def close(self):
if self.changed:
save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?'%self.name, 1)
if save > 0:
self.menu_save()
elif save < 0:
return
if self.parent.active == self:
self.parent.active = None
self.parent.updatemenubar()
del self.ted
del self.tedtexthandle
self.do_postclose()
def menu_save(self):
if not self.path:
self.menu_save_as()
return # Will call us recursively
## print 'Saving to ', self.path
dhandle = self.ted.WEGetText()
data = dhandle.data
fp = open(self.path, 'wb') # NOTE: wb, because data has CR for end-of-line
fp.write(data)
if data[-1] <> '\r': fp.write('\r')
fp.close()
self.changed = 0
def menu_save_as(self):
path = EasyDialogs.AskFileForSave(message='Save as:')
if not path: return
self.path = path
self.name = os.path.split(self.path)[-1]
self.wid.SetWTitle(self.name)
self.menu_save()
def menu_cut(self):
self.ted.WESelView()
if hasattr(Scrap, 'ZeroScrap'):
Scrap.ZeroScrap()
else:
Scrap.ClearCurrentScrap()
self.ted.WECut()
self.updatescrollbars()
self.parent.updatemenubar()
self.changed = 1
def menu_copy(self):
if hasattr(Scrap, 'ZeroScrap'):
Scrap.ZeroScrap()
else:
Scrap.ClearCurrentScrap()
self.ted.WECopy()
self.updatescrollbars()
self.parent.updatemenubar()
def menu_paste(self):
self.ted.WESelView()
self.ted.WEPaste()
self.updatescrollbars()
self.parent.updatemenubar()
self.changed = 1
def menu_clear(self):
self.ted.WESelView()
self.ted.WEDelete()
self.updatescrollbars()
self.parent.updatemenubar()
self.changed = 1
def menu_undo(self):
self.ted.WEUndo()
self.updatescrollbars()
self.parent.updatemenubar()
def have_selection(self):
start, stop = self.ted.WEGetSelection()
return start < stop
def can_paste(self):
return self.ted.WECanPaste()
def can_undo(self):
which, redo = self.ted.WEGetUndoInfo()
which = UNDOLABELS[which]
if which == None: return None
if redo:
return "Redo "+which
else:
return "Undo "+which
class Wed(Application):
def __init__(self):
Application.__init__(self)
self.num = 0
self.active = None
self.updatemenubar()
def makeusermenus(self):
self.filemenu = m = Menu(self.menubar, "File")
self.newitem = MenuItem(m, "New window", "N", self.open)
self.openitem = MenuItem(m, "Open...", "O", self.openfile)
self.closeitem = MenuItem(m, "Close", "W", self.closewin)
m.addseparator()
self.saveitem = MenuItem(m, "Save", "S", self.save)
self.saveasitem = MenuItem(m, "Save as...", "", self.saveas)
m.addseparator()
self.quititem = MenuItem(m, "Quit", "Q", self.quit)
self.editmenu = m = Menu(self.menubar, "Edit")
self.undoitem = MenuItem(m, "Undo", "Z", self.undo)
self.cutitem = MenuItem(m, "Cut", "X", self.cut)
self.copyitem = MenuItem(m, "Copy", "C", self.copy)
self.pasteitem = MenuItem(m, "Paste", "V", self.paste)
self.clearitem = MenuItem(m, "Clear", "", self.clear)
# Groups of items enabled together:
self.windowgroup = [self.closeitem, self.saveitem, self.saveasitem, self.editmenu]
self.focusgroup = [self.cutitem, self.copyitem, self.clearitem]
self.windowgroup_on = -1
self.focusgroup_on = -1
self.pastegroup_on = -1
self.undo_label = "never"
def updatemenubar(self):
changed = 0
on = (self.active <> None)
if on <> self.windowgroup_on:
for m in self.windowgroup:
m.enable(on)
self.windowgroup_on = on
changed = 1
if on:
# only if we have an edit menu
on = self.active.have_selection()
if on <> self.focusgroup_on:
for m in self.focusgroup:
m.enable(on)
self.focusgroup_on = on
changed = 1
on = self.active.can_paste()
if on <> self.pastegroup_on:
self.pasteitem.enable(on)
self.pastegroup_on = on
changed = 1
on = self.active.can_undo()
if on <> self.undo_label:
if on:
self.undoitem.enable(1)
self.undoitem.settext(on)
self.undo_label = on
else:
self.undoitem.settext("Nothing to undo")
self.undoitem.enable(0)
changed = 1
if changed:
DrawMenuBar()
#
# Apple menu
#
def do_about(self, id, item, window, event):
EasyDialogs.Message("A simple single-font text editor based on WASTE")
#
# File menu
#
def open(self, *args):
self._open(0)
def openfile(self, *args):
self._open(1)
def _open(self, askfile):
if askfile:
path = EasyDialogs.AskFileForOpen(typeList=('TEXT',))
if not path:
return
name = os.path.split(path)[-1]
try:
fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line
data = fp.read()
fp.close()
except IOError, arg:
EasyDialogs.Message("IOERROR: %r" % (arg,))
return
else:
path = None
name = "Untitled %d"%self.num
data = ''
w = WasteWindow(self)
w.open(path, name, data)
self.num = self.num + 1
def closewin(self, *args):
if self.active:
self.active.close()
else:
EasyDialogs.Message("No active window?")
def save(self, *args):
if self.active:
self.active.menu_save()
else:
EasyDialogs.Message("No active window?")
def saveas(self, *args):
if self.active:
self.active.menu_save_as()
else:
EasyDialogs.Message("No active window?")
def quit(self, *args):
for w in self._windows.values():
w.close()
if self._windows:
return
self._quit()
#
# Edit menu
#
def undo(self, *args):
if self.active:
self.active.menu_undo()
else:
EasyDialogs.Message("No active window?")
def cut(self, *args):
if self.active:
self.active.menu_cut()
else:
EasyDialogs.Message("No active window?")
def copy(self, *args):
if self.active:
self.active.menu_copy()
else:
EasyDialogs.Message("No active window?")
def paste(self, *args):
if self.active:
self.active.menu_paste()
else:
EasyDialogs.Message("No active window?")
def clear(self, *args):
if self.active:
self.active.menu_clear()
else:
EasyDialogs.Message("No active window?")
#
# Other stuff
#
def idle(self, event):
if self.active:
self.active.do_idle(event)
else:
Qd.SetCursor(Qd.GetQDGlobalsArrow())
def main():
App = Wed()
App.mainloop()
if __name__ == '__main__':
main()

File diff suppressed because it is too large Load Diff

View File

@ -1,152 +0,0 @@
# Scan an Apple header file, generating a Python file of generator calls.
import sys
import os
from bgenlocations import TOOLBOXDIR, BGENDIR
sys.path.append(BGENDIR)
from scantools import Scanner
WASTEDIR='/Users/jack/src/waste/C_C++ Headers/'
if not os.path.exists(WASTEDIR):
raise 'Error: not found: %s', WASTEDIR
OBJECT = "TEHandle"
SHORT = "waste"
OBJECT = "WEReference"
OBJECT2 = "WEObjectReference"
def main():
input = WASTEDIR + "WASTE.h"
output = SHORT + "gen.py"
defsoutput = os.path.join(os.path.split(TOOLBOXDIR)[0], "WASTEconst.py")
scanner = MyScanner(input, output, defsoutput)
scanner.scan()
## scanner.gentypetest(SHORT+"typetest.py")
scanner.close()
print "=== Testing definitions output code ==="
execfile(defsoutput, {}, {})
print "=== Done scanning and generating, now importing the generated code... ==="
exec "import " + SHORT + "support"
print "=== Done. It's up to you to compile it now! ==="
#class MyScanner(Scanner_PreUH3):
class MyScanner(Scanner):
def destination(self, type, name, arglist):
classname = "Function"
listname = "functions"
if arglist:
t, n, m = arglist[-1]
# This is non-functional today
if t == OBJECT and m == "InMode":
classname = "Method"
listname = "methods"
else:
t, n, m = arglist[0]
if t == OBJECT2 and m == "InMode":
classname = "Method2"
listname = "methods2"
return classname, listname
def writeinitialdefs(self):
self.defsfile.write("kPascalStackBased = None # workaround for header parsing\n")
self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
def makeblacklistnames(self):
return [
"WEDispose",
"WESetInfo", # Argument type unknown...
"WEGetInfo",
"WEVersion", # Unfortunately...
"WEPut", # XXXX TBD: needs array of flavortypes.
"WEGetOneAttribute", # XXXX TBD: output buffer
# Incompatible constant definitions
"weDoAutoScroll",
"weDoOutlineHilite",
"weDoReadOnly",
"weDoUndo",
"weDoIntCutAndPaste",
"weDoDragAndDrop",
"weDoInhibitRecal",
"weDoUseTempMem",
"weDoDrawOffscreen",
"weDoInhibitRedraw",
"weDoMonoStyled",
"weDoMultipleUndo",
"weDoNoKeyboardSync",
"weDoInhibitICSupport",
"weDoInhibitColor",
]
def makeblacklisttypes(self):
return [
"DragReference", # For now...
"UniversalProcPtr",
"WEFontIDToNameUPP",
"WEFontNameToIDUPP",
"WEClickLoopUPP",
"WEScrollUPP",
"WETSMPreUpdateUPP",
"WETSMPostUpdateUPP",
"WEPreTrackDragUPP",
"WETranslateDragUPP",
"WEHiliteDropAreaUPP",
"WEDrawTextUPP",
"WEDrawTSMHiliteUPP",
"WEPixelToCharUPP",
"WECharToPixelUPP",
"WELineBreakUPP",
"WEWordBreakUPP",
"WECharByteUPP",
"WECharTypeUPP",
"WEEraseUPP",
"WEFluxUPP",
"WENewObjectUPP",
"WEDisposeObjectUPP",
"WEDrawObjectUPP",
"WEClickObjectUPP",
"WEStreamObjectUPP",
"WEHoverObjectUPP",
"WERuler", # XXXX To be done
"WERuler_ptr", # ditto
"WEParaInfo", # XXXX To be done
"WEPrintSession", # XXXX To be done
"WEPrintOptions_ptr", # XXXX To be done
]
def makerepairinstructions(self):
return [
([("void_ptr", "*", "InMode"), ("SInt32", "*", "InMode")],
[("InBuffer", "*", "*")]),
# WEContinuousStyle
([("WEStyleMode", "ioMode", "OutMode"), ("TextStyle", "outTextStyle", "OutMode")],
[("WEStyleMode", "*", "InOutMode"), ("TextStyle", "*", "*")]),
# WECopyRange
([('Handle', 'outText', 'InMode'), ('StScrpHandle', 'outStyles', 'InMode'),
('WESoupHandle', 'outSoup', 'InMode')],
[('OptHandle', '*', '*'), ('OptStScrpHandle', '*', '*'),
('OptSoupHandle', '*', '*')]),
# WEInsert
([('StScrpHandle', 'inStyles', 'InMode'), ('WESoupHandle', 'inSoup', 'InMode')],
[('OptStScrpHandle', '*', '*'), ('OptSoupHandle', '*', '*')]),
# WEGetObjectOwner
("WEGetObjectOwner",
[('WEReference', '*', 'ReturnMode')],
[('ExistingWEReference', '*', 'ReturnMode')]),
# WEFindParagraph
([("char_ptr", "inKey", "InMode")],
[("stringptr", "*", "*")]),
# WESetOneAttribute
([("void_ptr", "*", "InMode"), ("ByteCount", "*", "InMode")],
[("InBuffer", "*", "*")]),
]
if __name__ == "__main__":
main()

View File

@ -1,444 +0,0 @@
# This script generates a Python interface for an Apple Macintosh Manager.
# It uses the "bgen" package to generate C code.
# The function specifications are generated by scanning the mamager's header file,
# using the "scantools" package (customized for this particular manager).
import string
# Declarations that change for each manager
MACHEADERFILE = 'WASTE.h' # The Apple header file
MODNAME = 'waste' # The name of the module
OBJECTNAME = 'waste' # The basic name of the objects used here
KIND = 'Ptr' # Usually 'Ptr' or 'Handle'
# The following is *usually* unchanged but may still require tuning
MODPREFIX = MODNAME # The prefix for module-wide routines
OBJECTTYPE = "WEReference" # The C type used to represent them
OBJECTPREFIX = MODPREFIX + 'Obj' # The prefix for object methods
INPUTFILE = 'wastegen.py' # The file generated by the scanner
TYPETESTFILE = 'wastetypetest.py' # Another file generated by the scanner
OUTPUTFILE = "wastemodule.c" # The file generated by this program
from macsupport import *
# Create the type objects
WEReference = OpaqueByValueType("WEReference", "wasteObj")
ExistingWEReference = OpaqueByValueType("WEReference", "ExistingwasteObj")
WEObjectReference = OpaqueByValueType("WEObjectReference", "WEOObj")
StScrpHandle = OpaqueByValueType("StScrpHandle", "ResObj")
RgnHandle = OpaqueByValueType("RgnHandle", "ResObj")
EventModifiers = Type("EventModifiers", "H")
FlavorType = OSTypeType("FlavorType")
WESelector = OSTypeType("WESelector")
OptHandle = OpaqueByValueType("Handle", "OptResObj")
OptSoupHandle = OpaqueByValueType("WESoupHandle", "OptResObj")
OptStScrpHandle = OpaqueByValueType("StScrpHandle", "OptResObj")
WEStyleMode = Type("WEStyleMode", "H")
WERulerMode = Type("WERulerMode", "l")
WEActionKind = Type("WEActionKind", "h")
WEAlignment = Type("WEAlignment", "B")
WEEdge = Type("WEEdge", "B")
WEDirection = Type("WEDirection", "h")
WESoupHandle = OpaqueByValueType("WESoupHandle", "ResObj")
WEFontTableHandle = OpaqueByValueType("WEFontTableHandle", "ResObj")
WEFontTableHandle
WERunInfo = OpaqueType("WERunInfo", "RunInfo")
AppleEvent = OpaqueType('AppleEvent', 'AEDesc')
AppleEvent_ptr = OpaqueType('AppleEvent', 'AEDesc')
TextStyle = OpaqueType("TextStyle", "TextStyle")
TextStyle_ptr = TextStyle
LongPt = OpaqueType("LongPt", "LongPt")
LongPt_ptr = LongPt
LongRect = OpaqueType("LongRect", "LongRect")
LongRect_ptr = LongRect
TextEncodingVariant = Type("TextEncodingVariant", "l")
TextEncodingFormat = Type("TextEncodingFormat", "l")
includestuff = includestuff + """
#include <%s>""" % MACHEADERFILE + """
#include <WEObjectHandlers.h>
#include <WETabs.h>
/* Exported by Qdmodule.c: */
extern PyObject *QdRGB_New(RGBColor *);
extern int QdRGB_Convert(PyObject *, RGBColor *);
/* Exported by AEModule.c: */
extern PyObject *AEDesc_New(AppleEvent *);
extern int AEDesc_Convert(PyObject *, AppleEvent *);
/* Forward declaration */
static PyObject *WEOObj_New(WEObjectReference);
static PyObject *ExistingwasteObj_New(WEReference);
/*
** Parse/generate TextStyle records
*/
static PyObject *
TextStyle_New(TextStylePtr itself)
{
return Py_BuildValue("lllO&", (long)itself->tsFont, (long)itself->tsFace, (long)itself->tsSize, QdRGB_New,
&itself->tsColor);
}
static int
TextStyle_Convert(PyObject *v, TextStylePtr p_itself)
{
long font, face, size;
if( !PyArg_ParseTuple(v, "lllO&", &font, &face, &size, QdRGB_Convert, &p_itself->tsColor) )
return 0;
p_itself->tsFont = (short)font;
p_itself->tsFace = (Style)face;
p_itself->tsSize = (short)size;
return 1;
}
/*
** Parse/generate RunInfo records
*/
static PyObject *
RunInfo_New(WERunInfo *itself)
{
return Py_BuildValue("llhhO&O&", itself->runStart, itself->runEnd, itself->runHeight,
itself->runAscent, TextStyle_New, &itself->runStyle, WEOObj_New, itself->runObject);
}
/* Conversion of long points and rects */
int
LongRect_Convert(PyObject *v, LongRect *r)
{
return PyArg_Parse(v, "(llll)", &r->left, &r->top, &r->right, &r->bottom);
}
PyObject *
LongRect_New(LongRect *r)
{
return Py_BuildValue("(llll)", r->left, r->top, r->right, r->bottom);
}
int
LongPt_Convert(PyObject *v, LongPt *p)
{
return PyArg_Parse(v, "(ll)", &p->h, &p->v);
}
PyObject *
LongPt_New(LongPt *p)
{
return Py_BuildValue("(ll)", p->h, p->v);
}
/* Stuff for the callbacks: */
static PyObject *callbackdict;
WENewObjectUPP upp_new_handler;
WEDisposeObjectUPP upp_dispose_handler;
WEDrawObjectUPP upp_draw_handler;
WEClickObjectUPP upp_click_handler;
static OSErr
any_handler(WESelector what, WEObjectReference who, PyObject *args, PyObject **rv)
{
FlavorType tp;
PyObject *key, *func;
if ( args == NULL ) return errAECorruptData;
tp = WEGetObjectType(who);
if( (key=Py_BuildValue("O&O&", PyMac_BuildOSType, tp, PyMac_BuildOSType, what)) == NULL)
return errAECorruptData;
if( (func = PyDict_GetItem(callbackdict, key)) == NULL ) {
Py_DECREF(key);
return errAEHandlerNotFound;
}
Py_INCREF(func);
*rv = PyEval_CallObject(func, args);
Py_DECREF(func);
Py_DECREF(key);
if ( *rv == NULL ) {
PySys_WriteStderr("--Exception in callback: ");
PyErr_Print();
return errAEReplyNotArrived;
}
return 0;
}
static pascal OSErr
my_new_handler(Point *objectSize, WEObjectReference objref)
{
PyObject *args=NULL, *rv=NULL;
OSErr err;
args=Py_BuildValue("(O&)", WEOObj_New, objref);
err = any_handler(weNewHandler, objref, args, &rv);
if (!err) {
if (!PyMac_GetPoint(rv, objectSize) )
err = errAECoercionFail;
}
if ( args ) {
Py_DECREF(args);
}
if ( rv ) {
Py_DECREF(rv);
}
return err;
}
static pascal OSErr
my_dispose_handler(WEObjectReference objref)
{
PyObject *args=NULL, *rv=NULL;
OSErr err;
args=Py_BuildValue("(O&)", WEOObj_New, objref);
err = any_handler(weDisposeHandler, objref, args, &rv);
if ( args ) {
Py_DECREF(args);
}
if ( rv ) {
Py_DECREF(rv);
}
return err;
}
static pascal OSErr
my_draw_handler(const Rect *destRect, WEObjectReference objref)
{
PyObject *args=NULL, *rv=NULL;
OSErr err;
args=Py_BuildValue("O&O&", PyMac_BuildRect, destRect, WEOObj_New, objref);
err = any_handler(weDrawHandler, objref, args, &rv);
if ( args ) {
Py_DECREF(args);
}
if ( rv ) {
Py_DECREF(rv);
}
return err;
}
static pascal Boolean
my_click_handler(Point hitPt, EventModifiers modifiers,
unsigned long clickTime, WEObjectReference objref)
{
PyObject *args=NULL, *rv=NULL;
int retvalue;
OSErr err;
args=Py_BuildValue("O&llO&", PyMac_BuildPoint, hitPt,
(long)modifiers, (long)clickTime, WEOObj_New, objref);
err = any_handler(weClickHandler, objref, args, &rv);
if (!err)
retvalue = PyInt_AsLong(rv);
else
retvalue = 0;
if ( args ) {
Py_DECREF(args);
}
if ( rv ) {
Py_DECREF(rv);
}
return retvalue;
}
"""
finalstuff = finalstuff + """
/* Return the object corresponding to the window, or NULL */
PyObject *
ExistingwasteObj_New(w)
WEReference w;
{
PyObject *it = NULL;
if (w == NULL)
it = NULL;
else
WEGetInfo(weRefCon, (void *)&it, w);
if (it == NULL || ((wasteObject *)it)->ob_itself != w)
it = Py_None;
Py_INCREF(it);
return it;
}
"""
class WEMethodGenerator(OSErrMethodGenerator):
"""Similar to MethodGenerator, but has self as last argument"""
def parseArgumentList(self, args):
args, a0 = args[:-1], args[-1]
t0, n0, m0 = a0
if m0 != InMode:
raise ValueError, "method's 'self' must be 'InMode'"
self.itself = Variable(t0, "_self->ob_itself", SelfMode)
FunctionGenerator.parseArgumentList(self, args)
self.argumentList.append(self.itself)
class WEObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
def outputCheckNewArg(self):
Output("""if (itself == NULL) {
PyErr_SetString(waste_Error,"Cannot create null WE");
return NULL;
}""")
def outputInitStructMembers(self):
GlobalObjectDefinition.outputInitStructMembers(self)
Output("WESetInfo(weRefCon, (void *)&it, itself);")
def outputFreeIt(self, itselfname):
Output("WEDispose(%s);", itselfname)
class WEOObjectDefinition(PEP253Mixin, GlobalObjectDefinition):
def outputCheckNewArg(self):
Output("""if (itself == NULL) {
Py_INCREF(Py_None);
return Py_None;
}""")
variablestuff = """
callbackdict = PyDict_New();
if (callbackdict == NULL || PyDict_SetItemString(d, "callbacks", callbackdict) != 0)
return;
upp_new_handler = NewWENewObjectProc(my_new_handler);
upp_dispose_handler = NewWEDisposeObjectProc(my_dispose_handler);
upp_draw_handler = NewWEDrawObjectProc(my_draw_handler);
upp_click_handler = NewWEClickObjectProc(my_click_handler);
"""
# From here on it's basically all boiler plate...
# Test types used for existence
## execfile(TYPETESTFILE)
# Create the generator groups and link them
module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff, variablestuff)
object = WEObjectDefinition(OBJECTNAME, OBJECTPREFIX, OBJECTTYPE)
object2 = WEOObjectDefinition("WEO", "WEOObj", "WEObjectReference")
module.addobject(object2)
module.addobject(object)
# Create the generator classes used to populate the lists
Function = OSErrFunctionGenerator
Method = WEMethodGenerator
Method2 = OSErrMethodGenerator
# Create and populate the lists
functions = []
methods = []
methods2 = []
execfile(INPUTFILE)
# A function written by hand:
stdhandlers_body = """
OSErr err;
// install the sample object handlers for pictures and sounds
#define kTypePicture 'PICT'
#define kTypeSound 'snd '
if ( !PyArg_ParseTuple(_args, "") ) return NULL;
if ((err = WEInstallObjectHandler(kTypePicture, weNewHandler,
(UniversalProcPtr) NewWENewObjectProc(HandleNewPicture), NULL)) != noErr)
goto cleanup;
if ((err = WEInstallObjectHandler(kTypePicture, weDisposeHandler,
(UniversalProcPtr) NewWEDisposeObjectProc(HandleDisposePicture), NULL)) != noErr)
goto cleanup;
if ((err = WEInstallObjectHandler(kTypePicture, weDrawHandler,
(UniversalProcPtr) NewWEDrawObjectProc(HandleDrawPicture), NULL)) != noErr)
goto cleanup;
if ((err = WEInstallObjectHandler(kTypeSound, weNewHandler,
(UniversalProcPtr) NewWENewObjectProc(HandleNewSound), NULL)) != noErr)
goto cleanup;
if ((err = WEInstallObjectHandler(kTypeSound, weDrawHandler,
(UniversalProcPtr) NewWEDrawObjectProc(HandleDrawSound), NULL)) != noErr)
goto cleanup;
if ((err = WEInstallObjectHandler(kTypeSound, weClickHandler,
(UniversalProcPtr) NewWEClickObjectProc(HandleClickSound), NULL)) != noErr)
goto cleanup;
Py_INCREF(Py_None);
_res = Py_None;
return _res;
cleanup:
return PyMac_Error(err);
"""
inshandler_body = """
OSErr err;
FlavorType objectType;
WESelector selector;
PyObject *py_handler;
UniversalProcPtr handler;
WEReference we = NULL;
PyObject *key;
if ( !PyArg_ParseTuple(_args, "O&O&O|O&",
PyMac_GetOSType, &objectType,
PyMac_GetOSType, &selector,
&py_handler,
WEOObj_Convert, &we) ) return NULL;
if ( selector == weNewHandler ) handler = (UniversalProcPtr)upp_new_handler;
else if ( selector == weDisposeHandler ) handler = (UniversalProcPtr)upp_dispose_handler;
else if ( selector == weDrawHandler ) handler = (UniversalProcPtr)upp_draw_handler;
else if ( selector == weClickHandler ) handler = (UniversalProcPtr)upp_click_handler;
else return PyMac_Error(weUndefinedSelectorErr);
if ((key = Py_BuildValue("O&O&",
PyMac_BuildOSType, objectType,
PyMac_BuildOSType, selector)) == NULL )
return NULL;
PyDict_SetItem(callbackdict, key, py_handler);
err = WEInstallObjectHandler(objectType, selector, handler, we);
if ( err ) return PyMac_Error(err);
Py_INCREF(Py_None);
_res = Py_None;
return _res;
"""
stdhand = ManualGenerator("STDObjectHandlers", stdhandlers_body)
inshand = ManualGenerator("WEInstallObjectHandler", inshandler_body)
# Tab hook handlers. Could be parsed from WETabs.h, but this is just as simple.
f = Method(OSErr, 'WEInstallTabHooks', (WEReference, 'we', InMode))
methods.append(f)
f = Method(OSErr, 'WERemoveTabHooks', (WEReference, 'we', InMode))
methods.append(f)
f = Method(Boolean, 'WEIsTabHooks', (WEReference, 'we', InMode))
methods.append(f)
f = Method(SInt16, 'WEGetTabSize', (WEReference, 'we', InMode))
methods.append(f)
f = Method(OSErr, 'WESetTabSize', (SInt16, 'tabWidth', InMode), (WEReference, 'we', InMode))
methods.append(f)
# add the populated lists to the generator groups
# (in a different wordl the scan program would generate this)
for f in functions: module.add(f)
module.add(stdhand)
module.add(inshand)
for f in methods: object.add(f)
for f in methods2: object2.add(f)
# generate output (open the output file as late as possible)
SetOutputFileName(OUTPUTFILE)
module.generate()

View File

@ -1095,29 +1095,6 @@ class PyBuildExt(build_ext):
extra_link_args=['-framework', 'QuickTime', extra_link_args=['-framework', 'QuickTime',
'-framework', 'Carbon']) ) '-framework', 'Carbon']) )
# As there is no standardized place (yet) to put
# user-installed Mac libraries on OSX, we search for "waste"
# in parent directories of the Python source tree. You
# should put a symlink to your Waste installation in the
# same folder as your python source tree. Or modify the
# next few lines:-)
waste_incs = find_file("WASTE.h", [],
['../'*n + 'waste/C_C++ Headers' for n in (0,1,2,3,4)])
waste_libs = find_library_file(self.compiler, "WASTE", [],
["../"*n + "waste/Static Libraries" for n in (0,1,2,3,4)])
if waste_incs != None and waste_libs != None:
exts.append( Extension('waste',
['waste/wastemodule.c'] + [
os.path.join(srcdir, d) for d in
'Mac/Wastemods/WEObjectHandlers.c',
'Mac/Wastemods/WETabHooks.c',
'Mac/Wastemods/WETabs.c'
],
include_dirs = waste_incs + [os.path.join(srcdir, 'Mac/Wastemods')],
library_dirs = waste_libs,
libraries = ['WASTE'],
extra_link_args = ['-framework', 'Carbon'],
) )
self.extensions.extend(exts) self.extensions.extend(exts)