///////////////////////////////////////////////////////////////////////////////
-// Name: mac/dataobj.cpp
+// Name: src/mac/carbon/dataobj.cpp
// Purpose: implementation of wxDataObject class
// Author: Stefan Csomor
// Modified by:
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
-// ============================================================================
-// declarations
-// ============================================================================
-
-// ----------------------------------------------------------------------------
-// headers
-// ----------------------------------------------------------------------------
-
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#if wxUSE_DATAOBJ
+#include "wx/dataobj.h"
+
#ifndef WX_PRECOMP
-#include "wx/intl.h"
+ #include "wx/intl.h"
+ #include "wx/log.h"
+ #include "wx/dcmemory.h"
+ #include "wx/image.h"
#endif
-#include "wx/log.h"
-#include "wx/dataobj.h"
-#include "wx/dcmemory.h"
#include "wx/mstream.h"
-#include "wx/image.h"
#include "wx/metafile.h"
-#include "wx/mac/private.h"
-#ifndef __DARWIN__
-#include <Scrap.h>
+#include "wx/tokenzr.h"
+
+#include "wx/mac/uma.h"
+
+#ifdef __DARWIN__
+ #include <QuickTime/QuickTime.h>
#endif
-// ----------------------------------------------------------------------------
-// functions
-// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// wxDataFormat
m_format = 0;
}
-wxDataFormat::wxDataFormat( wxDataFormatId vType )
+wxDataFormat::wxDataFormat( wxDataFormatId vType )
{
- SetType(vType);
+ m_format = 0;
+ m_type = wxDF_INVALID;
+ SetType( vType );
}
-wxDataFormat::wxDataFormat( const wxChar* zId)
+wxDataFormat::wxDataFormat( const wxChar *zId )
{
- SetId(zId);
+ m_format = 0;
+ m_type = wxDF_INVALID;
+ SetId( zId );
}
-wxDataFormat::wxDataFormat( const wxString& rId)
+wxDataFormat::wxDataFormat( const wxString& rId )
{
- SetId(rId);
+ m_format = 0;
+ m_type = wxDF_INVALID;
+ SetId( rId );
}
-wxDataFormat::wxDataFormat( NativeFormat vFormat)
+wxDataFormat::wxDataFormat(const wxDataFormat& rFormat)
{
- SetId(vFormat);
+ if ( rFormat.m_format )
+ m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)rFormat.m_format);
+ else
+ m_format = 0;
+ m_type = rFormat.m_type;
+ m_id = rFormat.m_id;
}
-void wxDataFormat::SetType( wxDataFormatId Type )
+wxDataFormat::wxDataFormat( NativeFormat vFormat )
{
- m_type = Type;
+ m_format = 0;
+ m_type = wxDF_INVALID;
+ SetId( vFormat );
+}
- if (m_type == wxDF_TEXT )
- m_format = kScrapFlavorTypeText;
- else if (m_type == wxDF_UNICODETEXT )
- m_format = kScrapFlavorTypeUnicode ;
- else if (m_type == wxDF_BITMAP || m_type == wxDF_METAFILE )
- m_format = kScrapFlavorTypePicture;
- else if (m_type == wxDF_FILENAME)
- m_format = kDragFlavorTypeHFS ;
- else
+wxDataFormat::~wxDataFormat()
+{
+ if ( m_format != 0 )
{
- wxFAIL_MSG( wxT("invalid dataformat") );
+ CFRelease( (CFStringRef) m_format );
+ m_format = 0;
+ }
+}
+
+// in order to be correct for 10.3 we restrict to the available types there
+// http://developer.apple.com/qa/qa2005/qa1406.html
+// TODO : Use UTCoreTypes.h constants once we support 10.4+ only
- // this is '????' but it can't be used in the code because ??' is
- // parsed as a trigraph!
- m_format = 0x3f3f3f3f;
+wxDataFormat& wxDataFormat::operator=(const wxDataFormat& rFormat)
+{
+ if ( m_format != 0 )
+ {
+ CFRelease( (CFStringRef) m_format );
+ m_format = 0;
}
+ if ( rFormat.m_format )
+ m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)rFormat.m_format);
+ m_type = rFormat.m_type;
+ m_id = rFormat.m_id;
+ return *this;
}
-wxString wxDataFormat::GetId() const
+void wxDataFormat::SetType( wxDataFormatId dataType )
{
- wxCHECK_MSG( !IsStandard(), wxEmptyString ,
- wxT("name of predefined format cannot be retrieved") );
+ m_type = dataType;
+ if ( m_format != 0 )
+ {
+ CFRelease( (CFStringRef) m_format );
+ m_format = 0;
+ }
- return m_id ;
+ switch (m_type)
+ {
+ case wxDF_TEXT:
+ m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.plain-text") );
+ break;
+
+ case wxDF_UNICODETEXT:
+ m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.utf16-plain-text") );
+ break;
+
+ case wxDF_BITMAP:
+ m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.tiff") );
+ break;
+ case wxDF_METAFILE:
+ m_format = (long) CFStringCreateCopy( NULL, CFSTR("com.adobe.pdf") );
+ break;
+
+ case wxDF_FILENAME:
+ m_format = (long) CFStringCreateCopy( NULL, CFSTR("public.file-url") );
+ break;
+
+ default:
+ wxFAIL_MSG( wxT("invalid data format") );
+ break;
+ }
}
-void wxDataFormat::SetId( NativeFormat format )
+wxString wxDataFormat::GetId() const
{
- m_format = format;
+ return wxCFStringRef(wxCFRetain((CFStringRef)m_format)).AsString();
+}
- if (m_format == kScrapFlavorTypeText)
- m_type = wxDF_TEXT;
- else if (m_format == kScrapFlavorTypeUnicode )
+void wxDataFormat::SetId( NativeFormat format )
+{
+ if ( m_format != 0 )
+ {
+ CFRelease( (CFStringRef) m_format );
+ m_format = 0;
+ }
+ m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)format);
+ if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.utf16-plain-text") ) )
+ {
m_type = wxDF_UNICODETEXT;
- else if (m_format == kScrapFlavorTypePicture)
+ }
+ else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.plain-text") ) )
+ {
+ m_type = wxDF_TEXT;
+ }
+ else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.tiff") ) )
+ {
m_type = wxDF_BITMAP;
- else if (m_format == kDragFlavorTypeHFS )
+ }
+ else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("com.adobe.pdf") ) )
+ {
+ m_type = wxDF_METAFILE;
+ }
+ else if ( UTTypeConformsTo( (CFStringRef)format, CFSTR("public.file-url") ) )
+ {
m_type = wxDF_FILENAME;
- else
+ }
+ else
{
m_type = wxDF_PRIVATE;
- char text[5] ;
- strncpy( text , (char*) &format , 4 ) ;
- text[4] = 0 ;
- m_id = wxString::FromAscii( text ) ;
+ m_id = wxCFStringRef( (CFStringRef) CFRetain((CFStringRef) format )).AsString();
}
}
-void wxDataFormat::SetId( const wxChar* zId )
+void wxDataFormat::SetId( const wxString& zId )
{
m_type = wxDF_PRIVATE;
- m_id = zId ;
- m_format = 'WXPR' ;
+ m_id = zId;
+ if ( m_format != 0 )
+ {
+ CFRelease( (CFStringRef) m_format );
+ m_format = 0;
+ }
+ // since it is private, no need to conform to anything ...
+ m_format = (long) wxCFRetain( (CFStringRef) wxCFStringRef(m_id) );
}
-bool wxDataFormat::operator==(const wxDataFormat& format) const
+bool wxDataFormat::operator==(const wxDataFormat& format) const
{
- if ( IsStandard() || format.IsStandard() )
- {
- return ( format.m_type == m_type ) ;
- }
+ if (IsStandard() || format.IsStandard())
+ return (format.m_type == m_type);
else
- {
- return ( m_id == format.m_id ) ;
- }
+ return ( UTTypeConformsTo( (CFStringRef) m_format , (CFStringRef) format.m_format ) );
}
//-------------------------------------------------------------------------
{
}
-bool wxDataObject::IsSupportedFormat(
- const wxDataFormat& rFormat
-, Direction vDir
-) const
+bool wxDataObject::IsSupportedFormat( const wxDataFormat& rFormat, Direction vDir ) const
{
- size_t nFormatCount = GetFormatCount(vDir);
+ size_t nFormatCount = GetFormatCount( vDir );
+ bool found = false;
if (nFormatCount == 1)
{
- return rFormat == GetPreferredFormat();
+ found = (rFormat == GetPreferredFormat());
}
else
{
- wxDataFormat* pFormats = new wxDataFormat[nFormatCount];
- GetAllFormats( pFormats
- ,vDir
- );
+ wxDataFormat *pFormats = new wxDataFormat[nFormatCount];
+ GetAllFormats( pFormats, vDir );
- size_t n;
-
- for (n = 0; n < nFormatCount; n++)
+ for (size_t n = 0; n < nFormatCount; n++)
{
if (pFormats[n] == rFormat)
+ {
+ found = true;
break;
+ }
}
delete [] pFormats;
+ }
+
+ return found;
+}
- // found?
- return n < nFormatCount;
+void wxDataObject::AddToPasteboard( void * pb, int itemID )
+{
+ PasteboardRef pasteboard = (PasteboardRef) pb;
+ // get formats from wxDataObjects
+ wxDataFormat *array = new wxDataFormat[ GetFormatCount() ];
+ GetAllFormats( array );
+
+ for (size_t i = 0; i < GetFormatCount(); i++)
+ {
+ wxDataFormat thisFormat = array[ i ];
+
+ // 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 );
+ 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 ) )
+ {
+ int counter = 1 ;
+ if ( thisFormat.GetType() == wxDF_FILENAME )
+ {
+ // the data is D-normalized UTF8 strings of filenames delimited with \n
+ char *fname = strtok((char*) buf,"\n");
+ while (fname != NULL)
+ {
+ // translate the filepath into a fileurl and put that into the pasteobard
+ CFStringRef path = CFStringCreateWithBytes(NULL,(UInt8*)fname,strlen(fname),kCFStringEncodingUTF8,false);
+ CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path , kCFURLPOSIXPathStyle, false);
+ CFRelease(path);
+ CFDataRef data = CFURLCreateData(NULL,url,kCFStringEncodingUTF8,true);
+ CFRelease(url);
+ PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) counter,
+ (CFStringRef) thisFormat.GetFormatId() , data, kPasteboardFlavorNoFlags);
+ CFRelease( data );
+ counter++;
+ fname = strtok (NULL,"\n");
+ }
+
+ }
+ else
+ {
+ CFDataRef data = CFDataCreate( kCFAllocatorDefault, (UInt8*)buf, datasize );
+ if ( thisFormat.GetType() == wxDF_TEXT )
+ PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) itemID,
+ CFSTR("com.apple.traditional-mac-plain-text") , data, kPasteboardFlavorNoFlags);
+ else
+ PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) itemID,
+ (CFStringRef) thisFormat.GetFormatId() , data, kPasteboardFlavorNoFlags);
+ CFRelease( data );
+ }
+ }
+ free( buf );
+ }
}
+
+ delete [] array;
+}
+
+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 );
+
+ 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 = 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.length() > 0)
+ {
+ wxCharBuffer buf = filenamesPassed.fn_str();
+ SetData( wxDF_FILENAME, strlen( buf ), (const char*)buf );
+ transferred = true;
+ }
+ }
+ }
+ return transferred;
+}
+
+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;
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
#if wxUSE_UNICODE
-void wxTextDataObject::GetAllFormats(wxDataFormat *formats, wxDataObjectBase::Direction dir) const
+void wxTextDataObject::GetAllFormats(wxDataFormat *formats,
+ wxDataObjectBase::Direction WXUNUSED(dir)) const
{
*formats++ = wxDataFormat( wxDF_TEXT );
*formats = wxDataFormat( wxDF_UNICODETEXT );
}
-
#endif
// ----------------------------------------------------------------------------
// wxFileDataObject
// ----------------------------------------------------------------------------
-bool wxFileDataObject::GetDataHere(
- void* pBuf
-) const
+void wxFileDataObject::GetFileNames( wxCharBuffer &buf ) const
{
- wxString sFilenames;
+ wxString filenames;
for (size_t i = 0; i < m_filenames.GetCount(); i++)
{
- sFilenames += m_filenames[i];
- sFilenames += (wxChar)0;
+ filenames += m_filenames[i];
+ filenames += wxT('\n');
}
- memcpy(pBuf, sFilenames.mbc_str(), sFilenames.Len() + 1);
- return TRUE;
+ buf = filenames.fn_str();
}
-size_t wxFileDataObject::GetDataSize() const
+bool wxFileDataObject::GetDataHere( void *pBuf ) const
{
- size_t nRes = 0;
+ if (pBuf == NULL)
+ return false;
- for (size_t i = 0; i < m_filenames.GetCount(); i++)
- {
- nRes += m_filenames[i].Len();
- nRes += 1;
- }
+ wxCharBuffer buf;
+ size_t buffLength;
- return nRes + 1;
+ GetFileNames( buf );
+ buffLength = strlen( buf );
+ memcpy( pBuf, (const char*)buf, buffLength + 1 );
+
+ return true;
}
-bool wxFileDataObject::SetData(
- size_t WXUNUSED(nSize)
-, const void* pBuf
-)
+size_t wxFileDataObject::GetDataSize() const
{
- m_filenames.Empty();
+ wxCharBuffer buf;
+ size_t buffLength;
- // only add if this is not an empty string
- // we can therefore clear the list by just setting an empty string
- if ( (*(char*)pBuf) != 0 )
- AddFile(wxString::FromAscii((char*)pBuf));
+ GetFileNames( buf );
+ buffLength = strlen( buf );
+ // terminating 0
+ return buffLength + 1;
+}
+
+bool wxFileDataObject::SetData( size_t WXUNUSED(nSize), const void *pBuf )
+{
+ wxString filenames;
- return TRUE;
+#if wxUSE_UNICODE
+ filenames = wxString( (const char*)pBuf, *wxConvFileName );
+#else
+ filenames = wxString (wxConvLocal.cWC2WX(wxConvFileName->cMB2WC( (const char*)pBuf)));
+#endif
+
+ m_filenames = wxStringTokenize( filenames, wxT("\n"), wxTOKEN_STRTOK );
+
+ return true;
}
-void wxFileDataObject::AddFile(
- const wxString& rFilename
-)
+void wxFileDataObject::AddFile( const wxString& rFilename )
{
- m_filenames.Add(rFilename);
+ m_filenames.Add( rFilename );
}
// ----------------------------------------------------------------------------
Init();
}
-wxBitmapDataObject::wxBitmapDataObject(
- const wxBitmap& rBitmap
-)
-: wxBitmapDataObjectBase(rBitmap)
+wxBitmapDataObject::wxBitmapDataObject( const wxBitmap& rBitmap )
+: wxBitmapDataObjectBase( rBitmap )
{
Init();
- if ( m_bitmap.Ok() )
+
+ if (m_bitmap.Ok())
{
- m_pictHandle = m_bitmap.GetBitmapData()->GetPictHandle() ;
- m_pictCreated = false ;
+ SetBitmap( rBitmap );
}
}
Clear();
}
-void wxBitmapDataObject::SetBitmap(
- const wxBitmap& rBitmap
-)
+void wxBitmapDataObject::SetBitmap( const wxBitmap& rBitmap )
{
Clear();
- wxBitmapDataObjectBase::SetBitmap(rBitmap);
- if ( m_bitmap.Ok() )
+ wxBitmapDataObjectBase::SetBitmap( rBitmap );
+ if (m_bitmap.Ok())
{
- m_pictHandle = m_bitmap.GetBitmapData()->GetPictHandle() ;
- m_pictCreated = false ;
+ CGImageRef cgImageRef = (CGImageRef) m_bitmap.CreateCGImage();
+
+ CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, 0);
+ CGImageDestinationRef destination = CGImageDestinationCreateWithData( data , kUTTypeTIFF , 1 , NULL );
+ if ( destination )
+ {
+ CGImageDestinationAddImage( destination, cgImageRef, NULL );
+ CGImageDestinationFinalize( destination );
+ CFRelease( destination );
+ }
+ m_pictHandle = NewHandle(CFDataGetLength(data));
+ if ( m_pictHandle )
+ {
+ memcpy( *(Handle)m_pictHandle, (const char *)CFDataGetBytePtr(data), CFDataGetLength(data) );
+ }
+ CFRelease( data );
+
+ CGImageRelease(cgImageRef);
}
}
-void wxBitmapDataObject::Init()
-{
- m_pictHandle = NULL ;
- m_pictCreated = false ;
-}
+void wxBitmapDataObject::Init()
+{
+ m_pictHandle = NULL;
+ m_pictCreated = false;
+}
-void wxBitmapDataObject::Clear()
+void wxBitmapDataObject::Clear()
{
- if ( m_pictCreated && m_pictHandle )
+ if (m_pictHandle != NULL)
{
- KillPicture( (PicHandle) m_pictHandle ) ;
+ DisposeHandle( (Handle) m_pictHandle );
+ m_pictHandle = NULL;
}
- m_pictHandle = NULL ;
+ m_pictCreated = false;
}
-bool wxBitmapDataObject::GetDataHere(
- void* pBuf
-) const
+bool wxBitmapDataObject::GetDataHere( void *pBuf ) const
{
- if (!m_pictHandle)
+ if (m_pictHandle == NULL)
{
- wxFAIL_MSG(wxT("attempt to copy empty bitmap failed"));
- return FALSE;
+ wxFAIL_MSG( wxT("attempt to copy empty bitmap failed") );
+ return false;
}
- memcpy(pBuf, *(Handle)m_pictHandle, GetHandleSize((Handle)m_pictHandle));
- return TRUE;
+
+ if (pBuf == NULL)
+ return false;
+
+ memcpy( pBuf, *(Handle)m_pictHandle, GetHandleSize( (Handle)m_pictHandle ) );
+
+ return true;
}
size_t wxBitmapDataObject::GetDataSize() const
{
- return GetHandleSize((Handle)m_pictHandle) ;
+ if (m_pictHandle != NULL)
+ return GetHandleSize( (Handle)m_pictHandle );
+ else
+ return 0;
}
-bool wxBitmapDataObject::SetData(
- size_t nSize
-, const void* pBuf
-)
+Handle MacCreateDataReferenceHandle(Handle theDataHandle)
+{
+ Handle dataRef = NULL;
+ OSErr err = noErr;
+
+ // Create a data reference handle for our data.
+ err = PtrToHand( &theDataHandle, &dataRef, sizeof(Handle));
+
+ return dataRef;
+}
+
+bool wxBitmapDataObject::SetData( size_t nSize, const void *pBuf )
{
Clear();
- PicHandle picHandle = (PicHandle) NewHandle( nSize ) ;
- memcpy( *picHandle , pBuf , nSize ) ;
- m_pictHandle = picHandle ;
- // ownership is transferred to the bitmap
- m_pictCreated = false ;
- Rect frame = (**picHandle).picFrame ;
-
- wxMetafile mf ;
- mf.SetHMETAFILE( (WXHMETAFILE) m_pictHandle ) ;
- wxMemoryDC mdc ;
- m_bitmap.Create( frame.right - frame.left ,frame.bottom - frame.top ) ;
- mdc.SelectObject(m_bitmap ) ;
- mf.Play( &mdc ) ;
- mdc.SelectObject( wxNullBitmap ) ;
-
+
+ if ((pBuf == NULL) || (nSize == 0))
+ return false;
+
+ Handle picHandle = NewHandle( nSize );
+ memcpy( *picHandle, pBuf, nSize );
+ m_pictHandle = picHandle;
+ CGImageRef cgImageRef = 0;
+
+ CFDataRef data = CFDataCreateWithBytesNoCopy( kCFAllocatorDefault, (const UInt8*) pBuf, nSize, kCFAllocatorNull);
+ CGImageSourceRef source = CGImageSourceCreateWithData( data, NULL );
+ if ( source )
+ {
+ cgImageRef = CGImageSourceCreateImageAtIndex(source, 0, NULL);
+ }
+ CFRelease( source );
+ CFRelease( data );
+
+ if ( cgImageRef )
+ {
+ m_bitmap.Create( CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
+ CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
+ // since our context is upside down we dont use CGContextDrawImage
+ wxMacDrawCGImage( (CGContextRef) m_bitmap.GetHBITMAP() , &r, cgImageRef ) ;
+ CGImageRelease(cgImageRef);
+ cgImageRef = NULL;
+ }
+
return m_bitmap.Ok();
}
-#endif
\ No newline at end of file
+#endif