X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/489468feaa08b8f504735eecca522fb8d0f825d2..47e175a24f862aa8b7ca7dd4a2bb5957991e7f2d:/src/osx/carbon/dataobj.cpp diff --git a/src/osx/carbon/dataobj.cpp b/src/osx/carbon/dataobj.cpp index cdec68b05d..e02e880b1a 100644 --- a/src/osx/carbon/dataobj.cpp +++ b/src/osx/carbon/dataobj.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Name: src/mac/carbon/dataobj.cpp +// Name: src/osx/carbon/dataobj.cpp // Purpose: implementation of wxDataObject class // Author: Stefan Csomor // Modified by: @@ -26,14 +26,14 @@ #include "wx/mstream.h" #include "wx/metafile.h" #include "wx/tokenzr.h" +#include "wx/filename.h" -#include "wx/mac/uma.h" +#include "wx/osx/private.h" -#ifdef __DARWIN__ +#if wxOSX_USE_COCOA_OR_CARBON #include #endif - // ---------------------------------------------------------------------------- // wxDataFormat // ---------------------------------------------------------------------------- @@ -121,22 +121,26 @@ void wxDataFormat::SetType( wxDataFormatId dataType ) switch (m_type) { case wxDF_TEXT: - m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.plain-text") ); + m_format = (long) CFStringCreateCopy( NULL, kUTTypePlainText ); break; case wxDF_UNICODETEXT: - m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.utf16-plain-text") ); + m_format = (long) CFStringCreateCopy( NULL, kUTTypeUTF16PlainText ); + break; + + case wxDF_HTML: + m_format = (long) CFStringCreateCopy( NULL, kUTTypeHTML ); break; case wxDF_BITMAP: - m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.tiff") ); + m_format = (long) CFStringCreateCopy( NULL, kUTTypeTIFF ); break; case wxDF_METAFILE: - m_format = (long) CFStringCreateCopy( NULL, CFSTR("com.adobe.pdf") ); + m_format = (long) CFStringCreateCopy( NULL, kUTTypePDF ); break; case wxDF_FILENAME: - m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.file-url") ); + m_format = (long) CFStringCreateCopy( NULL, kUTTypeFileURL ); break; default: @@ -158,27 +162,40 @@ void wxDataFormat::SetId( NativeFormat format ) m_format = 0; } m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)format); - if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.utf16-plain-text") ) ) + if ( UTTypeConformsTo( (CFStringRef)format, kUTTypeHTML ) ) + { + m_type = wxDF_HTML; + } + if ( UTTypeConformsTo( (CFStringRef)format, kUTTypeUTF16PlainText ) ) { m_type = wxDF_UNICODETEXT; - } - else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.plain-text") ) ) + } + else if ( UTTypeConformsTo( (CFStringRef)format,kUTTypeUTF16ExternalPlainText ) ) + { + m_type = wxDF_UNICODETEXT; + } + else if ( UTTypeConformsTo( (CFStringRef)format,kUTTypeUTF8PlainText ) ) + { + m_type = wxDF_UNICODETEXT; + } + else if ( UTTypeConformsTo( (CFStringRef)format, kUTTypePlainText ) ) { m_type = wxDF_TEXT; } - else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.tiff") ) ) + else if ( UTTypeConformsTo( (CFStringRef)format, kUTTypeImage ) ) { m_type = wxDF_BITMAP; } - else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("com.adobe.pdf") ) ) + else if ( UTTypeConformsTo( (CFStringRef)format, kUTTypePDF ) ) { m_type = wxDF_METAFILE; } - else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.file-url") ) ) + else if ( UTTypeConformsTo( (CFStringRef)format, kUTTypeFileURL ) || + UTTypeConformsTo( (CFStringRef)format, kPasteboardTypeFileURLPromise)) { m_type = wxDF_FILENAME; } - else + else { m_type = wxDF_PRIVATE; m_id = wxCFStringRef( (CFStringRef) CFRetain((CFStringRef) format )).AsString(); @@ -253,19 +270,37 @@ void wxDataObject::AddToPasteboard( void * pb, int itemID ) for (size_t i = 0; i < GetFormatCount(); i++) { wxDataFormat thisFormat = array[ i ]; - - // add four bytes at the end for data objs like text that + + // add four bytes at the end for data objs like text that // have a datasize = strlen but still need a buffer for the // string including trailing zero - + size_t datasize = GetDataSize( thisFormat ); + if ( datasize == wxCONV_FAILED && thisFormat.GetType() == wxDF_TEXT) + { + // conversion to local text failed, so we must use unicode + // if wxDF_UNICODETEXT is already on the 'todo' list, skip this iteration + // otherwise force it + size_t j = 0; + for (j = 0; j < GetFormatCount(); j++) + { + if ( array[j].GetType() == wxDF_UNICODETEXT ) + break; + } + if ( j < GetFormatCount() ) + continue; + + thisFormat.SetType(wxDF_UNICODETEXT); + datasize = GetDataSize( thisFormat ); + } + size_t sz = datasize + 4; void* buf = malloc( sz ); if ( buf != NULL ) { // empty the buffer because in some case GetDataHere does not fill buf memset( buf, 0, sz ); - if ( GetDataHere( array[ i ], buf ) ) + if ( GetDataHere( thisFormat, buf ) ) { int counter = 1 ; if ( thisFormat.GetType() == wxDF_FILENAME ) @@ -286,7 +321,7 @@ void wxDataObject::AddToPasteboard( void * pb, int itemID ) counter++; fname = strtok (NULL,"\n"); } - + } else { @@ -325,24 +360,24 @@ bool wxDataObject::IsFormatInPasteboard( void * pb, const wxDataFormat &dataForm 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; @@ -359,13 +394,15 @@ bool wxDataObject::IsFormatInPasteboard( void * pb, const wxDataFormat &dataForm bool wxDataObject::GetFromPasteboard( void * pb ) { PasteboardRef pasteboard = (PasteboardRef) pb; - size_t formatcount = GetFormatCount() + 1; + + size_t formatcount = GetFormatCount(wxDataObject::Set); wxDataFormat *array = new wxDataFormat[ formatcount ]; - array[0] = GetPreferredFormat(); - GetAllFormats( &array[1] ); + 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 ); @@ -391,7 +428,7 @@ bool wxDataObject::GetFromPasteboard( void * pb ) err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray ); if ( err != noErr ) continue; - + flavorCount = CFArrayGetCount( flavorTypeArray ); for( CFIndex flavorIndex = 0; !transferred && flavorIndex < flavorCount ; flavorIndex++ ) @@ -399,21 +436,42 @@ bool wxDataObject::GetFromPasteboard( void * pb ) 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 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 + // 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 ); @@ -432,7 +490,7 @@ bool wxDataObject::GetFromPasteboard( void * pb ) { memset( buf, 0, flavorDataSize + 4 ); memcpy( buf, CFDataGetBytePtr( flavorData ), flavorDataSize ); - + if (dataFormat.GetType() == wxDF_TEXT) wxMacConvertNewlines10To13( (char*) buf ); SetData( flavorFormat, flavorDataSize, buf ); @@ -467,7 +525,7 @@ bool wxDataObject::GetFromPasteboard( void * pb ) } CFRelease( flavorTypeArray ); } - if (filenamesPassed.length() > 0) + if ( !filenamesPassed.empty() ) { wxCharBuffer buf = filenamesPassed.fn_str(); SetData( wxDF_FILENAME, strlen( buf ), (const char*)buf ); @@ -481,10 +539,9 @@ bool wxDataObject::GetFromPasteboard( void * pb ) bool wxDataObject::HasDataInPasteboard( void * pb ) { PasteboardRef pasteboard = (PasteboardRef) pb; - size_t formatcount = GetFormatCount() + 1; + size_t formatcount = GetFormatCount(wxDataObject::Set); wxDataFormat *array = new wxDataFormat[ formatcount ]; - array[0] = GetPreferredFormat(); - GetAllFormats( &array[1] ); + GetAllFormats(array, wxDataObject::Set); ItemCount itemCount = 0; bool hasData = false; @@ -512,20 +569,20 @@ bool wxDataObject::HasDataInPasteboard( void * pb ) 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 ) + + if ( dataFormat == flavorFormat || + (dataFormat.GetType() == wxDF_UNICODETEXT && flavorFormat.GetType() == wxDF_TEXT) ) { hasData = true; } @@ -537,6 +594,51 @@ bool wxDataObject::HasDataInPasteboard( void * pb ) return hasData; } +#if wxOSX_USE_COCOA + +void wxDataObject::AddSupportedTypes( void* cfarray) +{ + size_t nFormats = GetFormatCount(wxDataObject::Set); + wxDataFormat *array = new wxDataFormat[nFormats]; + GetAllFormats(array, wxDataObject::Set); + + for (size_t i = 0; i < nFormats; i++) + { + wxDataFormat dataFormat = array[ i ]; + + if ( dataFormat.GetType() == wxDF_UNICODETEXT || dataFormat.GetType() == wxDF_TEXT ) + { + CFArrayAppendValue((CFMutableArrayRef)cfarray, kUTTypeUTF16PlainText); + CFArrayAppendValue((CFMutableArrayRef)cfarray, kUTTypePlainText); + } + else if ( dataFormat.GetType() == wxDF_FILENAME ) + { + CFArrayAppendValue((CFMutableArrayRef)cfarray, kUTTypeFileURL); + CFArrayAppendValue((CFMutableArrayRef)cfarray, kPasteboardTypeFileURLPromise); + } + else if ( dataFormat.GetType() == wxDF_HTML ) + { + CFArrayAppendValue((CFMutableArrayRef)cfarray, kUTTypeHTML); + } + else if ( dataFormat.GetType() == wxDF_BITMAP ) + { + CFArrayAppendValue((CFMutableArrayRef)cfarray, kUTTypeTIFF); + CFArrayAppendValue((CFMutableArrayRef)cfarray, kUTTypePICT); + } + else if ( dataFormat.GetType() == wxDF_METAFILE ) + { + CFArrayAppendValue((CFMutableArrayRef)cfarray, kUTTypePDF); + } + else if ( dataFormat.GetType() == wxDF_PRIVATE ) + { + CFArrayAppendValue((CFMutableArrayRef)cfarray, (CFStringRef) dataFormat.GetFormatId()); + } + } + delete[] array; +} + +#endif + // ---------------------------------------------------------------------------- // wxTextDataObject // ---------------------------------------------------------------------------- @@ -545,8 +647,8 @@ bool wxDataObject::HasDataInPasteboard( void * pb ) void wxTextDataObject::GetAllFormats(wxDataFormat *formats, wxDataObjectBase::Direction WXUNUSED(dir)) const { - *formats++ = wxDataFormat( wxDF_TEXT ); - *formats = wxDataFormat( wxDF_UNICODETEXT ); + *formats++ = wxDataFormat(wxDF_UNICODETEXT); + *formats = wxDataFormat(wxDF_TEXT); } #endif @@ -627,9 +729,9 @@ wxBitmapDataObject::wxBitmapDataObject( const wxBitmap& rBitmap ) { Init(); - if (m_bitmap.Ok()) + if (m_bitmap.IsOk()) { - SetBitmap( rBitmap ); + SetBitmap( rBitmap ); } } @@ -642,7 +744,7 @@ void wxBitmapDataObject::SetBitmap( const wxBitmap& rBitmap ) { Clear(); wxBitmapDataObjectBase::SetBitmap( rBitmap ); - if (m_bitmap.Ok()) + if (m_bitmap.IsOk()) { CGImageRef cgImageRef = (CGImageRef) m_bitmap.CreateCGImage(); @@ -733,8 +835,8 @@ bool wxBitmapDataObject::SetData( size_t nSize, const void *pBuf ) if ( source ) { cgImageRef = CGImageSourceCreateImageAtIndex(source, 0, NULL); + CFRelease( source ); } - CFRelease( source ); CFRelease( data ); if ( cgImageRef ) @@ -747,7 +849,7 @@ bool wxBitmapDataObject::SetData( size_t nSize, const void *pBuf ) cgImageRef = NULL; } - return m_bitmap.Ok(); + return m_bitmap.IsOk(); } #endif