mirror of https://github.com/python/cpython
Drop Mac wrappers for the WASTE library.
This commit is contained in:
parent
f70b14fb30
commit
fb2a169ce3
|
@ -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}
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"><piovanel@kagi.com></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/"><http://www.boingo.com/waste/></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.
|
|
|
@ -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()
|
|
|
@ -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()
|
|
|
@ -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
|
@ -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()
|
|
|
@ -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()
|
|
23
setup.py
23
setup.py
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue