From f83577df451e492a419246a6f67ed26eefae1e5b Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Tue, 8 Oct 2019 06:32:44 +0200 Subject: [PATCH] Changing datatransfer implementation from CFPasteboard to NSPasteboard API (#1264) * changing datatransfer from CFPasteboard to NSPasteboard API * factoring and cleaning up * Switching back naming * missed file * getting wxCFStringRef to be independent of system headers * add unichar include * using wxCFStringRef in header * moving to private headers, change method name * adapting to lesser content in cfstring.h * Removing malloc/free usage * use wxScopedArray throughout * using wxMemoryBuffer instead of char[] * fixing nonprecomp headers * missing forward decl in non-precomp builds --- include/wx/defs.h | 2 +- include/wx/osx/core/cfstring.h | 27 +- include/wx/osx/core/private.h | 1 + include/wx/osx/core/private/strconv_cf.h | 18 + include/wx/osx/dataform.h | 21 +- include/wx/osx/dataobj.h | 20 +- include/wx/osx/dnd.h | 7 +- include/wx/osx/private.h | 1 + include/wx/osx/private/datatransfer.h | 113 +++++ src/common/encconv.cpp | 1 + src/common/filefn.cpp | 17 +- src/common/intl.cpp | 3 +- src/osx/carbon/clipbrd.cpp | 46 +- src/osx/carbon/dataobj.cpp | 607 ++++++++--------------- src/osx/carbon/metafile.cpp | 4 +- src/osx/cocoa/dnd.mm | 276 +++++++++-- src/osx/cocoa/window.mm | 84 ++-- src/osx/core/cfstring.cpp | 38 +- src/osx/core/sound.cpp | 4 +- src/osx/core/strconv_cf.cpp | 35 ++ src/osx/core/utilsexc_base.cpp | 9 +- src/osx/dnd_osx.cpp | 17 +- src/osx/fswatcher_fsevents.cpp | 2 + src/osx/utils_osx.cpp | 4 +- 24 files changed, 733 insertions(+), 624 deletions(-) create mode 100644 include/wx/osx/private/datatransfer.h diff --git a/include/wx/defs.h b/include/wx/defs.h index f349de2cb2..e1b95a68b4 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -2790,7 +2790,7 @@ typedef WX_UIImage WXImage; typedef WX_EAGLContext WXGLContext; typedef WX_NSString WXGLPixelFormat; typedef WX_UIWebView OSXWebViewPtr; -typedef WX_UIPasteboard OSXPasteboard; +typedef WX_UIPasteboard WXOSXPasteboard; #endif diff --git a/include/wx/osx/core/cfstring.h b/include/wx/osx/core/cfstring.h index b3e814ac5d..baaa8bf56d 100644 --- a/include/wx/osx/core/cfstring.h +++ b/include/wx/osx/core/cfstring.h @@ -12,8 +12,6 @@ #ifndef __WX_CFSTRINGHOLDER_H__ #define __WX_CFSTRINGHOLDER_H__ -#include - #include "wx/dlimpexp.h" #include "wx/fontenc.h" #include "wx/osx/core/cfref.h" @@ -44,7 +42,7 @@ public: wxFontEncoding encoding = wxFONTENCODING_DEFAULT) ; #ifdef __WXMAC__ - wxCFStringRef(NSString* ref) + wxCFStringRef(WX_NSString ref) : wxCFRef< CFStringRef >((CFStringRef) ref) { } @@ -69,29 +67,12 @@ public: static wxString AsString( CFStringRef ref, wxFontEncoding encoding = wxFONTENCODING_DEFAULT ) ; static wxString AsStringWithNormalizationFormC( CFStringRef ref, wxFontEncoding encoding = wxFONTENCODING_DEFAULT ) ; #ifdef __WXMAC__ - static wxString AsString( NSString* ref, wxFontEncoding encoding = wxFONTENCODING_DEFAULT ) ; - static wxString AsStringWithNormalizationFormC( NSString* ref, wxFontEncoding encoding = wxFONTENCODING_DEFAULT ) ; + static wxString AsString( WX_NSString ref, wxFontEncoding encoding = wxFONTENCODING_DEFAULT ) ; + static wxString AsStringWithNormalizationFormC( WX_NSString ref, wxFontEncoding encoding = wxFONTENCODING_DEFAULT ) ; - NSString* AsNSString() const { return (NSString*)(CFStringRef) *this; } + WX_NSString AsNSString() const { return (WX_NSString)(CFStringRef) *this; } #endif private: } ; -// corresponding class for holding UniChars (native unicode characters) - -class WXDLLIMPEXP_BASE wxMacUniCharBuffer -{ -public : - wxMacUniCharBuffer( const wxString &str ) ; - - ~wxMacUniCharBuffer() ; - - UniCharPtr GetBuffer() ; - - UniCharCount GetChars() ; - -private : - UniCharPtr m_ubuf ; - UniCharCount m_chars ; -}; #endif //__WXCFSTRINGHOLDER_H__ diff --git a/include/wx/osx/core/private.h b/include/wx/osx/core/private.h index d7088ae959..9984d8d8e4 100644 --- a/include/wx/osx/core/private.h +++ b/include/wx/osx/core/private.h @@ -51,6 +51,7 @@ wxString WXDLLIMPEXP_CORE wxMacMakeStringFromPascal( const unsigned char * from WXDLLIMPEXP_BASE wxString wxMacFSRefToPath( const FSRef *fsRef , CFStringRef additionalPathComponent = NULL ); WXDLLIMPEXP_BASE OSStatus wxMacPathToFSRef( const wxString&path , FSRef *fsRef ); WXDLLIMPEXP_BASE wxString wxMacHFSUniStrToString( ConstHFSUniStr255Param uniname ); +WXDLLIMPEXP_BASE CFURLRef wxOSXCreateURLFromFileSystemPath( const wxString& path); // keycode utils from app.cpp diff --git a/include/wx/osx/core/private/strconv_cf.h b/include/wx/osx/core/private/strconv_cf.h index d9b3eda989..e39a9218ca 100644 --- a/include/wx/osx/core/private/strconv_cf.h +++ b/include/wx/osx/core/private/strconv_cf.h @@ -13,6 +13,7 @@ #include #include +#include "wx/fontmap.h" // ============================================================================ // CoreFoundation conversion classes @@ -335,3 +336,20 @@ private: CFStringEncoding m_encoding ; }; +// corresponding class for holding UniChars (native unicode characters) + +class WXDLLIMPEXP_BASE wxMacUniCharBuffer +{ + public : + wxMacUniCharBuffer( const wxString &str ) ; + + ~wxMacUniCharBuffer() ; + + UniCharPtr GetBuffer() ; + + UniCharCount GetChars() ; + + private : + UniCharPtr m_ubuf ; + UniCharCount m_chars ; +}; diff --git a/include/wx/osx/dataform.h b/include/wx/osx/dataform.h index a9c7ba9e3c..b2cc65b242 100644 --- a/include/wx/osx/dataform.h +++ b/include/wx/osx/dataform.h @@ -11,10 +11,12 @@ #ifndef _WX_MAC_DATAFORM_H #define _WX_MAC_DATAFORM_H +#include "wx/osx/core/cfstring.h" + class WXDLLIMPEXP_CORE wxDataFormat { public: - typedef unsigned long NativeFormat; + typedef CFStringRef NativeFormat; wxDataFormat(); wxDataFormat(wxDataFormatId vType); @@ -41,11 +43,11 @@ public: // explicit and implicit conversions to NativeFormat which is one of // standard data types (implicit conversion is useful for preserving the // compatibility with old code) - NativeFormat GetFormatId() const { return m_format; } - operator NativeFormat() const { return m_format; } + const NativeFormat GetFormatId() const { return m_format; } + operator const NativeFormat() const { return m_format; } void SetId(NativeFormat format); - + // string ids are used for custom types - this SetId() must be used for // application-specific formats wxString GetId() const; @@ -54,15 +56,18 @@ public: // implementation wxDataFormatId GetType() const { return m_type; } void SetType( wxDataFormatId type ); + static NativeFormat GetFormatForType(wxDataFormatId type); // returns true if the format is one of those defined in wxDataFormatId bool IsStandard() const { return m_type > 0 && m_type < wxDF_PRIVATE; } + // adds all the native formats for this format to an array + void AddSupportedTypes(CFMutableArrayRef types) const; private: - wxDataFormatId m_type; - NativeFormat m_format; - // indicates the type in case of wxDF_PRIVATE : - wxString m_id ; + void ClearNativeFormat(); + + wxDataFormatId m_type; + wxCFStringRef m_format; }; #endif // _WX_MAC_DATAFORM_H diff --git a/include/wx/osx/dataobj.h b/include/wx/osx/dataobj.h index 86ab65d748..82f6913ed1 100644 --- a/include/wx/osx/dataobj.h +++ b/include/wx/osx/dataobj.h @@ -11,28 +11,24 @@ #ifndef _WX_MAC_DATAOBJ_H_ #define _WX_MAC_DATAOBJ_H_ -// ---------------------------------------------------------------------------- -// wxDataObject is the same as wxDataObjectBase under wxGTK -// ---------------------------------------------------------------------------- +class WXDLLIMPEXP_CORE wxOSXDataSink; +class WXDLLIMPEXP_CORE wxOSXDataSource; class WXDLLIMPEXP_CORE wxDataObject : public wxDataObjectBase { public: wxDataObject(); -#ifdef __DARWIN__ virtual ~wxDataObject() { } -#endif virtual bool IsSupportedFormat( const wxDataFormat& format, Direction dir = Get ) const; - void AddToPasteboard( void * pasteboardRef , wxIntPtr itemID ); - // returns true if the passed in format is present in the pasteboard - static bool IsFormatInPasteboard( void * pasteboardRef, const wxDataFormat &dataFormat ); - // returns true if any of the accepted formats of this dataobj is in the pasteboard - bool HasDataInPasteboard( void * pasteboardRef ); - bool GetFromPasteboard( void * pasteboardRef ); + + void WriteToSink(wxOSXDataSink *sink) const; + bool ReadFromSource(wxOSXDataSource *source); + bool CanReadFromSource(wxOSXDataSource *source) const; #if wxOSX_USE_COCOA - virtual void AddSupportedTypes( void* cfarray); + // adds all the native formats (in descending order of preference) this data object supports + virtual void AddSupportedTypes( CFMutableArrayRef cfarray) const; #endif }; diff --git a/include/wx/osx/dnd.h b/include/wx/osx/dnd.h index b81679d7dd..c3a26afec1 100644 --- a/include/wx/osx/dnd.h +++ b/include/wx/osx/dnd.h @@ -30,6 +30,8 @@ class WXDLLIMPEXP_FWD_CORE wxFileDropTarget; class WXDLLIMPEXP_FWD_CORE wxDropSource; +class WXDLLIMPEXP_FWD_CORE wxOSXDataSource; + // ---------------------------------------------------------------------------- // macros // ---------------------------------------------------------------------------- @@ -58,9 +60,10 @@ class WXDLLIMPEXP_CORE wxDropTarget: public wxDropTargetBase virtual wxDataFormat GetMatchingPair(); bool CurrentDragHasSupportedFormat() ; - void SetCurrentDragPasteboard( void* dragpasteboard ) { m_currentDragPasteboard = dragpasteboard ; } + + void SetCurrentDragSource( wxOSXDataSource* dragpasteboard ) { m_currentDragPasteboard = dragpasteboard ; } protected : - void* m_currentDragPasteboard ; + wxOSXDataSource* m_currentDragPasteboard ; }; //------------------------------------------------------------------------- diff --git a/include/wx/osx/private.h b/include/wx/osx/private.h index 23fd0025fb..a49a4166f8 100644 --- a/include/wx/osx/private.h +++ b/include/wx/osx/private.h @@ -2,6 +2,7 @@ #define _WX_PRIVATE_OSX_H_ #include "wx/osx/core/private.h" +#include "wx/osx/private/datatransfer.h" #if wxOSX_USE_IPHONE #include "wx/osx/iphone/private.h" diff --git a/include/wx/osx/private/datatransfer.h b/include/wx/osx/private/datatransfer.h new file mode 100644 index 0000000000..281164f32b --- /dev/null +++ b/include/wx/osx/private/datatransfer.h @@ -0,0 +1,113 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/osx/private/datatransfer.h +// Purpose: OS X specific data transfer implementation +// Author: Stefan Csomor +// Created: 2019-03-29 +// Copyright: (c) 2019 Stefan Csomor +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_OSX_PRIVATE_DATATRANSFER_H_ +#define _WX_OSX_PRIVATE_DATATRANSFER_H_ + +#include "wx/osx/private.h" +#include "wx/osx/dataform.h" + +class WXDLLIMPEXP_FWD_CORE wxDataObject; + +class WXDLLIMPEXP_CORE wxOSXDataSourceItem +{ +public: + virtual ~wxOSXDataSourceItem(); + + virtual wxDataFormat::NativeFormat AvailableType(CFArrayRef types) const = 0; + + virtual bool GetData( const wxDataFormat& dataFormat, wxMemoryBuffer& target) = 0; + + virtual bool GetData( wxDataFormat::NativeFormat type, wxMemoryBuffer& target) = 0; + + virtual CFDataRef DoGetData(wxDataFormat::NativeFormat type) const = 0; +}; + +class WXDLLIMPEXP_CORE wxOSXDataSource +{ +public: + // the number of source items + virtual size_t GetItemCount() const = 0; + + // get source item by index, needs to be deleted after use + virtual const wxOSXDataSourceItem* GetItem(size_t pos) const = 0; + + // returns true if there is any data in this source conforming to dataFormat + virtual bool IsSupported(const wxDataFormat &dataFormat); + + // returns true if there is any data in this source supported by dataobj + virtual bool IsSupported(const wxDataObject &dataobj); + + // returns true if there is any data in this source of types + virtual bool HasData(CFArrayRef types) const = 0; + +}; + +class WXDLLIMPEXP_CORE wxOSXDataSinkItem +{ +public: + virtual ~wxOSXDataSinkItem(); + + virtual void SetFilename(const wxString& filename); + + // translating from wx into native representation + virtual void SetData(const wxDataFormat& format, const void *buf, size_t size) = 0; + + // translating from wx into native representation + virtual void SetData(wxDataFormat::NativeFormat format, const void *buf, size_t size) = 0; + + // native implementation for setting data + virtual void DoSetData(wxDataFormat::NativeFormat format, CFDataRef data) = 0; +}; + + +class WXDLLIMPEXP_CORE wxOSXDataSink +{ +public: + // delete all created sink items + virtual void Clear() = 0; + + // create a new sink item + virtual wxOSXDataSinkItem* CreateItem() = 0; + + // flush the created sink items into the system sink representation + virtual void Flush() = 0 ; +}; + +class WXDLLIMPEXP_CORE wxOSXPasteboard : public wxOSXDataSink, public wxOSXDataSource +{ +public: + wxOSXPasteboard(OSXPasteboard native); + ~wxOSXPasteboard(); + + // sink methods + + virtual wxOSXDataSinkItem* CreateItem() wxOVERRIDE; + + void Clear() wxOVERRIDE; + + void Flush() wxOVERRIDE; + + // source methods + + virtual size_t GetItemCount() const wxOVERRIDE; + + virtual const wxOSXDataSourceItem* GetItem(size_t pos) const wxOVERRIDE; + + virtual bool HasData(CFArrayRef types) const wxOVERRIDE; + + static wxOSXPasteboard* GetGeneralClipboard(); +private: + void DeleteSinkItems(); + + OSXPasteboard m_pasteboard; + wxVector m_sinkItems; +}; + +#endif diff --git a/src/common/encconv.cpp b/src/common/encconv.cpp index f9f41ef9c2..a95c7f7208 100644 --- a/src/common/encconv.cpp +++ b/src/common/encconv.cpp @@ -27,6 +27,7 @@ #ifdef __WXMAC__ #include "wx/osx/core/cfstring.h" + #include #include wxUint16 gMacEncodings[wxFONTENCODING_MACMAX-wxFONTENCODING_MACMIN+1][128] ; diff --git a/src/common/filefn.cpp b/src/common/filefn.cpp index d2b88ca7c6..51ac27ade9 100644 --- a/src/common/filefn.cpp +++ b/src/common/filefn.cpp @@ -798,8 +798,6 @@ wxString wxPathOnly (const wxString& path) #if defined(__WXMAC__) && !defined(__WXOSX_IPHONE__) -#define kDefaultPathStyle kCFURLPOSIXPathStyle - wxString wxMacFSRefToPath( const FSRef *fsRef , CFStringRef additionalPathComponent ) { CFURLRef fullURLRef; @@ -814,7 +812,7 @@ wxString wxMacFSRefToPath( const FSRef *fsRef , CFStringRef additionalPathCompon additionalPathComponent,false); CFRelease( parentURLRef ) ; } - wxCFStringRef cfString( CFURLCopyFileSystemPath(fullURLRef, kDefaultPathStyle )); + wxCFStringRef cfString( CFURLCopyFileSystemPath(fullURLRef, kCFURLPOSIXPathStyle )); CFRelease( fullURLRef ) ; return wxCFStringRef::AsStringWithNormalizationFormC(cfString); @@ -823,15 +821,11 @@ wxString wxMacFSRefToPath( const FSRef *fsRef , CFStringRef additionalPathCompon OSStatus wxMacPathToFSRef( const wxString&path , FSRef *fsRef ) { OSStatus err = noErr ; - CFMutableStringRef cfMutableString = CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(path)); - CFStringNormalize(cfMutableString,kCFStringNormalizationFormD); - CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kDefaultPathStyle, false); - CFRelease( cfMutableString ); + wxCFRef url(wxOSXCreateURLFromFileSystemPath(path)); if ( NULL != url ) { if ( CFURLGetFSRef(url, fsRef) == false ) err = fnfErr ; - CFRelease( url ) ; } else { @@ -848,6 +842,13 @@ wxString wxMacHFSUniStrToString( ConstHFSUniStr255Param uniname ) return wxCFStringRef::AsStringWithNormalizationFormC(cfname); } +CFURLRef wxOSXCreateURLFromFileSystemPath( const wxString& path) +{ + wxCFRef cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(path))); + CFStringNormalize(cfMutableString,kCFStringNormalizationFormD); + return CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false); +} + #ifndef __LP64__ wxString wxMacFSSpec2MacFilename( const FSSpec *spec ) diff --git a/src/common/intl.cpp b/src/common/intl.cpp index 8fbd6b00ed..0ba14ae524 100644 --- a/src/common/intl.cpp +++ b/src/common/intl.cpp @@ -66,9 +66,10 @@ #if defined(__WXOSX__) #include "wx/osx/core/cfref.h" + #include "wx/osx/core/cfstring.h" #include #include - #include "wx/osx/core/cfstring.h" + #include #endif // ---------------------------------------------------------------------------- diff --git a/src/osx/carbon/clipbrd.cpp b/src/osx/carbon/clipbrd.cpp index 535f5e4cff..274e200e3e 100644 --- a/src/osx/carbon/clipbrd.cpp +++ b/src/osx/carbon/clipbrd.cpp @@ -25,6 +25,7 @@ #endif #include "wx/metafile.h" +#include "wx/scopedarray.h" #include "wx/osx/private.h" @@ -43,18 +44,10 @@ wxClipboard::wxClipboard() { m_open = false; m_data = NULL ; - PasteboardRef clipboard = 0; - OSStatus err = PasteboardCreate( kPasteboardClipboard, &clipboard ); - if (err != noErr) - { - wxLogSysError( wxT("Failed to create the clipboard.") ); - } - m_pasteboard.reset(clipboard); } wxClipboard::~wxClipboard() { - m_pasteboard.reset((PasteboardRef)0); delete m_data; } @@ -62,13 +55,7 @@ void wxClipboard::Clear() { wxDELETE(m_data); - wxCHECK_RET( m_pasteboard, "Clipboard creation failed." ); - - OSStatus err = PasteboardClear( m_pasteboard ); - if (err != noErr) - { - wxLogSysError( wxT("Failed to empty the clipboard.") ); - } + wxOSXPasteboard::GetGeneralClipboard()->Clear(); } bool wxClipboard::Flush() @@ -116,14 +103,10 @@ bool wxClipboard::AddData( wxDataObject *data ) // we can only store one wxDataObject Clear(); - PasteboardSyncFlags syncFlags = PasteboardSynchronize( m_pasteboard ); - wxCHECK_MSG( !(syncFlags&kPasteboardModified), false, wxT("clipboard modified after clear") ); - wxCHECK_MSG( (syncFlags&kPasteboardClientIsOwner), false, wxT("client couldn't own clipboard") ); + data->WriteToSink(wxOSXPasteboard::GetGeneralClipboard()); m_data = data; - data->AddToPasteboard( m_pasteboard, 1 ); - return true; } @@ -139,14 +122,15 @@ void wxClipboard::Close() wxDELETE(m_data); } -bool wxClipboard::IsSupported( const wxDataFormat &dataFormat ) +bool wxClipboard::IsSupported(const wxDataFormat &dataFormat) { wxLogTrace(TRACE_CLIPBOARD, wxT("Checking if format %s is available"), dataFormat.GetId().c_str()); if ( m_data ) return m_data->IsSupported( dataFormat ); - return wxDataObject::IsFormatInPasteboard( m_pasteboard, dataFormat ); + + return wxOSXPasteboard::GetGeneralClipboard()->IsSupported(dataFormat); } bool wxClipboard::GetData( wxDataObject& data ) @@ -156,10 +140,9 @@ bool wxClipboard::GetData( wxDataObject& data ) wxCHECK_MSG( m_open, false, wxT("clipboard not open") ); - size_t formatcount = data.GetFormatCount(wxDataObject::Set) + 1; - wxDataFormat *array = new wxDataFormat[ formatcount ]; - array[0] = data.GetPreferredFormat(wxDataObject::Set); - data.GetAllFormats( &array[1], wxDataObject::Set ); + size_t formatcount = data.GetFormatCount(wxDataObject::Set); + wxScopedArray array(formatcount); + data.GetAllFormats( array.get(), wxDataObject::Set ); bool transferred = false; @@ -179,10 +162,11 @@ bool wxClipboard::GetData( wxDataObject& data ) } else { - char *d = new char[ dataSize ]; - m_data->GetDataHere( format, (void*)d ); + wxMemoryBuffer mem(dataSize); + void *d = mem.GetWriteBuf(dataSize); + m_data->GetDataHere( format, d ); data.SetData( format, dataSize, d ); - delete [] d; + mem.UngetWriteBuf(dataSize); } } } @@ -191,11 +175,9 @@ bool wxClipboard::GetData( wxDataObject& data ) // get formats from wxDataObjects if ( !transferred ) { - transferred = data.GetFromPasteboard( m_pasteboard ) ; + transferred = data.ReadFromSource(wxOSXPasteboard::GetGeneralClipboard()); } - delete [] array; - return transferred; } diff --git a/src/osx/carbon/dataobj.cpp b/src/osx/carbon/dataobj.cpp index 591bb674f6..61e37b7e2b 100644 --- a/src/osx/carbon/dataobj.cpp +++ b/src/osx/carbon/dataobj.cpp @@ -14,6 +14,7 @@ #if wxUSE_DATAOBJ #include "wx/dataobj.h" +#include "wx/clipbrd.h" #ifndef WX_PRECOMP #include "wx/intl.h" @@ -30,6 +31,8 @@ #include "wx/osx/private.h" +static CFStringRef kUTTypeTraditionalMacText = CFSTR("com.apple.traditional-mac-plain-text"); + // ---------------------------------------------------------------------------- // wxDataFormat // ---------------------------------------------------------------------------- @@ -37,111 +40,114 @@ wxDataFormat::wxDataFormat() { m_type = wxDF_INVALID; - m_format = 0; } wxDataFormat::wxDataFormat( wxDataFormatId vType ) { - m_format = 0; m_type = wxDF_INVALID; SetType( vType ); } wxDataFormat::wxDataFormat( const wxChar *zId ) { - m_format = 0; m_type = wxDF_INVALID; SetId( zId ); } wxDataFormat::wxDataFormat( const wxString& rId ) { - m_format = 0; m_type = wxDF_INVALID; SetId( rId ); } wxDataFormat::wxDataFormat(const wxDataFormat& rFormat) { - if ( rFormat.m_format ) - m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)rFormat.m_format); - else - m_format = 0; + m_format = rFormat.m_format; m_type = rFormat.m_type; - m_id = rFormat.m_id; } -wxDataFormat::wxDataFormat( NativeFormat vFormat ) +wxDataFormat::wxDataFormat(NativeFormat format) { - m_format = 0; - m_type = wxDF_INVALID; - SetId( vFormat ); + SetId(format); } wxDataFormat::~wxDataFormat() { - if ( m_format != 0 ) - { - 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 - 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_format = rFormat.m_format; m_type = rFormat.m_type; - m_id = rFormat.m_id; return *this; } +wxDataFormat::NativeFormat wxDataFormat::GetFormatForType(wxDataFormatId type) +{ + wxDataFormat::NativeFormat f = NULL; + switch (type) + { + case wxDF_TEXT: + f = kUTTypeTraditionalMacText; + break; + + case wxDF_UNICODETEXT: + f = kUTTypeUTF16PlainText; + break; + + case wxDF_HTML: + f = kUTTypeHTML; + break; + + case wxDF_BITMAP: + f = kUTTypeTIFF; + break; + + case wxDF_METAFILE: + f = kUTTypePDF; + break; + + case wxDF_FILENAME: + f = kUTTypeFileURL; + break; + + default: + wxFAIL_MSG( wxS("unsupported data format") ); + break; + } + return f; +} + void wxDataFormat::SetType( wxDataFormatId dataType ) { m_type = dataType; - if ( m_format != 0 ) + m_format = GetFormatForType(dataType); +} + +void wxDataFormat::AddSupportedTypes(CFMutableArrayRef cfarray) const +{ + if ( GetType() == wxDF_PRIVATE ) { - CFRelease( (CFStringRef) m_format ); - m_format = 0; + CFArrayAppendValue(cfarray, GetFormatId()); } - - switch (m_type) + else { - case wxDF_TEXT: - m_format = (long) CFStringCreateCopy( NULL, kUTTypePlainText ); - break; - - case wxDF_UNICODETEXT: - 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, kUTTypeTIFF ); - break; - case wxDF_METAFILE: - m_format = (long) CFStringCreateCopy( NULL, kUTTypePDF ); - break; - - case wxDF_FILENAME: - m_format = (long) CFStringCreateCopy( NULL, kUTTypeFileURL ); - break; - - default: - wxFAIL_MSG( wxT("invalid data format") ); - break; + CFArrayAppendValue(cfarray, GetFormatForType(m_type)); + // add additional accepted types + switch (GetType()) + { + case wxDF_UNICODETEXT: + CFArrayAppendValue(cfarray, kUTTypeUTF8PlainText); + break; + case wxDF_FILENAME: + CFArrayAppendValue(cfarray, kPasteboardTypeFileURLPromise); + break; + case wxDF_BITMAP: + CFArrayAppendValue(cfarray, kUTTypePICT); + break; + default: + break; + } } } @@ -152,12 +158,7 @@ wxString wxDataFormat::GetId() const void wxDataFormat::SetId( NativeFormat format ) { - if ( m_format != 0 ) - { - CFRelease( (CFStringRef) m_format ); - m_format = 0; - } - m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)format); + m_format = format; if ( UTTypeConformsTo( (CFStringRef)format, kUTTypeHTML ) ) { m_type = wxDF_HTML; @@ -194,21 +195,14 @@ void wxDataFormat::SetId( NativeFormat format ) else { m_type = wxDF_PRIVATE; - m_id = wxCFStringRef( (CFStringRef) CFRetain((CFStringRef) format )).AsString(); } } void wxDataFormat::SetId( const wxString& zId ) { m_type = wxDF_PRIVATE; - 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) ); + m_format = wxCFStringRef(zId); } bool wxDataFormat::operator==(const wxDataFormat& format) const @@ -216,7 +210,7 @@ bool wxDataFormat::operator==(const wxDataFormat& format) const if (IsStandard() || format.IsStandard()) return (format.m_type == m_type); else - return ( UTTypeConformsTo( (CFStringRef) m_format , (CFStringRef) format.m_format ) ); + return ( UTTypeConformsTo( m_format , (CFStringRef) format.m_format ) ); } //------------------------------------------------------------------------- @@ -238,418 +232,247 @@ bool wxDataObject::IsSupportedFormat( const wxDataFormat& rFormat, Direction vDi } else { - wxDataFormat *pFormats = new wxDataFormat[nFormatCount]; - GetAllFormats( pFormats, vDir ); + wxScopedArray array(nFormatCount); + GetAllFormats( array.get(), vDir ); for (size_t n = 0; n < nFormatCount; n++) { - if (pFormats[n] == rFormat) + if (array[n] == rFormat) { found = true; break; } } - - delete [] pFormats; } return found; } -void wxDataObject::AddToPasteboard( void * pb, wxIntPtr itemID ) +void wxDataObject::WriteToSink(wxOSXDataSink * datatransfer) const { - PasteboardRef pasteboard = (PasteboardRef) pb; // get formats from wxDataObjects - wxDataFormat *array = new wxDataFormat[ GetFormatCount() ]; - GetAllFormats( array ); + wxScopedArray array(GetFormatCount()); + GetAllFormats( array.get() ); + + wxOSXDataSinkItem* sinkItem = NULL; 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 ); 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++) + bool hasUnicodeFormat = false; + for (size_t j = 0; j < GetFormatCount(); j++) { if ( array[j].GetType() == wxDF_UNICODETEXT ) + { + hasUnicodeFormat = true; break; + } } - if ( j < GetFormatCount() ) + if ( hasUnicodeFormat ) continue; - + thisFormat.SetType(wxDF_UNICODETEXT); datasize = GetDataSize( thisFormat ); } - + + // 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 sz = datasize + 4; - void* buf = malloc( sz ); + wxMemoryBuffer databuf( datasize+4 ); + void* buf = databuf.GetWriteBuf(datasize+4); if ( buf != NULL ) { // empty the buffer because in some case GetDataHere does not fill buf memset( buf, 0, sz ); - if ( GetDataHere( thisFormat, buf ) ) + bool datavalid = GetDataHere( thisFormat, buf ); + databuf.UngetWriteBuf(datasize); + if ( datavalid ) { + if ( !sinkItem ) + sinkItem = datatransfer->CreateItem(); + if ( thisFormat.GetType() == wxDF_FILENAME ) { - wxIntPtr counter = 1; - // 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"); - } + wxString filenames; + +#if wxUSE_UNICODE + filenames = wxString( (const char*)buf, *wxConvFileName ); +#else + filenames = wxString (wxConvLocal.cWC2WX(wxConvFileName->cMB2WC( (const char*)buf))); +#endif + wxArrayString files = wxStringTokenize( filenames, wxT("\n"), wxTOKEN_STRTOK ); + for ( size_t j = 0 ; j < files.GetCount(); ++j ) + { + sinkItem->SetFilename(files[j]); + // if there is another filepath, macOS needs another item + if ( j + 1 < files.GetCount() ) + sinkItem = datatransfer->CreateItem(); + } } 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 ); + sinkItem->SetData(thisFormat.GetFormatId(), databuf.GetData(), databuf.GetDataLen()); } } - free( buf ); } } - - delete [] array; } -bool wxDataObject::IsFormatInPasteboard( void * pb, const wxDataFormat &dataFormat ) +bool wxDataObject::ReadFromSource(wxOSXDataSource * source) { - 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; + bool transferred = false; size_t formatcount = GetFormatCount(wxDataObject::Set); wxScopedArray array(formatcount); GetAllFormats(array.get(), wxDataObject::Set); - - 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++) { - bool pastelocationset = false; - for (size_t i = 0; !transferred && i < formatcount; i++) + // go through the data in our order of preference + wxDataFormat dataFormat = array[i]; + + if (source->IsSupported(dataFormat)) { - // go through the data in our order of preference - wxDataFormat dataFormat = array[ i ]; - - for( UInt32 itemIndex = 1; itemIndex <= itemCount && transferred == false ; itemIndex++ ) + wxCFMutableArrayRef typesarray; + dataFormat.AddSupportedTypes(typesarray); + size_t itemCount = source->GetItemCount(); + + for ( size_t itemIndex = 0; itemIndex < itemCount && !transferred; ++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++ ) + wxScopedPtr sitem(source->GetItem(itemIndex)); + + wxDataFormat::NativeFormat nativeFormat = sitem->AvailableType(typesarray); + CFDataRef flavorData = sitem->DoGetData(nativeFormat); + if (flavorData) { - CFStringRef flavorType; - CFDataRef flavorData; - CFIndex flavorDataSize; - - flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, - flavorIndex ); - - wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType ); - - if ( dataFormat == flavorFormat ) + CFIndex flavorDataSize = CFDataGetLength(flavorData); + size_t sz = flavorDataSize + 4; + wxMemoryBuffer databuf( sz ); + void* buf = databuf.GetWriteBuf( sz ); + if (buf) { - if ( UTTypeConformsTo( (CFStringRef)flavorType, kPasteboardTypeFileURLPromise) ) + memset(buf, 0, sz); + memcpy(buf, CFDataGetBytePtr(flavorData), flavorDataSize); + databuf.UngetWriteBuf(flavorDataSize); + + if (nativeFormat != dataFormat.GetFormatId()) { - if ( !pastelocationset ) + // data is accepted but needs conversion + + // UTF8 data to our UTF16 + if (dataFormat.GetType() == wxDF_UNICODETEXT && CFStringCompare(nativeFormat, kUTTypeUTF8PlainText, 0) == 0) { - 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(); + wxMBConvUTF16 UTF16Converter; + + wxString s((char*)buf, wxConvUTF8, flavorDataSize); + + const wxCharBuffer cb = s.mb_str(UTF16Converter); + flavorDataSize = cb.length(); + sz = flavorDataSize + 2; + buf = databuf.GetWriteBuf(sz); + memset(buf, 0, sz); + memcpy(buf, cb.data(), flavorDataSize); + databuf.UngetWriteBuf(flavorDataSize); + } } - err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType , &flavorData ); - if ( err == noErr ) + if (dataFormat.GetType() == wxDF_FILENAME) { - flavorDataSize = CFDataGetLength( flavorData ); - if (dataFormat.GetType() == wxDF_FILENAME ) + // revert the translation and decomposition to arrive at a proper utf8 string again + + wxCFRef url = CFURLCreateWithBytes(kCFAllocatorDefault, (UInt8*) buf, flavorDataSize, kCFStringEncodingUTF8, NULL); + wxCFStringRef cfString = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); + + CFMutableStringRef cfMutableString = CFStringCreateMutableCopy(NULL, 0, cfString); + CFStringNormalize(cfMutableString, kCFStringNormalizationFormC); + // cfMutableString is released by the wxCFStringRef + wxString path = wxCFStringRef(cfMutableString).AsString(); + if (!path.empty()) + filenamesPassed += path + wxS("\n"); + + // if it's the last item, we set the wx data + if ( itemIndex + 1 == itemCount ) { - // revert the translation and decomposition to arrive at a proper utf8 string again - CFURLRef url = CFURLCreateWithBytes( kCFAllocatorDefault, CFDataGetBytePtr( flavorData ), flavorDataSize, kCFStringEncodingUTF8, NULL ); - if ( url ) - { - CFStringRef cfString = CFURLCopyFileSystemPath( url, kCFURLPOSIXPathStyle ); - CFRelease( url ); - if ( cfString ) - { - 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) - { - for (char* p = static_cast(buf); *p; p++) - if (*p == '\r') - *p = '\n'; - } - else if (dataFormat.GetType() == wxDF_UNICODETEXT) - { - for (wxChar16* p = static_cast(buf); *p; p++) - if (*p == '\r') - *p = '\n'; - } - 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 ); + wxCharBuffer filenamebuf = filenamesPassed.char_str(); + SetData(dataFormat, filenamebuf.length(), filenamebuf.data()); transferred = true; - free( asciibuf ); } - else - CFRelease (flavorData); + } + else + { + // because some data implementation expect trailing a trailing NUL, we add some headroom + + if (dataFormat.GetType() == wxDF_TEXT) + { + for (char* p = static_cast(buf); *p; p++) + if (*p == '\r') + *p = '\n'; + } + else if (dataFormat.GetType() == wxDF_UNICODETEXT) + { + for (wxChar16* p = static_cast(buf); *p; p++) + if (*p == '\r') + *p = '\n'; + } + SetData(dataFormat, flavorDataSize, buf); + // multiple items are not supported in wx, set flag to true + transferred = true; } } } - CFRelease( flavorTypeArray ); - } - if ( !filenamesPassed.empty() ) - { - wxCharBuffer buf = filenamesPassed.fn_str(); - SetData( wxDF_FILENAME, strlen( buf ), (const char*)buf ); - transferred = true; } } } return transferred; } -bool wxDataObject::HasDataInPasteboard( void * pb ) +bool wxDataObject::CanReadFromSource( wxOSXDataSource * source ) const { - PasteboardRef pasteboard = (PasteboardRef) pb; + bool hasData = false; + size_t formatcount = GetFormatCount(wxDataObject::Set); wxScopedArray array(formatcount); GetAllFormats(array.get(), wxDataObject::Set); - 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 ) + + wxString filenamesPassed; + + for (size_t i = 0; !hasData && i < formatcount; i++) { - for (size_t i = 0; !hasData && i < formatcount; i++) + // go through the data in our order of preference + wxDataFormat dataFormat = array[i]; + + if (source->IsSupported(dataFormat)) { - // 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 ); - } + hasData = true; } } + return hasData; } -#if wxOSX_USE_COCOA -void wxDataObject::AddSupportedTypes( void* cfarray) +void wxDataObject::AddSupportedTypes( CFMutableArrayRef cfarray) const { 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; -} + wxScopedArray array(GetFormatCount()); + GetAllFormats(array.get(), wxDataObject::Set); -#endif + for (size_t i = 0; i < nFormats; i++) + array[i].AddSupportedTypes(cfarray); + +} // ---------------------------------------------------------------------------- // wxTextDataObject diff --git a/src/osx/carbon/metafile.cpp b/src/osx/carbon/metafile.cpp index 5232166c38..685e627124 100644 --- a/src/osx/carbon/metafile.cpp +++ b/src/osx/carbon/metafile.cpp @@ -95,9 +95,7 @@ wxMetafileRefData::wxMetafileRefData( const wxString& filename ) if ( !filename.empty() ) { - wxCFRef cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(filename))); - CFStringNormalize(cfMutableString,kCFStringNormalizationFormD); - wxCFRef url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false)); + wxCFRef url(wxOSXCreateURLFromFileSystemPath(filename)); m_pdfDoc.reset(CGPDFDocumentCreateWithURL(url)); } } diff --git a/src/osx/cocoa/dnd.mm b/src/osx/cocoa/dnd.mm index 5f1059253a..6ff71f619d 100644 --- a/src/osx/cocoa/dnd.mm +++ b/src/osx/cocoa/dnd.mm @@ -17,6 +17,8 @@ #if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" +#include "wx/clipbrd.h" +#include "wx/filename.h" #ifndef WX_PRECOMP #include "wx/app.h" @@ -29,6 +31,217 @@ #include "wx/osx/private.h" +wxOSXDataSinkItem::~wxOSXDataSinkItem() +{ +} + +void wxOSXDataSinkItem::SetFilename(const wxString& filename) +{ + wxCFRef url(wxOSXCreateURLFromFileSystemPath(filename)); + wxCFRef data(CFURLCreateData(NULL,url,kCFStringEncodingUTF8,true)); + DoSetData( kUTTypeFileURL, data); +} + +wxOSXDataSourceItem::~wxOSXDataSourceItem() +{ +} + +bool wxOSXDataSource::IsSupported(const wxDataFormat &dataFormat) +{ + wxCFMutableArrayRef typesarray; + dataFormat.AddSupportedTypes(typesarray); + return HasData(typesarray); +} + +bool wxOSXDataSource::IsSupported(const wxDataObject &dataobj) +{ + wxCFMutableArrayRef typesarray; + dataobj.AddSupportedTypes(typesarray); + return HasData(typesarray); +} + +class WXDLLIMPEXP_CORE wxOSXPasteboardSinkItem : public wxOSXDataSinkItem +{ +public: + wxOSXPasteboardSinkItem(NSPasteboardItem* item): m_item(item) + { + } + + ~wxOSXPasteboardSinkItem() + { + + } + + virtual void SetData(const wxDataFormat& format, const void *buf, size_t datasize) + { + SetData( format.GetFormatId(), buf, datasize); + } + + virtual void SetData(wxDataFormat::NativeFormat format, const void *buf, size_t datasize) + { + wxCFRef data(CFDataCreate( kCFAllocatorDefault, (UInt8*)buf, datasize )); + DoSetData(format, data); + } + + virtual void DoSetData(wxDataFormat::NativeFormat format, CFDataRef data) + { + [m_item setData:(NSData*) data forType:(NSString*) format]; + } + + NSPasteboardItem* GetNative() { return m_item; }; +private: + NSPasteboardItem* m_item; +}; + +class WXDLLIMPEXP_CORE wxOSXPasteboardSourceItem : public wxOSXDataSourceItem +{ +public: + wxOSXPasteboardSourceItem(NSPasteboardItem* item, NSPasteboard* board): m_item(item), m_pasteboard(board) + { + } + + virtual wxDataFormat::NativeFormat AvailableType(CFArrayRef types) const + { + return (wxDataFormat::NativeFormat)[m_item availableTypeFromArray:(NSArray*)types]; + } + + virtual bool GetData( const wxDataFormat& dataFormat, wxMemoryBuffer& target) + { + return GetData(dataFormat.GetFormatId(), target); + } + + + virtual bool GetData( wxDataFormat::NativeFormat type, wxMemoryBuffer& target) + { + bool success = false; + + target.Clear(); + + CFDataRef flavorData = DoGetData( type ); + + if ( flavorData ) + { + CFIndex flavorDataSize = CFDataGetLength(flavorData); + size_t allocatedSize = flavorDataSize+4; + void * buf = target.GetWriteBuf(allocatedSize); + if ( buf ) + { + memset(buf, 0, allocatedSize); + memcpy(buf, CFDataGetBytePtr(flavorData), flavorDataSize); + target.UngetWriteBuf(flavorDataSize); + success = true; + } + } + return success; + } + + virtual CFDataRef DoGetData(wxDataFormat::NativeFormat type) const + { + // before a file promise can be resolved, we must pass a paste location + if ( UTTypeConformsTo((CFStringRef)type, kPasteboardTypeFileURLPromise ) ) + { + wxString tempdir = wxFileName::GetTempDir() + wxFILE_SEP_PATH + "wxtemp.XXXXXX"; + char* result = mkdtemp((char*)tempdir.fn_str().data()); + + wxCFRef dest(CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8*)result, strlen(result), true)); + PasteboardRef pboardRef = NULL; + PasteboardCreate((CFStringRef)[m_pasteboard name], &pboardRef); + if (pboardRef != NULL) { + PasteboardSynchronize(pboardRef); + PasteboardSetPasteLocation(pboardRef, (CFURLRef)dest); + CFRelease(pboardRef); + } + } + + return (CFDataRef) [m_item dataForType:(NSString*) type]; + } + + NSPasteboardItem* GetNative() { return m_item; }; +private: + NSPasteboardItem* m_item; + NSPasteboard* m_pasteboard; +}; + +wxOSXPasteboard::wxOSXPasteboard(OSXPasteboard native) +{ + m_pasteboard = native; +} + +wxOSXPasteboard::~wxOSXPasteboard() +{ + DeleteSinkItems(); +} + +void wxOSXPasteboard::DeleteSinkItems() +{ + for ( wxVector::iterator it = m_sinkItems.begin(); + it != m_sinkItems.end(); + ++it) + { + delete (*it); + } + m_sinkItems.clear(); +} + +// data sink methods + +void wxOSXPasteboard::Clear() +{ + [m_pasteboard clearContents]; + DeleteSinkItems(); +} + +void wxOSXPasteboard::Flush() +{ + NSMutableArray* nsarray = [[NSMutableArray alloc] init]; + for ( wxVector::iterator it = m_sinkItems.begin(); + it != m_sinkItems.end(); + ++it) + { + wxOSXPasteboardSinkItem* item = dynamic_cast(*it); + [nsarray addObject:item->GetNative()]; + delete item; + } + m_sinkItems.clear(); + [m_pasteboard writeObjects:nsarray]; + [nsarray release]; +} + +wxOSXDataSinkItem* wxOSXPasteboard::CreateItem() +{ + NSPasteboardItem* nsitem = [[NSPasteboardItem alloc] init]; + wxOSXPasteboardSinkItem* item = new wxOSXPasteboardSinkItem(nsitem); + m_sinkItems.push_back(item); + + return item; +} + +// data source methods + +bool wxOSXPasteboard::HasData(CFArrayRef types) const +{ + return [m_pasteboard canReadItemWithDataConformingToTypes:(NSArray*) types]; +} + +const wxOSXDataSourceItem* wxOSXPasteboard::GetItem(size_t pos) const +{ + return new wxOSXPasteboardSourceItem([[m_pasteboard pasteboardItems] objectAtIndex: pos], m_pasteboard); +} + +// data source methods + +wxOSXPasteboard* wxOSXPasteboard::GetGeneralClipboard() +{ + static wxOSXPasteboard clipboard( [NSPasteboard pasteboardWithName:NSGeneralPboard]); + return &clipboard; +} + +size_t wxOSXPasteboard::GetItemCount() const +{ + return [[m_pasteboard pasteboardItems] count]; +} + + wxDropSource* gCurrentSource = NULL; wxDragResult NSDragOperationToWxDragResult(NSDragOperation code) @@ -128,10 +341,10 @@ wxDragResult NSDragOperationToWxDragResult(NSDragOperation code) { wxUnusedVar( anImage ); wxUnusedVar( aPoint ); - + bool optionDown = GetCurrentKeyModifiers() & optionKey; wxDragResult result = optionDown ? wxDragCopy : wxDragMove; - + if (wxDropSource* source = impl) { if (!source->GiveFeedback(result)) @@ -177,7 +390,7 @@ wxDragResult NSDragOperationToWxDragResult(NSDragOperation code) { wxUnusedVar( anImage ); wxUnusedVar( aPoint ); - + resultCode = operation; dragFinished = YES; } @@ -230,77 +443,66 @@ wxDragResult wxDropSource::DoDragDrop(int flags) NSView* view = m_window->GetPeer()->GetWXWidget(); if (view) { - NSPasteboard *pboard; - - pboard = [NSPasteboard pasteboardWithName:NSDragPboard]; - - OSStatus err = noErr; - PasteboardRef pboardRef; - PasteboardCreate((CFStringRef)[pboard name], &pboardRef); - - err = PasteboardClear( pboardRef ); - if ( err != noErr ) - { - CFRelease( pboardRef ); - return wxDragNone; - } - PasteboardSynchronize( pboardRef ); - - m_data->AddToPasteboard( pboardRef, 1 ); - + NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard]; + wxOSXPasteboard dragPasteboard( pboard ); + dragPasteboard.Clear(); + + m_data->WriteToSink( &dragPasteboard); + + dragPasteboard.Flush(); + NSEvent* theEvent = (NSEvent*)wxTheApp->MacGetCurrentEvent(); wxASSERT_MSG(theEvent, "DoDragDrop must be called in response to a mouse down or drag event."); NSPoint down = [theEvent locationInWindow]; NSPoint p = [view convertPoint:down fromView:nil]; - + gCurrentSource = this; - - // add a dummy square as dragged image for the moment, + + // add a dummy square as dragged image for the moment, // TODO: proper drag image for data NSSize sz = NSMakeSize(16,16); NSRect fillRect = NSMakeRect(0, 0, 16, 16); NSImage* image = [[NSImage alloc] initWithSize: sz]; - + [image lockFocus]; - + [[[NSColor whiteColor] colorWithAlphaComponent:0.8] set]; NSRectFill(fillRect); [[NSColor blackColor] set]; NSFrameRectWithWidthUsingOperation(fillRect,1.0f,NSCompositeDestinationOver); - - [image unlockFocus]; - - + + [image unlockFocus]; + DropSourceDelegate* delegate = [[DropSourceDelegate alloc] init]; [delegate setImplementation:this flags:flags]; - [view dragImage:image at:p offset:NSMakeSize(0.0,0.0) + [view dragImage:image at:p offset:NSMakeSize(0.0,0.0) event: theEvent pasteboard: pboard source:delegate slideBack: NO]; - + wxEventLoopBase * const loop = wxEventLoop::GetActive(); while ( ![delegate finished] ) loop->Dispatch(); - + result = NSDragOperationToWxDragResult([delegate code]); [delegate release]; [image release]; - + wxWindow* mouseUpTarget = wxWindow::GetCapture(); if ( mouseUpTarget == NULL ) { mouseUpTarget = m_window; } - + if ( mouseUpTarget != NULL ) { wxMouseEvent wxevent(wxEVT_LEFT_DOWN); ((wxWidgetCocoaImpl*)mouseUpTarget->GetPeer())->SetupMouseEvent(wxevent , theEvent) ; wxevent.SetEventType(wxEVT_LEFT_UP); - + mouseUpTarget->HandleWindowEvent(wxevent); } - + gCurrentSource = NULL; } diff --git a/src/osx/cocoa/window.mm b/src/osx/cocoa/window.mm index ef0a0ba623..c182de7fc5 100644 --- a/src/osx/cocoa/window.mm +++ b/src/osx/cocoa/window.mm @@ -32,6 +32,7 @@ #if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" + #include "wx/clipbrd.h" #endif #if wxUSE_TOOLTIPS @@ -1006,9 +1007,6 @@ void wxOSX_insertText(NSView* self, SEL _cmd, NSString* text); #if wxUSE_DRAG_AND_DROP -// see http://lists.apple.com/archives/Cocoa-dev/2005/Jul/msg01244.html -// for details on the NSPasteboard -> PasteboardRef conversion - NSDragOperation wxOSX_draggingEntered( id self, SEL _cmd, id sender ) { wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self ); @@ -1290,8 +1288,16 @@ namespace unsigned int wxOnDraggingEnteredOrUpdated(wxWidgetCocoaImpl* viewImpl, void *s, bool entered) { + wxWindow* wxpeer = viewImpl->GetWXPeer(); + if ( wxpeer == NULL ) + return NSDragOperationNone; + + wxDropTarget* target = wxpeer->GetDropTarget(); + if ( target == NULL ) + return NSDragOperationNone; + id sender = (id ) s; - NSPasteboard *pboard = [sender draggingPasteboard]; + wxOSXPasteboard pb([sender draggingPasteboard]); /* sourceDragMask contains a flag field with drag operations permitted by the source: @@ -1311,14 +1317,6 @@ unsigned int wxOnDraggingEnteredOrUpdated(wxWidgetCocoaImpl* viewImpl, */ NSDragOperation sourceDragMask = [sender draggingSourceOperationMask]; - wxWindow* wxpeer = viewImpl->GetWXPeer(); - if ( wxpeer == NULL ) - return NSDragOperationNone; - - wxDropTarget* target = wxpeer->GetDropTarget(); - if ( target == NULL ) - return NSDragOperationNone; - NSPoint nspoint = [viewImpl->GetWXWidget() convertPoint:[sender draggingLocation] fromView:nil]; wxPoint pt = wxFromNSPoint( viewImpl->GetWXWidget(), nspoint ); @@ -1345,9 +1343,7 @@ unsigned int wxOnDraggingEnteredOrUpdated(wxWidgetCocoaImpl* viewImpl, else if (sourceDragMask & NSDragOperationLink) result = wxDragLink; - PasteboardRef pboardRef; - PasteboardCreate((CFStringRef)[pboard name], &pboardRef); - target->SetCurrentDragPasteboard(pboardRef); + target->SetCurrentDragSource(&pb); if (entered) { // Drag entered @@ -1359,8 +1355,6 @@ unsigned int wxOnDraggingEnteredOrUpdated(wxWidgetCocoaImpl* viewImpl, result = target->OnDragOver(pt.x, pt.y, result); } - CFRelease(pboardRef); - NSDragOperation nsresult = NSDragOperationNone; switch (result ) { @@ -1391,9 +1385,6 @@ unsigned int wxWidgetCocoaImpl::draggingEntered(void* s, WXWidget WXUNUSED(slf), void wxWidgetCocoaImpl::draggingExited(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd)) { - id sender = (id ) s; - NSPasteboard *pboard = [sender draggingPasteboard]; - wxWindow* wxpeer = GetWXPeer(); if ( wxpeer == NULL ) return; @@ -1402,11 +1393,11 @@ void wxWidgetCocoaImpl::draggingExited(void* s, WXWidget WXUNUSED(slf), void *WX if ( target == NULL ) return; - PasteboardRef pboardRef; - PasteboardCreate((CFStringRef)[pboard name], &pboardRef); - target->SetCurrentDragPasteboard(pboardRef); + id sender = (id ) s; + wxOSXPasteboard pb([sender draggingPasteboard]); + + target->SetCurrentDragSource(&pb); target->OnLeave(); - CFRelease(pboardRef); } unsigned int wxWidgetCocoaImpl::draggingUpdated(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd)) @@ -1416,13 +1407,17 @@ unsigned int wxWidgetCocoaImpl::draggingUpdated(void* s, WXWidget WXUNUSED(slf), bool wxWidgetCocoaImpl::performDragOperation(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd)) { - id sender = (id ) s; + wxWindow* wxpeer = GetWXPeer(); + if ( wxpeer == NULL ) + return false; + wxDropTarget* target = wxpeer->GetDropTarget(); + if ( target == NULL ) + return false; - NSPasteboard *pboard = [sender draggingPasteboard]; + id sender = (id ) s; + wxOSXPasteboard pb([sender draggingPasteboard]); NSDragOperation sourceDragMask = [sender draggingSourceOperationMask]; - wxWindow* wxpeer = GetWXPeer(); - wxDropTarget* target = wxpeer->GetDropTarget(); wxDragResult result = wxDragNone; NSPoint nspoint = [m_osxView convertPoint:[sender draggingLocation] fromView:nil]; wxPoint pt = wxFromNSPoint( m_osxView, nspoint ); @@ -1435,15 +1430,11 @@ bool wxWidgetCocoaImpl::performDragOperation(void* s, WXWidget WXUNUSED(slf), vo else if (sourceDragMask & NSDragOperationLink) result = wxDragLink; - PasteboardRef pboardRef; - PasteboardCreate((CFStringRef)[pboard name], &pboardRef); - target->SetCurrentDragPasteboard(pboardRef); + target->SetCurrentDragSource(&pb); if (target->OnDrop(pt.x, pt.y)) result = target->OnData(pt.x, pt.y, result); - CFRelease(pboardRef); - return result != wxDragNone; } #endif // wxUSE_DRAG_AND_DROP @@ -1458,7 +1449,7 @@ void wxWidgetCocoaImpl::mouseEvent(WX_NSEvent event, WXWidget slf, void *_cmd) if ( hitview == NULL || hitview != slf) return; } - + if ( !DoHandleMouseEvent(event) ) { // for plain NSView mouse events would propagate to parents otherwise @@ -1467,19 +1458,19 @@ void wxWidgetCocoaImpl::mouseEvent(WX_NSEvent event, WXWidget slf, void *_cmd) { wxOSX_EventHandlerPtr superimpl = (wxOSX_EventHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd]; superimpl(slf, (SEL)_cmd, event); - + // super of built-ins keeps the mouse up, as wx expects this event, we have to synthesize it // only trigger if at this moment the mouse is already up, and the control is still existing after the event has // been handled (we do this by looking up the native NSView's peer from the hash map, that way we are sure the info // is current - even when the instance memory of ourselves may have been freed ... - + wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( slf ); if ( [ event type] == NSLeftMouseDown && !wxGetMouseState().LeftIsDown() && impl != NULL ) { wxMouseEvent wxevent(wxEVT_LEFT_DOWN); SetupMouseEvent(wxevent , event) ; wxevent.SetEventType(wxEVT_LEFT_UP); - + GetWXPeer()->HandleWindowEvent(wxevent); } } @@ -3123,22 +3114,21 @@ bool wxWidgetCocoaImpl::SetFocus() void wxWidgetCocoaImpl::SetDropTarget(wxDropTarget* target) { [m_osxView unregisterDraggedTypes]; - - if ( target == NULL ) + + if (target == NULL) return; - + wxDataObject* dobj = target->GetDataObject(); - - if( dobj ) + + if (dobj) { - CFMutableArrayRef typesarray = CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks); + wxCFMutableArrayRef typesarray; dobj->AddSupportedTypes(typesarray); NSView* targetView = m_osxView; - if ( [m_osxView isKindOfClass:[NSScrollView class] ] ) - targetView = [(NSScrollView*) m_osxView documentView]; + if ([m_osxView isKindOfClass:[NSScrollView class]]) + targetView = [(NSScrollView*)m_osxView documentView]; - [targetView registerForDraggedTypes:(NSArray*)typesarray]; - CFRelease(typesarray); + [targetView registerForDraggedTypes:typesarray]; } } #endif // wxUSE_DRAG_AND_DROP diff --git a/src/osx/core/cfstring.cpp b/src/osx/core/cfstring.cpp index 502c2bc4a8..38356233eb 100644 --- a/src/osx/core/cfstring.cpp +++ b/src/osx/core/cfstring.cpp @@ -20,9 +20,10 @@ #endif #include "wx/osx/core/cfstring.h" +#include "wx/osx/core/cfdataref.h" #include - +#include const wxString sCR((wxChar)13); const wxString sLF((wxChar)10); @@ -695,38 +696,3 @@ wxString wxCFStringRef::AsStringWithNormalizationFormC( NSString* ref, wxFontEnc } #endif - -// -// wxMacUniCharBuffer -// - -wxMacUniCharBuffer::wxMacUniCharBuffer( const wxString &str ) -{ - wxMBConvUTF16 converter ; -#if wxUSE_UNICODE - size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ) ; - m_ubuf = (UniChar*) malloc( unicharlen + 2 ) ; - converter.WC2MB( (char*) m_ubuf , str.wc_str(), unicharlen + 2 ) ; -#else - const wxWCharBuffer wchar = str.wc_str( wxConvLocal ) ; - size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ) ; - m_ubuf = (UniChar*) malloc( unicharlen + 2 ) ; - converter.WC2MB( (char*) m_ubuf , wchar.data() , unicharlen + 2 ) ; -#endif - m_chars = unicharlen / 2 ; -} - -wxMacUniCharBuffer::~wxMacUniCharBuffer() -{ - free( m_ubuf ) ; -} - -UniCharPtr wxMacUniCharBuffer::GetBuffer() -{ - return m_ubuf ; -} - -UniCharCount wxMacUniCharBuffer::GetChars() -{ - return m_chars ; -} diff --git a/src/osx/core/sound.cpp b/src/osx/core/sound.cpp index e81a4d7826..89ffe70a6e 100644 --- a/src/osx/core/sound.cpp +++ b/src/osx/core/sound.cpp @@ -134,9 +134,7 @@ bool wxSound::Create(const wxString& fileName, bool isResource) { wxCHECK_MSG( !isResource, false, "not implemented" ); - wxCFRef cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(fileName))); - CFStringNormalize(cfMutableString,kCFStringNormalizationFormD); - wxCFRef url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false)); + wxCFRef url(wxOSXCreateURLFromFileSystemPath(fileName)); SystemSoundID soundID; OSStatus err = AudioServicesCreateSystemSoundID(url, &soundID); diff --git a/src/osx/core/strconv_cf.cpp b/src/osx/core/strconv_cf.cpp index a385e528b3..4870533a50 100644 --- a/src/osx/core/strconv_cf.cpp +++ b/src/osx/core/strconv_cf.cpp @@ -233,6 +233,41 @@ WXDLLIMPEXP_BASE wxMBConv* new_wxMBConv_cf(wxFontEncoding encoding) return usedBufLen; } +// +// wxMacUniCharBuffer +// + +wxMacUniCharBuffer::wxMacUniCharBuffer( const wxString &str ) +{ + wxMBConvUTF16 converter ; +#if wxUSE_UNICODE + size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ) ; + m_ubuf = (UniChar*) malloc( unicharlen + 2 ) ; + converter.WC2MB( (char*) m_ubuf , str.wc_str(), unicharlen + 2 ) ; +#else + const wxWCharBuffer wchar = str.wc_str( wxConvLocal ) ; + size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ) ; + m_ubuf = (UniChar*) malloc( unicharlen + 2 ) ; + converter.WC2MB( (char*) m_ubuf , wchar.data() , unicharlen + 2 ) ; +#endif + m_chars = unicharlen / 2 ; +} + +wxMacUniCharBuffer::~wxMacUniCharBuffer() +{ + free( m_ubuf ) ; +} + +UniCharPtr wxMacUniCharBuffer::GetBuffer() +{ + return m_ubuf ; +} + +UniCharCount wxMacUniCharBuffer::GetChars() +{ + return m_chars ; +} + #endif // __DARWIN__ diff --git a/src/osx/core/utilsexc_base.cpp b/src/osx/core/utilsexc_base.cpp index ccbcd3ee75..12f290a50d 100644 --- a/src/osx/core/utilsexc_base.cpp +++ b/src/osx/core/utilsexc_base.cpp @@ -41,9 +41,6 @@ #include "wx/osx/core/cfstring.h" #include "wx/osx/core/private.h" -// Default path style -#define kDefaultPathStyle kCFURLPOSIXPathStyle - #if wxUSE_SOCKETS // global pointer which lives in the base library, set from the net one (see // sockosx.cpp) and used from the GUI code (see utilsexc_cf.cpp) -- ugly but @@ -95,7 +92,7 @@ bool wxMacLaunch(const char* const* argv) CFURLCreateWithFileSystemPath( kCFAllocatorDefault, wxCFStringRef(path), - kDefaultPathStyle, + kCFURLPOSIXPathStyle, true); //false == not a directory // Check for error from the CFURL @@ -163,7 +160,7 @@ bool wxMacLaunch(const char* const* argv) cfurlCurrentFile = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, wxCFStringRef(*argv), - kDefaultPathStyle, + kCFURLPOSIXPathStyle, true); //true == directory } else if(argfn.FileExists()) @@ -173,7 +170,7 @@ bool wxMacLaunch(const char* const* argv) cfurlCurrentFile = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, wxCFStringRef(*argv), - kDefaultPathStyle, + kCFURLPOSIXPathStyle, false); //false == regular file } else diff --git a/src/osx/dnd_osx.cpp b/src/osx/dnd_osx.cpp index 4170c5a5cf..e2864d85a2 100644 --- a/src/osx/dnd_osx.cpp +++ b/src/osx/dnd_osx.cpp @@ -13,6 +13,7 @@ #if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" +#include "wx/scopedarray.h" #ifndef WX_PRECOMP #include "wx/app.h" @@ -73,8 +74,8 @@ bool wxDropTarget::CurrentDragHasSupportedFormat() if ( data ) { size_t formatcount = data->GetFormatCount(); - wxDataFormat *array = new wxDataFormat[formatcount]; - data->GetAllFormats( array ); + wxScopedArray array(formatcount); + data->GetAllFormats( array.get() ); for (size_t i = 0; !supported && i < formatcount; i++) { wxDataFormat format = array[i]; @@ -84,14 +85,12 @@ bool wxDropTarget::CurrentDragHasSupportedFormat() break; } } - - delete [] array; } } if ( !supported ) { - supported = m_dataObject->HasDataInPasteboard( m_currentDragPasteboard ); + supported = m_dataObject->CanReadFromSource( m_currentDragPasteboard ); } return supported; @@ -113,8 +112,8 @@ bool wxDropTarget::GetData() if (data != NULL) { size_t formatcount = data->GetFormatCount(); - wxDataFormat *array = new wxDataFormat[formatcount]; - data->GetAllFormats( array ); + wxScopedArray array(formatcount); + data->GetAllFormats( array.get() ); for (size_t i = 0; !transferred && i < formatcount; i++) { wxDataFormat format = array[i]; @@ -135,14 +134,12 @@ bool wxDropTarget::GetData() } } } - - delete [] array; } } if ( !transferred ) { - transferred = m_dataObject->GetFromPasteboard( m_currentDragPasteboard ); + transferred = m_dataObject->ReadFromSource(m_currentDragPasteboard); } return transferred; diff --git a/src/osx/fswatcher_fsevents.cpp b/src/osx/fswatcher_fsevents.cpp index 8d60e17994..dbf6e457bd 100644 --- a/src/osx/fswatcher_fsevents.cpp +++ b/src/osx/fswatcher_fsevents.cpp @@ -19,6 +19,8 @@ #include "wx/fswatcher.h" #include "wx/osx/core/cfstring.h" +#include "wx/osx/core/private/strconv_cf.h" + #include // A small class that we will give the FSEvents diff --git a/src/osx/utils_osx.cpp b/src/osx/utils_osx.cpp index 2350f16cb6..0b43c1fef9 100644 --- a/src/osx/utils_osx.cpp +++ b/src/osx/utils_osx.cpp @@ -65,9 +65,7 @@ bool wxLaunchDefaultApplication(const wxString& document, int flags) { wxUnusedVar(flags); - wxCFRef cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(document))); - CFStringNormalize(cfMutableString,kCFStringNormalizationFormD); - wxCFRef curl(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false)); + wxCFRef curl(wxOSXCreateURLFromFileSystemPath(document)); OSStatus err = LSOpenCFURLRef( curl , NULL ); if (err == noErr)