bool wxDataObject::HasDataInPasteboard( void * pb ) { PasteboardRef pasteboard = (PasteboardRef) pb; size_t formatcount = GetFormatCount() + 1; wxDataFormat *array = new wxDataFormat[ formatcount ]; array[0] = GetPreferredFormat(); GetAllFormats( &array[1] ); ItemCount itemCount = 0; bool hasData = false; // we synchronize here once again, so we don't mind which flags get returned PasteboardSynchronize( pasteboard ); OSStatus err = PasteboardGetItemCount( pasteboard, &itemCount ); if ( err == noErr ) { for (size_t i = 0; !hasData && i < formatcount; i++) { // go through the data in our order of preference wxDataFormat dataFormat = array[ i ]; for( UInt32 itemIndex = 1; itemIndex <= itemCount && hasData == false ; itemIndex++ ) { PasteboardItemID itemID = 0; CFArrayRef flavorTypeArray = NULL; CFIndex flavorCount = 0; err = PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ); if ( err != noErr ) continue; err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray ); if ( err != noErr ) continue; flavorCount = CFArrayGetCount( flavorTypeArray ); for( CFIndex flavorIndex = 0; !hasData && flavorIndex < flavorCount ; flavorIndex++ ) { CFStringRef flavorType; flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, flavorIndex ); wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType ); if ( dataFormat == flavorFormat || dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT ) { hasData = true; } } CFRelease( flavorTypeArray ); } } } return hasData; }
bool wxDataObject::IsFormatInPasteboard( void * pb, const wxDataFormat &dataFormat ) { PasteboardRef pasteboard = (PasteboardRef) pb; bool hasData = false; OSStatus err = noErr; ItemCount itemCount; // we synchronize here once again, so we don't mind which flags get returned PasteboardSynchronize( pasteboard ); err = PasteboardGetItemCount( pasteboard, &itemCount ); if ( err == noErr ) { for( UInt32 itemIndex = 1; itemIndex <= itemCount && hasData == false ; itemIndex++ ) { PasteboardItemID itemID; CFArrayRef flavorTypeArray; CFIndex flavorCount; err = PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ); if ( err != noErr ) continue; err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray ); if ( err != noErr ) continue; flavorCount = CFArrayGetCount( flavorTypeArray ); for( CFIndex flavorIndex = 0; flavorIndex < flavorCount && hasData == false ; flavorIndex++ ) { CFStringRef flavorType; flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, flavorIndex ); wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType ); if ( dataFormat == flavorFormat ) hasData = true; else if ( dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT ) hasData = true; } CFRelease (flavorTypeArray); } } return hasData; }
bool wxDataObject::GetFromPasteboard( void * pb ) { PasteboardRef pasteboard = (PasteboardRef) pb; size_t formatcount = GetFormatCount() + 1; wxDataFormat *array = new wxDataFormat[ formatcount ]; array[0] = GetPreferredFormat(); GetAllFormats( &array[1] ); ItemCount itemCount = 0; wxString filenamesPassed; bool transferred = false; // we synchronize here once again, so we don't mind which flags get returned PasteboardSynchronize( pasteboard ); OSStatus err = PasteboardGetItemCount( pasteboard, &itemCount ); if ( err == noErr ) { for (size_t i = 0; !transferred && i < formatcount; i++) { // go through the data in our order of preference wxDataFormat dataFormat = array[ i ]; for( UInt32 itemIndex = 1; itemIndex <= itemCount && transferred == false ; itemIndex++ ) { PasteboardItemID itemID = 0; CFArrayRef flavorTypeArray = NULL; CFIndex flavorCount = 0; err = PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ); if ( err != noErr ) continue; err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray ); if ( err != noErr ) continue; flavorCount = CFArrayGetCount( flavorTypeArray ); for( CFIndex flavorIndex = 0; !transferred && flavorIndex < flavorCount ; flavorIndex++ ) { CFStringRef flavorType; CFDataRef flavorData; CFIndex flavorDataSize; flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, flavorIndex ); // avoid utf8 being treated closer to plain-text than unicode by forcing a conversion if ( UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text") ) ) { flavorType = CFSTR("public.utf16-plain-text"); } wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType ); if ( dataFormat == flavorFormat ) { err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType , &flavorData ); if ( err == noErr ) { flavorDataSize = CFDataGetLength( flavorData ); if (dataFormat.GetType() == wxDF_FILENAME ) { // revert the translation and decomposition to arrive at a proper utf8 string again CFURLRef url = CFURLCreateWithBytes( kCFAllocatorDefault, CFDataGetBytePtr( flavorData ), flavorDataSize, kCFStringEncodingUTF8, NULL ); CFStringRef cfString = CFURLCopyFileSystemPath( url, kCFURLPOSIXPathStyle ); CFRelease( url ); CFMutableStringRef cfMutableString = CFStringCreateMutableCopy(NULL, 0, cfString); CFRelease( cfString ); CFStringNormalize(cfMutableString,kCFStringNormalizationFormC); wxString path = wxMacCFStringHolder(cfMutableString).AsString(); if (!path.empty()) filenamesPassed += path + wxT("\n"); } else { // because some data implementation expect trailing a trailing NUL, we add some headroom void *buf = malloc( flavorDataSize + 4 ); if ( buf ) { memset( buf, 0, flavorDataSize + 4 ); memcpy( buf, CFDataGetBytePtr( flavorData ), flavorDataSize ); if (dataFormat.GetType() == wxDF_TEXT) wxMacConvertNewlines10To13( (char*) buf ); SetData( flavorFormat, flavorDataSize, buf ); transferred = true; free( buf ); } } CFRelease (flavorData); } } else if ( dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT ) { err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType, &flavorData ); if ( err == noErr ) { flavorDataSize = CFDataGetLength( flavorData ); void *asciibuf = malloc( flavorDataSize + 1 ); if ( asciibuf ) { memset( asciibuf, 0, flavorDataSize + 1 ); memcpy( asciibuf, CFDataGetBytePtr( flavorData ), flavorDataSize ); CFRelease (flavorData); SetData( wxDF_TEXT, flavorDataSize, asciibuf ); transferred = true; free( asciibuf ); } else CFRelease (flavorData); } } } CFRelease( flavorTypeArray ); } if (filenamesPassed.length() > 0) { wxCharBuffer buf = filenamesPassed.fn_str(); SetData( wxDF_FILENAME, strlen( buf ), (const char*)buf ); transferred = true; } } } return transferred; }
bool wxDataObject::GetFromPasteboard( void * pb ) { PasteboardRef pasteboard = (PasteboardRef) pb; size_t formatcount = GetFormatCount(wxDataObject::Set); wxDataFormat *array = new wxDataFormat[ formatcount ]; GetAllFormats(array, wxDataObject::Set); ItemCount itemCount = 0; wxString filenamesPassed; bool transferred = false; bool pastelocationset = false; // we synchronize here once again, so we don't mind which flags get returned PasteboardSynchronize( pasteboard ); OSStatus err = PasteboardGetItemCount( pasteboard, &itemCount ); if ( err == noErr ) { for (size_t i = 0; !transferred && i < formatcount; i++) { // go through the data in our order of preference wxDataFormat dataFormat = array[ i ]; for( UInt32 itemIndex = 1; itemIndex <= itemCount && transferred == false ; itemIndex++ ) { PasteboardItemID itemID = 0; CFArrayRef flavorTypeArray = NULL; CFIndex flavorCount = 0; err = PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ); if ( err != noErr ) continue; err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray ); if ( err != noErr ) continue; flavorCount = CFArrayGetCount( flavorTypeArray ); for( CFIndex flavorIndex = 0; !transferred && flavorIndex < flavorCount ; flavorIndex++ ) { CFStringRef flavorType; CFDataRef flavorData; CFIndex flavorDataSize; flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, flavorIndex ); wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType ); if ( dataFormat == flavorFormat ) { if ( UTTypeConformsTo( (CFStringRef)flavorType, kPasteboardTypeFileURLPromise) ) { if ( !pastelocationset ) { wxString tempdir = wxFileName::GetTempDir() + wxFILE_SEP_PATH + "wxtemp.XXXXXX"; char* result = mkdtemp((char*)tempdir.fn_str().data()); if (!result) continue; wxCFRef<CFURLRef> dest(CFURLCreateFromFileSystemRepresentation(NULL,(const UInt8*)result,strlen(result),true)); PasteboardSetPasteLocation(pasteboard, dest); pastelocationset = true; } } else if ( flavorFormat.GetType() != wxDF_PRIVATE ) { // indicate the expected format for the type, benefiting from native conversions eg utf8 -> utf16 flavorType = (CFStringRef) wxDataFormat( flavorFormat.GetType()).GetFormatId(); } err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType , &flavorData ); if ( err == noErr ) { flavorDataSize = CFDataGetLength( flavorData ); if (dataFormat.GetType() == wxDF_FILENAME ) { // revert the translation and decomposition to arrive at a proper utf8 string again CFURLRef url = CFURLCreateWithBytes( kCFAllocatorDefault, CFDataGetBytePtr( flavorData ), flavorDataSize, kCFStringEncodingUTF8, NULL ); CFStringRef cfString = CFURLCopyFileSystemPath( url, kCFURLPOSIXPathStyle ); CFRelease( url ); CFMutableStringRef cfMutableString = CFStringCreateMutableCopy(NULL, 0, cfString); CFRelease( cfString ); CFStringNormalize(cfMutableString,kCFStringNormalizationFormC); wxString path = wxCFStringRef(cfMutableString).AsString(); if (!path.empty()) filenamesPassed += path + wxT("\n"); } else { // because some data implementation expect trailing a trailing NUL, we add some headroom void *buf = malloc( flavorDataSize + 4 ); if ( buf ) { memset( buf, 0, flavorDataSize + 4 ); memcpy( buf, CFDataGetBytePtr( flavorData ), flavorDataSize ); if (dataFormat.GetType() == wxDF_TEXT) wxMacConvertNewlines10To13( (char*) buf ); SetData( flavorFormat, flavorDataSize, buf ); transferred = true; free( buf ); } } CFRelease (flavorData); } } else if ( dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT ) { err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType, &flavorData ); if ( err == noErr ) { flavorDataSize = CFDataGetLength( flavorData ); void *asciibuf = malloc( flavorDataSize + 1 ); if ( asciibuf ) { memset( asciibuf, 0, flavorDataSize + 1 ); memcpy( asciibuf, CFDataGetBytePtr( flavorData ), flavorDataSize ); CFRelease (flavorData); SetData( wxDF_TEXT, flavorDataSize, asciibuf ); transferred = true; free( asciibuf ); } else CFRelease (flavorData); } } } CFRelease( flavorTypeArray ); } if ( !filenamesPassed.empty() ) { wxCharBuffer buf = filenamesPassed.fn_str(); SetData( wxDF_FILENAME, strlen( buf ), (const char*)buf ); transferred = true; } } } return transferred; }