ok, first draft.
given
Protected Structure NSRange
location as Integer
length as Integer
End Structure
then this methods returns all the actual types in a clipboard (on macos only for now)
Public Function ItemTypes(extends c As Clipboard) as String()
#If Target64Bit
Dim SizeOfPointer As Integer = 8
#Else
Dim SizeOfPointer As Integer = 4
#EndIf
#If targetMacOS
' NSObject
Declare Function alloc Lib CocoaLib selector "alloc" (class_id As Ptr) As Ptr
' NSArray
Declare Function initWithArray Lib CocoaLib selector "initWithArray:copyItems:" (obj_id As Ptr, anArray As Ptr, flag As Boolean) As Ptr
Declare Function m_count Lib CocoaLib selector "count" ( obj As Ptr ) As UInteger
Declare Sub getObjects Lib CocoaLib selector "getObjects:range:" (obj_id As Ptr, aBuffer As Ptr, aRange As NSRange)
' NSPasteBoard
Declare Function NSClassFromString Lib CocoaLib (aClassName As CFStringRef) As Ptr
Declare Function generalPasteboard Lib CocoaLib selector "generalPasteboard" (obj_id As Ptr) As Ptr
Declare Function types Lib CocoaLib selector "types" (obj_id As Ptr) As Ptr
' NSString
Declare Function CFRetain Lib CarbonLib (cf As Ptr) As CFStringRef
Dim pasteboardRef As Ptr = generalPasteboard(NSClassFromString("NSPasteboard")) ' get actual general pasteboard
If pasteboardRef <> Nil Then
Dim anArrayRef,nsarray_id As Ptr
anArrayRef = types(pasteboardRef)
nsarray_id = initWithArray(alloc(NSClassFromString("NSArray")), anArrayRef, False)
Dim retArray() As String
Dim arrayRange As NSRange
arrayRange.location = 0
arrayRange.length = m_count( nsarray_id)
Dim m As New MemoryBlock(SizeOfPointer*arrayRange.length)
getObjects nsarray_id, m, arrayRange
Dim n As Integer = arrayRange.length-1
For i As Integer = 0 To n
retArray.append CFRetain((m.Ptr(i*SizeOfPointer)))
Next
Return retArray
End If
#EndIf
End Function
I was silent because I was creating an example (MacOS El Capitan) of what I wrote earlier.
Temporary result: I was able to store a RTF Text and a Sound (MP3) in the Clipboard.
I do not know why the Text and Picture are not there.
Returned data from the Script Editor:
{{«class RTF », 3174}, {«class MPG3», 34056}}
Now, it is time for me to dinner, then watch TV. With a bit of luck, I will finish that simple project by tomorrow.
Nota: I stored in a Folder four files; Text, RTF, MP3 and PNG. I read then in a button sequencially (by file name) and place the data in the CLipboard using Clip.AddRawData(Sound_MB, "public.mp3")
for example.
I think I do not use the correct public.<kind-name>
entries for Text (I use the LR value: "public.text"
) and Picture (I used: "public.image"
).
this second method still extends the clipboard, and let you get the data you want as a string, given the datatype present in the clipboard you provide. still only for macos, will do other platforms as I need it. if any of you add this windows or linux feature, please contribute to this thread ! thanks.
Public Function ItemData(extends c as Clipboard, aClipboardDataType as String) as String
#If targetMacOS
' NSData
Declare Function m_length Lib CocoaLib selector "length" (id As Ptr) As Integer
Declare Sub getBytes Lib CocoaLib selector "getBytes:length:" ( id As Ptr, buffer As Ptr, length As UInteger )
' NSPasteBoard
Declare Function NSClassFromString Lib CocoaLib (aClassName As CFStringRef) As Ptr
Declare Function generalPasteboard Lib CocoaLib selector "generalPasteboard" (obj_id As Ptr) As Ptr
Declare Function dataForType Lib CocoaLib selector "dataForType:" (obj_id As Ptr, type As CFStringRef) As Ptr
Dim pasteboardRef As Ptr = generalPasteboard(NSClassFromString("NSPasteboard")) ' get actual general pasteboard
If pasteboardRef <> Nil Then
Dim p As Ptr = dataForType ( pasteboardRef, aClipboardDataType)
Dim sLen As UInteger = m_length( p)
If sLen>0 Then
Dim m As New MemoryBlock( sLen )
getBytes p, m, sLen
Return m.StringValue( 0, sLen)
Else
Return ""
End If
End If
#EndIf
#If TargetWindows
Raise New PlatformNotSupportedException
#EndIf
#If TargetLinux
Raise New PlatformNotSupportedException
#EndIf
End Function
this above method now gives me the tiff data I want, just had to cast it to a picture using picture.fromdata.
and another small useful method for the same price …
Public Function ItemTypesCount(extends c As Clipboard) as Integer
Return c.ItemTypes.Ubound+1
End Function
Hi all,
the code to load RTF, TEXT, MP3 and PNG are meaningless, so are the code to store some data as String in MemoryBlock and so I do not copied them here.
I only shared the code to place these different resources in the Clipboard. The used UTI seems to be correct. The order of the lines below (lines that starts with: Clip.AddRawData
) change nothing (exept the order of appearance of the class in the Clipboard.
Only MP3 and RTF appears in the Clipboard and I do not know why / I was not able to change the result. Probably my error (or Xojo ?). I checked in the debugger, the used variables (below) hold the data, but for some unknow reason, they are lost.
[code]// Fills the Clipboard
Dim Clip As New Clipboard
Clip.AddRawData(Pict_MB, “public.image”) // Pict_MB is a MemoryBlock where I stored an image as String
Clip.AddRawData(Sound_MB, “public.mp3”) // Sound_MB is a MemoryBlock where I stored a sound as String
Clip.AddRawData(Text_RTF, “public.rtf”) // Text_RTF is a MemoryBlock where I stored a text RTF source as String
Clip.AddRawData(Text_Raw, “public.text”) // Text_Raw is a MemoryBlock where I stored a Raw text as String
// Export the Clipboard
Clip.Close[/code]