mirror of
https://github.com/fltk/fltk.git
synced 2026-06-02 15:46:52 +08:00
Implemented copy/paste with Cocoa's NSPasteboard instead of Core Foundation's Pasteboard Manager
which allows quite simpler code. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@9975 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
+23
-84
@@ -2694,7 +2694,6 @@ void Fl_X::q_end_image() {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
// Copy & Paste fltk implementation.
|
// Copy & Paste fltk implementation.
|
||||||
// Requires Mac OS 10.3 or later
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static void convert_crlf(char * s, size_t len)
|
static void convert_crlf(char * s, size_t len)
|
||||||
@@ -2704,27 +2703,20 @@ static void convert_crlf(char * s, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fltk 1.3 clipboard support constant definitions:
|
// fltk 1.3 clipboard support constant definitions:
|
||||||
const CFStringRef flavorNames[] = {
|
static const NSString *utf8_format = @"public.utf8-plain-text";
|
||||||
CFSTR("public.utf8-plain-text"),
|
|
||||||
CFSTR("public.utf16-plain-text"),
|
|
||||||
CFSTR("com.apple.traditional-mac-plain-text")
|
|
||||||
};
|
|
||||||
const CFStringEncoding encodings[] = {
|
|
||||||
kCFStringEncodingUTF8,
|
|
||||||
kCFStringEncodingUnicode,
|
|
||||||
kCFStringEncodingMacRoman};
|
|
||||||
const size_t handledFlavorsCount = sizeof(encodings)/sizeof(CFStringEncoding);
|
|
||||||
|
|
||||||
// clipboard variables definitions :
|
// clipboard variables definitions :
|
||||||
char *fl_selection_buffer[2];
|
char *fl_selection_buffer[2];
|
||||||
int fl_selection_length[2];
|
int fl_selection_length[2];
|
||||||
static int fl_selection_buffer_length[2];
|
static int fl_selection_buffer_length[2];
|
||||||
|
|
||||||
static PasteboardRef myPasteboard = 0;
|
static PasteboardRef allocatePasteboard(void)
|
||||||
static void allocatePasteboard() {
|
{
|
||||||
if (!myPasteboard)
|
PasteboardRef clip;
|
||||||
PasteboardCreate(kPasteboardClipboard, &myPasteboard);
|
PasteboardCreate(kPasteboardClipboard, &clip); // requires Mac OS 10.3
|
||||||
|
return clip;
|
||||||
}
|
}
|
||||||
|
static PasteboardRef myPasteboard = allocatePasteboard();
|
||||||
|
|
||||||
extern void fl_trigger_clipboard_notify(int source);
|
extern void fl_trigger_clipboard_notify(int source);
|
||||||
|
|
||||||
@@ -2736,8 +2728,7 @@ static void clipboard_check(void)
|
|||||||
{
|
{
|
||||||
PasteboardSyncFlags flags;
|
PasteboardSyncFlags flags;
|
||||||
|
|
||||||
allocatePasteboard();
|
flags = PasteboardSynchronize(myPasteboard); // requires Mac OS 10.3
|
||||||
flags = PasteboardSynchronize(myPasteboard);
|
|
||||||
|
|
||||||
if (!(flags & kPasteboardModified))
|
if (!(flags & kPasteboardModified))
|
||||||
return;
|
return;
|
||||||
@@ -2764,13 +2755,11 @@ void Fl::copy(const char *stuff, int len, int clipboard) {
|
|||||||
fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
|
fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
|
||||||
fl_selection_length[clipboard] = len;
|
fl_selection_length[clipboard] = len;
|
||||||
if (clipboard) {
|
if (clipboard) {
|
||||||
allocatePasteboard();
|
|
||||||
OSStatus err = PasteboardClear(myPasteboard);
|
|
||||||
if (err!=noErr) return; // clear did not work, maybe not owner of clipboard.
|
|
||||||
PasteboardSynchronize(myPasteboard);
|
|
||||||
CFDataRef text = CFDataCreate(kCFAllocatorDefault, (UInt8*)fl_selection_buffer[1], len);
|
CFDataRef text = CFDataCreate(kCFAllocatorDefault, (UInt8*)fl_selection_buffer[1], len);
|
||||||
if (text==NULL) return; // there was a pb creating the object, abort.
|
if (text==NULL) return; // there was a pb creating the object, abort.
|
||||||
err=PasteboardPutItemFlavor(myPasteboard, (PasteboardItemID)1, CFSTR("public.utf8-plain-text"), text, 0);
|
NSPasteboard *clip = [NSPasteboard generalPasteboard];
|
||||||
|
[clip declareTypes:[NSArray arrayWithObject:utf8_format] owner:nil];
|
||||||
|
[clip setData:(NSData*)text forType:utf8_format];
|
||||||
CFRelease(text);
|
CFRelease(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2780,72 +2769,22 @@ void Fl::paste(Fl_Widget &receiver, int clipboard) {
|
|||||||
if (clipboard) {
|
if (clipboard) {
|
||||||
// see if we own the selection, if not go get it:
|
// see if we own the selection, if not go get it:
|
||||||
fl_selection_length[1] = 0;
|
fl_selection_length[1] = 0;
|
||||||
OSStatus err = noErr;
|
|
||||||
Boolean found = false;
|
|
||||||
CFDataRef flavorData = NULL;
|
|
||||||
CFStringEncoding encoding = 0;
|
|
||||||
|
|
||||||
allocatePasteboard();
|
NSPasteboard *clip = [NSPasteboard generalPasteboard];
|
||||||
PasteboardSynchronize(myPasteboard);
|
NSString *found = [clip availableTypeFromArray:[NSArray arrayWithObject:utf8_format]];
|
||||||
ItemCount nFlavor = 0, i, j;
|
if (found) {
|
||||||
err = PasteboardGetItemCount(myPasteboard, &nFlavor);
|
NSData *data = [clip dataForType:found];
|
||||||
if (err==noErr) {
|
if (data) {
|
||||||
for (i=1; i<=nFlavor; i++) {
|
NSInteger len = [data length] + 1;
|
||||||
PasteboardItemID itemID = 0;
|
|
||||||
CFArrayRef flavorTypeArray = NULL;
|
|
||||||
found = false;
|
|
||||||
err = PasteboardGetItemIdentifier(myPasteboard, i, &itemID);
|
|
||||||
if (err!=noErr) continue;
|
|
||||||
err = PasteboardCopyItemFlavors(myPasteboard, itemID, &flavorTypeArray);
|
|
||||||
if (err!=noErr) {
|
|
||||||
if (flavorTypeArray) {CFRelease(flavorTypeArray); flavorTypeArray = NULL;}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
CFIndex flavorCount = CFArrayGetCount(flavorTypeArray);
|
|
||||||
for (j = 0; j < handledFlavorsCount; j++) {
|
|
||||||
for (CFIndex flavorIndex=0; flavorIndex<flavorCount; flavorIndex++) {
|
|
||||||
CFStringRef flavorType = (CFStringRef)CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex);
|
|
||||||
if (UTTypeConformsTo(flavorType, flavorNames[j])) {
|
|
||||||
err = PasteboardCopyItemFlavorData( myPasteboard, itemID, flavorNames[j], &flavorData );
|
|
||||||
if (err != noErr) continue;
|
|
||||||
encoding = encodings[j];
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found) break;
|
|
||||||
}
|
|
||||||
if (flavorTypeArray) {CFRelease(flavorTypeArray); flavorTypeArray = NULL;}
|
|
||||||
if (found) break;
|
|
||||||
}
|
|
||||||
if (found) {
|
|
||||||
// Textual data was found in the pasteboard. Copy it directly if it's UTF-8 encoded,
|
|
||||||
// and put it in a CFString if it's in another encoding.
|
|
||||||
CFStringRef mycfs;
|
|
||||||
CFIndex len = CFDataGetLength(flavorData);
|
|
||||||
if (encoding != kCFStringEncodingUTF8) {
|
|
||||||
mycfs = CFStringCreateWithBytes(NULL, CFDataGetBytePtr(flavorData), len, encoding, false);
|
|
||||||
CFRelease(flavorData);
|
|
||||||
len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(mycfs), kCFStringEncodingUTF8);
|
|
||||||
}
|
|
||||||
len++;
|
|
||||||
if ( len >= fl_selection_buffer_length[1] ) {
|
if ( len >= fl_selection_buffer_length[1] ) {
|
||||||
fl_selection_buffer_length[1] = len;
|
fl_selection_buffer_length[1] = len;
|
||||||
delete[] fl_selection_buffer[1];
|
delete[] fl_selection_buffer[1];
|
||||||
fl_selection_buffer[1] = new char[len];
|
fl_selection_buffer[1] = new char[len];
|
||||||
}
|
}
|
||||||
if (encoding == kCFStringEncodingUTF8) {
|
[data getBytes:fl_selection_buffer[1]];
|
||||||
memcpy(fl_selection_buffer[1], CFDataGetBytePtr(flavorData), len-1);
|
fl_selection_buffer[1][len - 1] = 0;
|
||||||
CFRelease(flavorData);
|
fl_selection_length[1] = len - 1;
|
||||||
fl_selection_buffer[1][len-1] = 0;
|
convert_crlf(fl_selection_buffer[1], len - 1); // turn all \r characters into \n:
|
||||||
}
|
|
||||||
else {
|
|
||||||
CFStringGetCString(mycfs, fl_selection_buffer[1], len, kCFStringEncodingUTF8);
|
|
||||||
CFRelease(mycfs);
|
|
||||||
}
|
|
||||||
len = strlen(fl_selection_buffer[1]);
|
|
||||||
fl_selection_length[1] = len;
|
|
||||||
convert_crlf(fl_selection_buffer[1],len); // turn all \r characters into \n:
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3326,8 +3265,8 @@ int Fl::dnd(void)
|
|||||||
NSAutoreleasePool *localPool;
|
NSAutoreleasePool *localPool;
|
||||||
localPool = [[NSAutoreleasePool alloc] init];
|
localPool = [[NSAutoreleasePool alloc] init];
|
||||||
NSPasteboard *mypasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
|
NSPasteboard *mypasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
|
||||||
[mypasteboard declareTypes:[NSArray arrayWithObjects:@"public.utf8-plain-text", nil] owner:nil];
|
[mypasteboard declareTypes:[NSArray arrayWithObject:utf8_format] owner:nil];
|
||||||
[mypasteboard setData:(NSData*)text forType:@"public.utf8-plain-text"];
|
[mypasteboard setData:(NSData*)text forType:utf8_format];
|
||||||
CFRelease(text);
|
CFRelease(text);
|
||||||
Fl_Widget *w = Fl::pushed();
|
Fl_Widget *w = Fl::pushed();
|
||||||
Fl_Window *win = w->top_window();
|
Fl_Window *win = w->top_window();
|
||||||
|
|||||||
Reference in New Issue
Block a user