This is eText.Pasteboard.m in view mode; [Download] [Up]
{\rtf0\ansi{\fonttbl\f0\fmodern Courier;\f1\ftech Symbol;\f2\fmodern Ohlfs;}
\margl40
\margr40
{\colortbl;\red0\green0\blue0;}
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i0\ulnone\fs24\fc0\cf0 //ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\
//
\i
\b FILENAME
\b0 :
\b\i0 eText.Pasteboard.m\
\b0 //
\i
\b SUMMARY
\b0 :
\b\i0 Implementation of interactions between eText and Pasteboards
\b0 \
//
\b\i CATEGORY
\b0 :
\i0
\b Pasteboard
\b0 \
//
\b\i PROTOCOLS
\b0 :
\i0
\b None
\b0 \
//
\b\i INTERFACE
\b0 :
\i0
\b None
\b0 \
//
\b\i AUTHOR
\b0 :
\b\i0 Rohit Khare
\b0 \
//
\b\i COPYRIGHT
\b0 :
\f1\i0 Ó
\f0\b 1993,94 California Institute of Technology, eText Project\
\b0 //ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\
//
\b\i Implementation Comments
\b0\i0 \
// All actions should get routed to read/write
\i Selection
\i0 To/From
\i Pasteboard
\i0 .\
//ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\
//
\b\i History
\b0\i0 \
// 02/12/95:
\b Changed Pasting policy to prefer creation of annotiations.
\b0 \
// 11/20/94:
\b Realized that most apps can't handle filename && ASCII, stupidly.
\b0 \
// 11/20/94:
\b Extended to use writeASCII on copying selections to PBoard.
\b0 \
// 10/31/94:
\b Added detectors for smartPaste.
\b0 \
// 10/17/94:
\b Cleaned up for eText5.
\b0 \
// 08/05/94:
\b Completely Rearchitected for 5.0. RK
\b0 \
//ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\
//
\b Imported Interfaces
\b0 \
//\
#import "
\b eText.Pasteboard.h
\b0 "\
\
#define
\b eTETFPboardType
\b0 NXUniqueString("
\b eText ETF pasteboard type
\b0 ")\
\
\i @implementation eText(Pasteboard)\
\i0 //ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\
//
\b Centralized Selection Management
\b0 \
//\
-
\b readSelectionFromPasteboard
\b0 :pboard \{\
return [self
\b readSelectionFromPasteboard
\b0 :pboard
\b linked
\b0 :
\b NO
\b0 ];\}\
-
\b readSelectionFromPasteboard
\b0 :pboard
\b linked
\b0 :(
\b BOOL
\b0 )isLinked \{\
\b NXSelPt
\b0 a,b;\
\b NXStream
\b0 *
\b memstream
\b0 ;\
NXAtom
\b supportedTypes
\b0 [9];\
NXAtom
\b foundType
\b0 ;\
\
//
\i 1) is there a selection? what types do we have?\
\i0 [self
\b getSel
\b0 :&a :&b];\
if (!((a.
\b cp
\b0
\b >= 0
\b0 ) && [self
\b isEditable
\b0 ]))\
return
\b nil
\b0 ;\
\
//
\i All possible "Pasteable" types:
\i0 \
supportedTypes[0] =
\b eTETFPboardType
\b0 ;\
supportedTypes[1] =
\b NXRTFDPboardType
\b0 ;\
supportedTypes[2] =
\b NXRTFPboardType
\b0 ;\
supportedTypes[3] =
\b NXTabularTextPboardType
\b0 ;\
supportedTypes[4] =
\b NXAsciiPboardType
\b0 ;\
supportedTypes[5] =
\b NXColorPboardType
\b0 ;\
supportedTypes[6] =
\b NXFontPboardType
\b0 ;\
supportedTypes[7] =
\b NXRulerPboardType
\b0 ;\
supportedTypes[8] =
\b NXFilenamePboardType
\b0 ;\
supportedTypes[9] = NULL;\
\b foundType
\b0 = [pboard
\b findAvailableTypeFrom
\b0 :
\b supportedTypes
\b0 num:
\b 2
\b0 ];\
\
//
\i 2) If we found nothing, try creating an Annotation for it\
\i0 //
\i 2a) NEW POLICY: If we can create an annotation, && no etf, do it\
\i0 if (
\b !foundType &&
\b0 [etApp
\b annotationByPboard
\b0 :
\b pboard
\b0 ]) \{\
[self
\b insertAnnotation
\b0 : [[[etApp
\b annotationByPboard
\b0 :
\b pboard
\b0 ] alloc]\
\b initFromPboard
\b0 :
\b pboard
\b0
\b inDoc
\b0 :
\b etDoc
\b0
\b linked
\b0 :
\b isLinked
\b0 ]];\
\
\b foundType
\b0 = [pboard
\b findAvailableTypeFrom
\b0 :
\b supportedTypes
\b0 num:
\b 8
\b0 ];\
\
//
\i e) If we have filenames, parse them out and instantiate each one.
\i0 \
\b //
\i NOTE THAT THIS DOESN'T WORK YET!!!!!! FIX ME!\
\b0\i0 \} else if (foundType ==
\b NXFilenamePboardType
\b0 ) \{\
NXLogError("
\b eText tried to read an NXFilenamePboardType.
\b0 ");\
[self insertAnnotation: [[[etApp annotationByPboard:pboard] alloc]\
initFromPboard:pboard inDoc:etDoc linked:isLinked]];\
//
\i 3) do we have RTFD? This is a _very_ special case, and is mutex to ETF\
\i0 \} else if (foundType ==
\b NXRTFDPboardType
\b0 ) \{\
//
\b\i this is really gruesome code. Don't look
\b0\i0 .\
\b Text
\b0 *
\b rtfd
\b0 ;\
\b NXRect
\b0
\b rect
\b0 ;\
\b Class
\b0
\b oldHandler
\b0 ;\
\
//
\i unload the old \\NeXTGraphic handler
\i0 \
\b oldHandler
\b0 = [eText classForDirective:"
\b NeXTGraphic
\b0 "];\
//
\i And load in NeXT's crap. All cause they serialize to a private form.
\i0 \
[eText
\b registerDirective
\b0 :"
\b NeXTGraphic
\b0 " \
\b forClass
\b0 :[Text
\b graphicCellClass
\b0 ]];\
rect.origin.x = 0; rect.origin.y = 0;\
rect.size.height = MAXFLOAT; rect.size.width = MAXFLOAT;\
\b rtfd
\b0 = [[
\b Text
\b0 alloc]
\b initFrame
\b0 :&
\b rect
\b0 ]; //
\i NeXT's Text class
\i0 \
[rtfd
\b setMonoFont
\b0 :
\b NO
\b0 ];\
[rtfd
\b setGraphicsImportEnabled
\b0 :
\b YES
\b0 ];\
[rtfd
\b setSel
\b0 :0 :[rtfd
\b textLength
\b0 ]];\
[
\b rtfd
\b0
\b readSelectionFromPasteboard
\b0 :
\b pboard
\b0 ]; //
\i Text
\i0
\i groks RTFD
\i0 \
if ([rtfd textLength]) \{\
\b NXRTFDError
\b0
\b ret
\b0 ;\
\
\b ret
\b0 =[rtfd
\b saveRTFDTo
\b0 :"
\b /tmp/eTextRTFDConversionStoreFile.rtfd
\b0 "\
\b removeBackup
\b0 :YES
\b errorHandler
\b0 :nil];\
//
\i get that crappy NXGraphicCell code out of my kernel NOW!!!
\i0 \
rtfd = [rtfd
\b free
\b0 ];\
[eText
\b registerDirective
\b0 :"
\b NeXTGraphic
\b0 " \
\b forClass
\b0 :
\b oldHandler
\b0 ];\
\
if (ret ==
\b NX_RTFDErrorNone
\b0 ) \{\
NXAtom oldP,oldT; int start;\
\
//
\i now parse in the good stuff
\i0 \
//
\i temporarily set this doc's docInfoPath to tempName
\i0 \
\b oldP
\b0 = [[etDoc
\b docInfo
\b0 ]
\b docPath
\b0 ];\
\b oldT
\b0 = [[etDoc
\b docInfo
\b0 ]
\b docTitle
\b0 ];\
start = sp0.cp;\
[[etDoc
\b docInfo
\b0 ]\
\b setDocPath
\b0 :"
\b /tmp/eTextRTFDConversionStoreFile.rtfd
\b0 "];\
\
//
\i issue a read for the "RTF" part of the data
\i0 \
[self
\b undoSelChange
\b0 :"
\b Paste RTFD
\b0 "];\
[
\b super
\b0
\b readSelectionFromPasteboard
\b0 :pboard];\
[self
\b undoAffectedRange
\b0 :start
\b to
\b0 :spN.cp];\
\
//
\i preserves the traditional semantics of pasting
\i0 \
//
\i since readSelection doesn't move the cursor
\i0 \
[self
\b setSel
\b0 :sp0.cp :sp0.cp];\
\
[[etDoc
\b docInfo
\b0 ]
\b setDocPath
\b0 :oldP];\
[[etDoc
\b docInfo
\b0 ]
\b setDocTitle
\b0 :oldT];\
\}\
\i // unfortunately, the objects created may want persistent\
// access to the files on disk, so we can't nuke them.\
// There's possibly a bug here relating to the use of a single,\
// shared ConversionStoreFile to hold all this shit.\
// Oh, for want of a OOfilesystem with autorelease!\
\i0 \}\
//
\i get that crappy NXGraphicCell code out of my kernel NOW!!!
\i0 \
[eText
\b registerDirective
\b0 :"
\b NeXTGraphic
\b0 " \
\b forClass
\b0 :
\b oldHandler
\b0 ];\
//
\i 4) do we have ETF or RTF (in that preference order?)\
\i0 \} else if ((foundType ==
\b eTETFPboardType
\b0 ) ||\
(foundType ==
\b NXRTFPboardType
\b0 ))\{\
//
\i OK, just paste in the ETF/RTF code
\i0 \
\b memstream
\b0 = [pboard
\b readTypeToStream
\b0 :
\b foundType
\b0 ];\
if (memstream) \{\
char buf[3]; int
\b smart
\b0 =0; //
\i Default is to assume dumbpaste
\i0 \
int start = sp0.cp;\
\
if ([self getSubstring:
\b buf
\b0 start:
\b spN
\b0 .cp length:
\b 1
\b0 ] != -1)\{\
\b smart
\b0 = (
\b strchr
\b0 (
\b\fc1\cf1 postSelSmartTable
\b0 , buf[0]
\fc0\cf0 ) ? 0 : 1);\
\}\
[self
\b undoSelChange
\b0 :"
\b Paste ETF/RTF
\b0 "];\
[self
\b replaceSelWithRichText
\b0 :
\b memstream
\b0 ]; //
\i subsumes ETF as well
\i0 .\
if (!(
\b smart
\b0 &&\
([self getSubstring:
\b buf
\b0 start:
\b spN
\b0 .cp length:
\b 1
\b0 ] != -1) &&\
(buf[0] == ' ')))\
\b smart = 0
\b0 ;\
[self
\b undoAffectedRange
\b0 :start
\b to
\b0 :(spN.cp +
\b smart
\b0 )];\
\b NXCloseMemory
\b0 (
\b memstream
\b0 , NX_FREEBUFFER);\
\}\
//
\i 5) do we have ASCII or Tabular Text?\
\i0 \}else if ((foundType ==
\b NXAsciiPboardType
\b0 ) ||\
(foundType ==
\b NXTabularTextPboardType
\b0 ))\{\
//
\i OK, just paste in the ASCII code
\i0 \
char *data; int len,
\b start
\b0 =
\b sp0.cp
\b0 ;\
\
[self
\b undoSelChange
\b0 :"
\b Paste PlainText
\b0 "];\
[pboard
\b readType
\b0 :
\b foundType
\b0 data:&data length:&len];\
[self
\b replaceSel
\b0 :data
\b length
\b0 :len]; //
\i subsumes TabText as well
\i0 .\
[pboard
\b deallocatePasteboardData
\b0 :data length:len];\
[self
\b undoAffectedRange
\b0 :start
\b to
\b0 :spN.cp];\
return self;\
//
\i 6) do we have Color data?\
\i0 \} else if (foundType ==
\b NXColorPboardType
\b0 ) \{\
[self
\b setSelColor
\b0 :
\b NXReadColorFromPasteboard
\b0 (pboard)];\
//
\i 7) do we have Font data?
\i0 \
//
\i 8) do we have Ruler data?\
\i0 \} else if ((foundType ==
\b NXFontPboardType
\b0 ) ||\
(foundType ==
\b NXRulerPboardType
\b0 )) \{\
//
\i this is kind of funky: we pull a little switcheroo on Text
\i0 \
id
\b targetPboard
\b0 ;\
char *
\b saveData
\b0 ,*
\b newData
\b0 ;\
int
\b saveLen
\b0 ,
\b newLen
\b0 ;\
NXAtom
\b targetType
\b0 [1];\
\
//
\i determine the targetPboard
\i0 \
if (foundType ==
\b NXRulerPboardType
\b0 ) \{\
targetPboard = [Pasteboard newName:
\b NXRulerPboard
\b0 ];\
*targetType =
\b NXRulerPboardType
\b0 ;\
\} else \{\
targetPboard = [Pasteboard newName:
\b NXFontPboard
\b0 ];\
*targetType =
\b NXFontPboardType
\b0 ;\
\}\
\
//
\i save data from targetPboard
\i0 \
[
\b targetPboard
\b0
\b readType
\b0 :*
\b targetType\
\b0 data:&saveData length:&saveLen];\
\
//
\i copy data from pboard to targetPboard
\i0 \
[
\b pboard
\b0
\b readType
\b0 :*
\b targetType\
\b0 data:&newData length:&newLen];\
[
\b targetPboard
\b0
\b declareTypes
\b0 :
\b targetType
\b0 num:1 owner:nil];\
[
\b targetPboard
\b0
\b writeType
\b0 :*
\b targetType
\b0 data:newData length:newLen];\
\
//
\i perform operation
\i0 \
if (foundType ==
\b NXRulerPboardType
\b0 ) \{\
[self
\b pasteRuler
\b0 :self];\
\} else \{\
[self
\b pasteFont
\b0 :self];\
\}\
\
//
\i restore data to targetPboard
\i0 \
[
\b targetPboard
\b0
\b declareTypes
\b0 :
\b targetType
\b0 num:1 owner:nil];\
[
\b targetPboard
\b0
\b writeType
\b0 :*
\b targetType
\b0 data:saveData length:saveLen];\
\
//
\i free both datas
\i0 \
[
\b targetPboard
\b0
\b deallocatePasteboardData
\b0 :
\b saveData
\b0 length:saveLen];\
[
\b pboard
\b0
\b deallocatePasteboardData
\b0 :
\b newData
\b0 length:newLen];\
\} \
return self;\
\}\
-
\b writeSelectionToPasteboard
\b0 :pboard \{\
\b NXSelPt
\b0 a,b;\
int pos,k,N;\
\b NXRun
\b0 *
\b curr
\b0 ;\
\b NXStream
\b0 *
\b memstream
\b0 ;\
NXAtom
\b supportedTypes
\b0 [5];\
\
//
\i 1) is there a selection of nonzero length?\
\i0 [self
\b getSel
\b0 :&a :&b];\
if (!((
\b a.cp >=0
\b0 ) && [self
\b isEditable
\b0 ] && (
\b b.cp != a.cp
\b0 ))) return
\b nil
\b0 ;\
\
//
\i 2) Initialize our pboard\
// after some extensive experimentation, calling writeSelection does\
// seem to work after all. The issue is that a real "copy" can have a\
// "NeXT smart paste pasteboard type" which wstopb cannot. Tests in\
// Edit reveal that this has no effect. Some keen user may find one though. \
\i0 supportedTypes[0] =
\b eTETFPboardType
\b0 ;\
supportedTypes[1] =
\b NXRTFPboardType
\b0 ;\
supportedTypes[2] =
\b NXAsciiPboardType
\b0 ;\
supportedTypes[
\b 3
\b0 ] =
\b NXFilenamePboardType
\b0 ;\
supportedTypes[
\b 3
\b0 ] =
\b NULL
\b0 ;\
supportedTypes[4] = NULL;\
[
\b pboard
\b0
\b declareTypes
\b0 :
\b supportedTypes
\b0 num:
\b\fs36 3
\b0\fs24 owner:
\b nil
\b0 ];\
\
\b memstream
\b0 =
\b NXOpenMemory
\b0 (NULL,0,NX_READWRITE);\
if (memstream) \{\
[self
\b writeETF
\b0 :
\b memstream
\b0
\b from
\b0 :sp0.cp
\b to
\b0 :spN.cp];\
[pboard
\b writeType
\b0 :
\b eTETFPboardType
\b0
\b fromStream
\b0 :
\b memstream
\b0 ];\
\b NXCloseMemory
\b0 (
\b memstream
\b0 , NX_FREEBUFFER);\
\}\
\
\b memstream
\b0 =
\b NXOpenMemory
\b0 (NULL,0,NX_READWRITE);\
if (memstream) \{\
[self
\b writeRTF
\b0 :memstream
\b from
\b0 :sp0.cp
\b to
\b0 :spN.cp];\
[pboard
\b writeType
\b0 :
\b NXRTFPboardType
\b0
\b fromStream
\b0 :
\b memstream
\b0 ];\
\b NXCloseMemory
\b0 (
\b memstream
\b0 , NX_FREEBUFFER);\
\}\
\
\b memstream
\b0 =
\b NXOpenMemory
\b0 (NULL,0,NX_READWRITE);\
if (memstream) \{\
[self
\b writeASCII
\b0 :memstream
\b from
\b0 :sp0.cp
\b to
\b0 :spN.cp];\
[pboard
\b writeType
\b0 :
\b NXAsciiPboardType
\b0
\b fromStream
\b0 :
\b memstream
\b0 ];\
\b NXCloseMemory
\b0 (
\b memstream
\b0 , NX_FREEBUFFER);\
\}\
\
\i // [pboard
\b writeType
\b0 :
\b NXFilenamePboardType
\b0
\b data
\b0 :[[etDoc
\b docInfo
\b0 ]
\b docPath
\b0 ]\
//
\b length
\b0 :
\b strlen
\b0 ([[etDoc
\b docInfo
\b0 ]
\b docPath
\b0 ])
\b +1
\b0 ];\
\i0 \
//
\i 3) are there Annotations in our selection?\
\i0 pos=0;\
N = theRuns->chunk.used/sizeof(NXRun);\
curr = theRuns->runs;\
for (k=0; ((k < N) && (b.cp > pos)); k++) \{\
if ((curr->info) && (a.cp <= pos) && \
[curr->
\b info
\b0
\b respondsTo
\b0 :@selector(
\b addToPboard:
\b0 )]) \
[curr->
\b info
\b0
\b addToPboard
\b0 :
\b pboard
\b0 ];\
\i // this is kosher because a second addType of the same type fails.\
// but a second writeType:of a different type might!\
\i0 pos += curr->chars;\
curr++;\
\}\
return self;\
\}\
- (
\b BOOL
\b0 )
\b writeSelectionToPasteboard
\b0 :pboard
\b types
\b0 :(
\b NXAtom
\b0 *)types\
\{\
id retVal;\
int
\b numTypes
\b0 =
\b 0
\b0 ;\
\
retVal=[self
\b writeSelectionToPasteboard
\b0 :pboard];\
//
\i now check to see that one of _types_ is on the pboard to return YES
\i0 \
while(types && types[numTypes])\{ \
\i
\i0 if (types[numTypes] ==
\b NXFilenamePboardType
\b0 ) \{\
if (retVal)\
[pboard
\b addTypes
\b0 :&(types[numTypes]) num:
\b 1
\b0 owner:
\b nil
\b0 ];\
else \
[pboard
\b declareTypes
\b0 :&(types[numTypes]) num:
\b 1
\b0 owner:
\b nil
\b0 ];\
[pboard
\b writeType
\b0 :
\b NXFilenamePboardType
\b0
\b data
\b0 :[[etDoc
\b docInfo
\b0 ]
\b docPath
\b0 ]\
\b length
\b0 :
\b strlen
\b0 ([[etDoc
\b docInfo
\b0 ]
\b docPath
\b0 ])
\b +1
\b0 ];\
\}\
\b numTypes++
\b0 ; //
\i Counter\
\i0 \}\
\b return
\b0 ([pboard
\b findAvailableTypeFrom
\b0 :
\b types
\b0
\b num
\b0 :
\b numTypes
\b0 ] ?
\b YES
\b0 :
\b NO
\b0 );\
\}\
\
//ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\
//
\b Dropping
\b0 \
//\
- (
\b NXDragOperation
\b0 )
\b draggingEntered
\b0 :(id <NXDraggingInfo>)sender \{\
return [self
\b draggingUpdated
\b0 :sender];\}\
- (
\b NXDragOperation
\b0 )
\b draggingUpdated
\b0 :(id <NXDraggingInfo>)sender \{\
NXSelPt a,b;\
NXPoint p;\
NXCoord l,r,t,bot;\
\b NXDragOperation
\b0
\b sourceMask
\b0 = [sender
\b draggingSourceOperationMask
\b0 ];\
\
//
\i Check for self-drags
\i0 \
[self
\b getMarginLeft
\b0 :&l right:&r top:&t bottom:&bot]; \
\b p
\b0 = [sender
\b draggingLocation
\b0 ];\
if ((
\b p.x
\b0 < (
\b l + SCROLLWIDTH
\b0 )) && ([sender
\b draggingSource
\b0 ] ==
\b self
\b0 ))\
return
\b NX_DragOperationNone
\b0 ;\
\
//
\i Check that the selection exists and isEditable
\i0 \
[self getSel:&a :&b];\
if (!((
\b a.cp >=0
\b0 ) && [self
\b isEditable
\b0 ]))\
return
\b NX_DragOperationNone
\b0 ;\
\
\i // It would be really nice to check whether the dragging Source is an\
// Annotation and is *within* the current selection (auto-destruct!)\
// Instead, it is the responsibility of each Annotation (see eTImage)\
// Also, consider laying the image in the window at the insertionPoint\
\i0 \
if (sourceMask &
\b NX_DragOperationLink
\b0 ) \{\
return NX_DragOperationLink;\
\} else if (sourceMask &
\b NX_DragOperationCopy
\b0 ) \{\
return NX_DragOperationCopy;\
\} else if (sourceMask &
\b NX_DragOperationGeneric
\b0 ) \{\
return NX_DragOperationGeneric;\
\}\
return
\b NX_DragOperationNone
\b0 ;\
\}\
- (
\b BOOL
\b0 )
\b prepareForDragOperation
\b0 :(id <NXDraggingInfo>)sender \{\
\i // Future Feature: slide to the insertion point? NXSelPt sp0?\
// Edit implementation: remove the temp image of *entered/exit\
\i0 return
\b YES
\b0 ;\
\}\
- (
\b BOOL
\b0 )
\b performDragOperation
\b0 :(id <NXDraggingInfo>)sender \{\
[self
\b readSelectionFromPasteboard
\b0 :[sender
\b draggingPasteboard
\b0 ] \
\b linked
\b0 :([sender
\b draggingSourceOperationMask
\b0 ] &
\b NX_DragOperationLink
\b0 )];\
return
\b YES
\b0 ;\
\}\
-
\b concludeDragOperation
\b0 :(id <NXDraggingInfo>)sender \{\
[[self
\b window
\b0 ]
\b makeKeyAndOrderFront
\b0 :self];\
return self;\
\}\
//ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\
//
\b Changing Fonts
\b0 \
//\
-
\b acceptFont
\b0 :(Font *)fontA
\b atPoint
\b0 :(NXPoint *)p \{\
id font;\
\
if ([fontA
\b matrix
\b0 ] !=
\b NX_FLIPPEDMATRIX
\b0 )\
\b font
\b0 = [Font
\b newFont
\b0 :[fontA name] \
size:[fontA pointSize] \
matrix:
\b NX_FLIPPEDMATRIX
\b0 ];\
else
\b font
\b0 = fontA;\
\
if (sp0.cp == spN.cp) //
\i "insert" a font at a flashing caret.\
\i0 [self
\b setSel
\b0 :sp0.cp :(sp0.cp+1)];\
[self
\b setSelFont
\b0 :
\b font
\b0 ]; //
\i undo is in setSelFont:
\i0 \
//
\i [self
\b setSel
\b0 :sp0.cp :spN.cp]; Remind Text object where the selection is!
\i0 \
return self;\
\}\
-
\b replaceFont
\b0 :(Font *)oldFontA
\b with
\b0 :(Font *)newFontA \{\
id oldFont, newFont;\
int k,N;\
NXRun *curr;\
\
//
\i First, check that the font matrices are in order
\i0 \
if ([oldFontA
\b matrix
\b0 ] !=
\b NX_FLIPPEDMATRIX
\b0 )\
\b oldFont
\b0 = [Font
\b newFont
\b0 :[
\b oldFontA
\b0 name] \
size:[
\b oldFontA
\b0 pointSize] \
matrix:
\b NX_FLIPPEDMATRIX
\b0 ];\
else
\b oldFont
\b0 = oldFontA;\
\
if ([newFontA
\b matrix
\b0 ] !=
\b NX_FLIPPEDMATRIX
\b0 )\
\b newFont
\b0 = [Font
\b newFont
\b0 :[
\b newFontA
\b0 name] \
size:[
\b newFontA
\b0 pointSize] \
matrix:
\b NX_FLIPPEDMATRIX
\b0 ];\
else
\b newFont
\b0 = newFontA;\
\
//
\i Freeze the display, Loop over all the NXRuns, recalc
\i0 \
[[self window]
\b disableFlushWindow
\b0 ];\
\b N
\b0 =
\b theRuns
\b0 ->chunk.
\b used
\b0 /sizeof(NXRun);\
\b curr
\b0 = theRuns->
\b runs
\b0 ;\
for (k=0;
\b k < N
\b0 ; k++) \{\
if (
\b curr->font
\b0 ==
\b oldFont
\b0 )
\b \
curr->font
\b0 =
\b newFont
\b0 ; \
curr++;\
\} \
[self
\b calcLine
\b0 ];\
[[[[self window]
\b display
\b0 ]
\b reenableFlushWindow
\b0 ]
\b\fc1\cf1 flushWindowIfNeeded
\b0\fc0\cf0 ];\
return self;\
\}\
\
//ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\
//
\b Edit Menu
\b0 \
//\
-
\b copy
\b0 :sender \{\
[self
\b writeSelectionToPasteboard
\b0 :[Pasteboard newName:
\b NXGeneralPboard
\b0 ]];\
return self;\
\}\
-
\b paste
\b0 :sender \{\
return [self
\b readSelectionFromPasteboard
\b0 :[Pasteboard newName:
\b NXGeneralPboard
\b0 ]];\
\}\
-
\b clear
\b0 :sender \{\
return [self
\b delete
\b0 :sender];\}\
-
\b delete
\b0 :sender \{\
id retval;\
if (
\b sp0
\b0 .cp
\b ==
\b0
\b spN
\b0 .cp) return
\b nil
\b0 ;\
[self
\b undoSelChange
\b0 :"
\b Delete Selection
\b0 "];\
retval = [super
\b delete
\b0 :sender];\
[self
\b undoAffectedRange
\b0 :
\b sp0
\b0 .cp
\b to
\b0 :
\b sp0
\b0 .cp];\
return retval;\
\}\
\
//ÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐÐ\
//
\b Services Menu
\b0 \
//\
-
\b validRequestorForSendType
\b0 :(NXAtom)typeSent\
\b andReturnType
\b0 :(NXAtom)typeReturned\
\{\
\i // OK, so sue me, we can't advertise that we send images and audio\
// by actually confirming it dynamically -- that's too damn expensive\
// Originally, we only checked if the sent type was one of:\
// NXFilenamePboardType,NXAsciiPboardType,NXRTFPboardType\
// Now, we just say what the hell and return self.\
// If the requestor actually wanted audio data and the selection is\
// text, tough luck. But this way, EqB's Edit Equation works...\
\i0 if (
\b typeReturned
\b0 && (
\b !
\b0 [self
\b isEditable
\b0 ])) return
\b nil
\b0 ;\
return
\b self
\b0 ;\
\}\
\
\i @end
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.