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
This commit is contained in:
Stefan Csomor
2019-10-08 06:32:44 +02:00
committed by GitHub
parent 9102da27ec
commit f83577df45
24 changed files with 733 additions and 624 deletions

View File

@@ -2790,7 +2790,7 @@ typedef WX_UIImage WXImage;
typedef WX_EAGLContext WXGLContext; typedef WX_EAGLContext WXGLContext;
typedef WX_NSString WXGLPixelFormat; typedef WX_NSString WXGLPixelFormat;
typedef WX_UIWebView OSXWebViewPtr; typedef WX_UIWebView OSXWebViewPtr;
typedef WX_UIPasteboard OSXPasteboard; typedef WX_UIPasteboard WXOSXPasteboard;
#endif #endif

View File

@@ -12,8 +12,6 @@
#ifndef __WX_CFSTRINGHOLDER_H__ #ifndef __WX_CFSTRINGHOLDER_H__
#define __WX_CFSTRINGHOLDER_H__ #define __WX_CFSTRINGHOLDER_H__
#include <CoreFoundation/CFString.h>
#include "wx/dlimpexp.h" #include "wx/dlimpexp.h"
#include "wx/fontenc.h" #include "wx/fontenc.h"
#include "wx/osx/core/cfref.h" #include "wx/osx/core/cfref.h"
@@ -44,7 +42,7 @@ public:
wxFontEncoding encoding = wxFONTENCODING_DEFAULT) ; wxFontEncoding encoding = wxFONTENCODING_DEFAULT) ;
#ifdef __WXMAC__ #ifdef __WXMAC__
wxCFStringRef(NSString* ref) wxCFStringRef(WX_NSString ref)
: wxCFRef< CFStringRef >((CFStringRef) ref) : wxCFRef< CFStringRef >((CFStringRef) ref)
{ {
} }
@@ -69,29 +67,12 @@ public:
static wxString AsString( CFStringRef ref, wxFontEncoding encoding = wxFONTENCODING_DEFAULT ) ; static wxString AsString( CFStringRef ref, wxFontEncoding encoding = wxFONTENCODING_DEFAULT ) ;
static wxString AsStringWithNormalizationFormC( CFStringRef ref, wxFontEncoding encoding = wxFONTENCODING_DEFAULT ) ; static wxString AsStringWithNormalizationFormC( CFStringRef ref, wxFontEncoding encoding = wxFONTENCODING_DEFAULT ) ;
#ifdef __WXMAC__ #ifdef __WXMAC__
static wxString AsString( NSString* ref, wxFontEncoding encoding = wxFONTENCODING_DEFAULT ) ; static wxString AsString( WX_NSString ref, wxFontEncoding encoding = wxFONTENCODING_DEFAULT ) ;
static wxString AsStringWithNormalizationFormC( 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 #endif
private: 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__ #endif //__WXCFSTRINGHOLDER_H__

View File

@@ -51,6 +51,7 @@ wxString WXDLLIMPEXP_CORE wxMacMakeStringFromPascal( const unsigned char * from
WXDLLIMPEXP_BASE wxString wxMacFSRefToPath( const FSRef *fsRef , CFStringRef additionalPathComponent = NULL ); WXDLLIMPEXP_BASE wxString wxMacFSRefToPath( const FSRef *fsRef , CFStringRef additionalPathComponent = NULL );
WXDLLIMPEXP_BASE OSStatus wxMacPathToFSRef( const wxString&path , FSRef *fsRef ); WXDLLIMPEXP_BASE OSStatus wxMacPathToFSRef( const wxString&path , FSRef *fsRef );
WXDLLIMPEXP_BASE wxString wxMacHFSUniStrToString( ConstHFSUniStr255Param uniname ); WXDLLIMPEXP_BASE wxString wxMacHFSUniStrToString( ConstHFSUniStr255Param uniname );
WXDLLIMPEXP_BASE CFURLRef wxOSXCreateURLFromFileSystemPath( const wxString& path);
// keycode utils from app.cpp // keycode utils from app.cpp

View File

@@ -13,6 +13,7 @@
#include <CoreFoundation/CFString.h> #include <CoreFoundation/CFString.h>
#include <CoreFoundation/CFStringEncodingExt.h> #include <CoreFoundation/CFStringEncodingExt.h>
#include "wx/fontmap.h"
// ============================================================================ // ============================================================================
// CoreFoundation conversion classes // CoreFoundation conversion classes
@@ -335,3 +336,20 @@ private:
CFStringEncoding m_encoding ; 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 ;
};

View File

@@ -11,10 +11,12 @@
#ifndef _WX_MAC_DATAFORM_H #ifndef _WX_MAC_DATAFORM_H
#define _WX_MAC_DATAFORM_H #define _WX_MAC_DATAFORM_H
#include "wx/osx/core/cfstring.h"
class WXDLLIMPEXP_CORE wxDataFormat class WXDLLIMPEXP_CORE wxDataFormat
{ {
public: public:
typedef unsigned long NativeFormat; typedef CFStringRef NativeFormat;
wxDataFormat(); wxDataFormat();
wxDataFormat(wxDataFormatId vType); wxDataFormat(wxDataFormatId vType);
@@ -41,8 +43,8 @@ public:
// explicit and implicit conversions to NativeFormat which is one of // explicit and implicit conversions to NativeFormat which is one of
// standard data types (implicit conversion is useful for preserving the // standard data types (implicit conversion is useful for preserving the
// compatibility with old code) // compatibility with old code)
NativeFormat GetFormatId() const { return m_format; } const NativeFormat GetFormatId() const { return m_format; }
operator NativeFormat() const { return m_format; } operator const NativeFormat() const { return m_format; }
void SetId(NativeFormat format); void SetId(NativeFormat format);
@@ -54,15 +56,18 @@ public:
// implementation // implementation
wxDataFormatId GetType() const { return m_type; } wxDataFormatId GetType() const { return m_type; }
void SetType( wxDataFormatId type ); void SetType( wxDataFormatId type );
static NativeFormat GetFormatForType(wxDataFormatId type);
// returns true if the format is one of those defined in wxDataFormatId // returns true if the format is one of those defined in wxDataFormatId
bool IsStandard() const { return m_type > 0 && m_type < wxDF_PRIVATE; } 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: private:
wxDataFormatId m_type; void ClearNativeFormat();
NativeFormat m_format;
// indicates the type in case of wxDF_PRIVATE : wxDataFormatId m_type;
wxString m_id ; wxCFStringRef m_format;
}; };
#endif // _WX_MAC_DATAFORM_H #endif // _WX_MAC_DATAFORM_H

View File

@@ -11,28 +11,24 @@
#ifndef _WX_MAC_DATAOBJ_H_ #ifndef _WX_MAC_DATAOBJ_H_
#define _WX_MAC_DATAOBJ_H_ #define _WX_MAC_DATAOBJ_H_
// ---------------------------------------------------------------------------- class WXDLLIMPEXP_CORE wxOSXDataSink;
// wxDataObject is the same as wxDataObjectBase under wxGTK class WXDLLIMPEXP_CORE wxOSXDataSource;
// ----------------------------------------------------------------------------
class WXDLLIMPEXP_CORE wxDataObject : public wxDataObjectBase class WXDLLIMPEXP_CORE wxDataObject : public wxDataObjectBase
{ {
public: public:
wxDataObject(); wxDataObject();
#ifdef __DARWIN__
virtual ~wxDataObject() { } virtual ~wxDataObject() { }
#endif
virtual bool IsSupportedFormat( const wxDataFormat& format, Direction dir = Get ) const; 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 void WriteToSink(wxOSXDataSink *sink) const;
static bool IsFormatInPasteboard( void * pasteboardRef, const wxDataFormat &dataFormat ); bool ReadFromSource(wxOSXDataSource *source);
// returns true if any of the accepted formats of this dataobj is in the pasteboard bool CanReadFromSource(wxOSXDataSource *source) const;
bool HasDataInPasteboard( void * pasteboardRef );
bool GetFromPasteboard( void * pasteboardRef );
#if wxOSX_USE_COCOA #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 #endif
}; };

View File

@@ -30,6 +30,8 @@ class WXDLLIMPEXP_FWD_CORE wxFileDropTarget;
class WXDLLIMPEXP_FWD_CORE wxDropSource; class WXDLLIMPEXP_FWD_CORE wxDropSource;
class WXDLLIMPEXP_FWD_CORE wxOSXDataSource;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// macros // macros
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -58,9 +60,10 @@ class WXDLLIMPEXP_CORE wxDropTarget: public wxDropTargetBase
virtual wxDataFormat GetMatchingPair(); virtual wxDataFormat GetMatchingPair();
bool CurrentDragHasSupportedFormat() ; bool CurrentDragHasSupportedFormat() ;
void SetCurrentDragPasteboard( void* dragpasteboard ) { m_currentDragPasteboard = dragpasteboard ; }
void SetCurrentDragSource( wxOSXDataSource* dragpasteboard ) { m_currentDragPasteboard = dragpasteboard ; }
protected : protected :
void* m_currentDragPasteboard ; wxOSXDataSource* m_currentDragPasteboard ;
}; };
//------------------------------------------------------------------------- //-------------------------------------------------------------------------

View File

@@ -2,6 +2,7 @@
#define _WX_PRIVATE_OSX_H_ #define _WX_PRIVATE_OSX_H_
#include "wx/osx/core/private.h" #include "wx/osx/core/private.h"
#include "wx/osx/private/datatransfer.h"
#if wxOSX_USE_IPHONE #if wxOSX_USE_IPHONE
#include "wx/osx/iphone/private.h" #include "wx/osx/iphone/private.h"

View File

@@ -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 <vadim@wxwidgets.org>
// 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<wxOSXDataSinkItem*> m_sinkItems;
};
#endif

View File

@@ -27,6 +27,7 @@
#ifdef __WXMAC__ #ifdef __WXMAC__
#include "wx/osx/core/cfstring.h" #include "wx/osx/core/cfstring.h"
#include <CoreFoundation/CFString.h>
#include <CoreFoundation/CFStringEncodingExt.h> #include <CoreFoundation/CFStringEncodingExt.h>
wxUint16 gMacEncodings[wxFONTENCODING_MACMAX-wxFONTENCODING_MACMIN+1][128] ; wxUint16 gMacEncodings[wxFONTENCODING_MACMAX-wxFONTENCODING_MACMIN+1][128] ;

View File

@@ -798,8 +798,6 @@ wxString wxPathOnly (const wxString& path)
#if defined(__WXMAC__) && !defined(__WXOSX_IPHONE__) #if defined(__WXMAC__) && !defined(__WXOSX_IPHONE__)
#define kDefaultPathStyle kCFURLPOSIXPathStyle
wxString wxMacFSRefToPath( const FSRef *fsRef , CFStringRef additionalPathComponent ) wxString wxMacFSRefToPath( const FSRef *fsRef , CFStringRef additionalPathComponent )
{ {
CFURLRef fullURLRef; CFURLRef fullURLRef;
@@ -814,7 +812,7 @@ wxString wxMacFSRefToPath( const FSRef *fsRef , CFStringRef additionalPathCompon
additionalPathComponent,false); additionalPathComponent,false);
CFRelease( parentURLRef ) ; CFRelease( parentURLRef ) ;
} }
wxCFStringRef cfString( CFURLCopyFileSystemPath(fullURLRef, kDefaultPathStyle )); wxCFStringRef cfString( CFURLCopyFileSystemPath(fullURLRef, kCFURLPOSIXPathStyle ));
CFRelease( fullURLRef ) ; CFRelease( fullURLRef ) ;
return wxCFStringRef::AsStringWithNormalizationFormC(cfString); return wxCFStringRef::AsStringWithNormalizationFormC(cfString);
@@ -823,15 +821,11 @@ wxString wxMacFSRefToPath( const FSRef *fsRef , CFStringRef additionalPathCompon
OSStatus wxMacPathToFSRef( const wxString&path , FSRef *fsRef ) OSStatus wxMacPathToFSRef( const wxString&path , FSRef *fsRef )
{ {
OSStatus err = noErr ; OSStatus err = noErr ;
CFMutableStringRef cfMutableString = CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(path)); wxCFRef<CFURLRef> url(wxOSXCreateURLFromFileSystemPath(path));
CFStringNormalize(cfMutableString,kCFStringNormalizationFormD);
CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kDefaultPathStyle, false);
CFRelease( cfMutableString );
if ( NULL != url ) if ( NULL != url )
{ {
if ( CFURLGetFSRef(url, fsRef) == false ) if ( CFURLGetFSRef(url, fsRef) == false )
err = fnfErr ; err = fnfErr ;
CFRelease( url ) ;
} }
else else
{ {
@@ -848,6 +842,13 @@ wxString wxMacHFSUniStrToString( ConstHFSUniStr255Param uniname )
return wxCFStringRef::AsStringWithNormalizationFormC(cfname); return wxCFStringRef::AsStringWithNormalizationFormC(cfname);
} }
CFURLRef wxOSXCreateURLFromFileSystemPath( const wxString& path)
{
wxCFRef<CFMutableStringRef> cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(path)));
CFStringNormalize(cfMutableString,kCFStringNormalizationFormD);
return CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false);
}
#ifndef __LP64__ #ifndef __LP64__
wxString wxMacFSSpec2MacFilename( const FSSpec *spec ) wxString wxMacFSSpec2MacFilename( const FSSpec *spec )

View File

@@ -66,9 +66,10 @@
#if defined(__WXOSX__) #if defined(__WXOSX__)
#include "wx/osx/core/cfref.h" #include "wx/osx/core/cfref.h"
#include "wx/osx/core/cfstring.h"
#include <CoreFoundation/CFLocale.h> #include <CoreFoundation/CFLocale.h>
#include <CoreFoundation/CFDateFormatter.h> #include <CoreFoundation/CFDateFormatter.h>
#include "wx/osx/core/cfstring.h" #include <CoreFoundation/CFString.h>
#endif #endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -25,6 +25,7 @@
#endif #endif
#include "wx/metafile.h" #include "wx/metafile.h"
#include "wx/scopedarray.h"
#include "wx/osx/private.h" #include "wx/osx/private.h"
@@ -43,18 +44,10 @@ wxClipboard::wxClipboard()
{ {
m_open = false; m_open = false;
m_data = NULL ; 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() wxClipboard::~wxClipboard()
{ {
m_pasteboard.reset((PasteboardRef)0);
delete m_data; delete m_data;
} }
@@ -62,13 +55,7 @@ void wxClipboard::Clear()
{ {
wxDELETE(m_data); wxDELETE(m_data);
wxCHECK_RET( m_pasteboard, "Clipboard creation failed." ); wxOSXPasteboard::GetGeneralClipboard()->Clear();
OSStatus err = PasteboardClear( m_pasteboard );
if (err != noErr)
{
wxLogSysError( wxT("Failed to empty the clipboard.") );
}
} }
bool wxClipboard::Flush() bool wxClipboard::Flush()
@@ -116,14 +103,10 @@ bool wxClipboard::AddData( wxDataObject *data )
// we can only store one wxDataObject // we can only store one wxDataObject
Clear(); Clear();
PasteboardSyncFlags syncFlags = PasteboardSynchronize( m_pasteboard ); data->WriteToSink(wxOSXPasteboard::GetGeneralClipboard());
wxCHECK_MSG( !(syncFlags&kPasteboardModified), false, wxT("clipboard modified after clear") );
wxCHECK_MSG( (syncFlags&kPasteboardClientIsOwner), false, wxT("client couldn't own clipboard") );
m_data = data; m_data = data;
data->AddToPasteboard( m_pasteboard, 1 );
return true; return true;
} }
@@ -139,14 +122,15 @@ void wxClipboard::Close()
wxDELETE(m_data); 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"), wxLogTrace(TRACE_CLIPBOARD, wxT("Checking if format %s is available"),
dataFormat.GetId().c_str()); dataFormat.GetId().c_str());
if ( m_data ) if ( m_data )
return m_data->IsSupported( dataFormat ); return m_data->IsSupported( dataFormat );
return wxDataObject::IsFormatInPasteboard( m_pasteboard, dataFormat );
return wxOSXPasteboard::GetGeneralClipboard()->IsSupported(dataFormat);
} }
bool wxClipboard::GetData( wxDataObject& data ) bool wxClipboard::GetData( wxDataObject& data )
@@ -156,10 +140,9 @@ bool wxClipboard::GetData( wxDataObject& data )
wxCHECK_MSG( m_open, false, wxT("clipboard not open") ); wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
size_t formatcount = data.GetFormatCount(wxDataObject::Set) + 1; size_t formatcount = data.GetFormatCount(wxDataObject::Set);
wxDataFormat *array = new wxDataFormat[ formatcount ]; wxScopedArray<wxDataFormat> array(formatcount);
array[0] = data.GetPreferredFormat(wxDataObject::Set); data.GetAllFormats( array.get(), wxDataObject::Set );
data.GetAllFormats( &array[1], wxDataObject::Set );
bool transferred = false; bool transferred = false;
@@ -179,10 +162,11 @@ bool wxClipboard::GetData( wxDataObject& data )
} }
else else
{ {
char *d = new char[ dataSize ]; wxMemoryBuffer mem(dataSize);
m_data->GetDataHere( format, (void*)d ); void *d = mem.GetWriteBuf(dataSize);
m_data->GetDataHere( format, d );
data.SetData( format, dataSize, d ); data.SetData( format, dataSize, d );
delete [] d; mem.UngetWriteBuf(dataSize);
} }
} }
} }
@@ -191,11 +175,9 @@ bool wxClipboard::GetData( wxDataObject& data )
// get formats from wxDataObjects // get formats from wxDataObjects
if ( !transferred ) if ( !transferred )
{ {
transferred = data.GetFromPasteboard( m_pasteboard ) ; transferred = data.ReadFromSource(wxOSXPasteboard::GetGeneralClipboard());
} }
delete [] array;
return transferred; return transferred;
} }

View File

@@ -14,6 +14,7 @@
#if wxUSE_DATAOBJ #if wxUSE_DATAOBJ
#include "wx/dataobj.h" #include "wx/dataobj.h"
#include "wx/clipbrd.h"
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/intl.h" #include "wx/intl.h"
@@ -30,6 +31,8 @@
#include "wx/osx/private.h" #include "wx/osx/private.h"
static CFStringRef kUTTypeTraditionalMacText = CFSTR("com.apple.traditional-mac-plain-text");
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxDataFormat // wxDataFormat
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -37,111 +40,114 @@
wxDataFormat::wxDataFormat() wxDataFormat::wxDataFormat()
{ {
m_type = wxDF_INVALID; m_type = wxDF_INVALID;
m_format = 0;
} }
wxDataFormat::wxDataFormat( wxDataFormatId vType ) wxDataFormat::wxDataFormat( wxDataFormatId vType )
{ {
m_format = 0;
m_type = wxDF_INVALID; m_type = wxDF_INVALID;
SetType( vType ); SetType( vType );
} }
wxDataFormat::wxDataFormat( const wxChar *zId ) wxDataFormat::wxDataFormat( const wxChar *zId )
{ {
m_format = 0;
m_type = wxDF_INVALID; m_type = wxDF_INVALID;
SetId( zId ); SetId( zId );
} }
wxDataFormat::wxDataFormat( const wxString& rId ) wxDataFormat::wxDataFormat( const wxString& rId )
{ {
m_format = 0;
m_type = wxDF_INVALID; m_type = wxDF_INVALID;
SetId( rId ); SetId( rId );
} }
wxDataFormat::wxDataFormat(const wxDataFormat& rFormat) wxDataFormat::wxDataFormat(const wxDataFormat& rFormat)
{ {
if ( rFormat.m_format ) m_format = rFormat.m_format;
m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)rFormat.m_format);
else
m_format = 0;
m_type = rFormat.m_type; m_type = rFormat.m_type;
m_id = rFormat.m_id;
} }
wxDataFormat::wxDataFormat( NativeFormat vFormat ) wxDataFormat::wxDataFormat(NativeFormat format)
{ {
m_format = 0; SetId(format);
m_type = wxDF_INVALID;
SetId( vFormat );
} }
wxDataFormat::~wxDataFormat() 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) wxDataFormat& wxDataFormat::operator=(const wxDataFormat& rFormat)
{ {
if ( m_format != 0 ) m_format = rFormat.m_format;
{
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_type = rFormat.m_type;
m_id = rFormat.m_id;
return *this; 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 ) void wxDataFormat::SetType( wxDataFormatId dataType )
{ {
m_type = 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 ); CFArrayAppendValue(cfarray, GetFormatId());
m_format = 0;
} }
else
switch (m_type)
{ {
case wxDF_TEXT: CFArrayAppendValue(cfarray, GetFormatForType(m_type));
m_format = (long) CFStringCreateCopy( NULL, kUTTypePlainText ); // add additional accepted types
break; switch (GetType())
{
case wxDF_UNICODETEXT: case wxDF_UNICODETEXT:
m_format = (long) CFStringCreateCopy( NULL, kUTTypeUTF16PlainText ); CFArrayAppendValue(cfarray, kUTTypeUTF8PlainText);
break; break;
case wxDF_FILENAME:
case wxDF_HTML: CFArrayAppendValue(cfarray, kPasteboardTypeFileURLPromise);
m_format = (long) CFStringCreateCopy( NULL, kUTTypeHTML ); break;
break; case wxDF_BITMAP:
CFArrayAppendValue(cfarray, kUTTypePICT);
case wxDF_BITMAP: break;
m_format = (long) CFStringCreateCopy( NULL, kUTTypeTIFF ); default:
break; 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;
} }
} }
@@ -152,12 +158,7 @@ wxString wxDataFormat::GetId() const
void wxDataFormat::SetId( NativeFormat format ) void wxDataFormat::SetId( NativeFormat format )
{ {
if ( m_format != 0 ) m_format = format;
{
CFRelease( (CFStringRef) m_format );
m_format = 0;
}
m_format = (NativeFormat) CFStringCreateCopy(NULL, (CFStringRef)format);
if ( UTTypeConformsTo( (CFStringRef)format, kUTTypeHTML ) ) if ( UTTypeConformsTo( (CFStringRef)format, kUTTypeHTML ) )
{ {
m_type = wxDF_HTML; m_type = wxDF_HTML;
@@ -194,21 +195,14 @@ void wxDataFormat::SetId( NativeFormat format )
else else
{ {
m_type = wxDF_PRIVATE; m_type = wxDF_PRIVATE;
m_id = wxCFStringRef( (CFStringRef) CFRetain((CFStringRef) format )).AsString();
} }
} }
void wxDataFormat::SetId( const wxString& zId ) void wxDataFormat::SetId( const wxString& zId )
{ {
m_type = wxDF_PRIVATE; 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 ... // 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 bool wxDataFormat::operator==(const wxDataFormat& format) const
@@ -216,7 +210,7 @@ bool wxDataFormat::operator==(const wxDataFormat& format) const
if (IsStandard() || format.IsStandard()) if (IsStandard() || format.IsStandard())
return (format.m_type == m_type); return (format.m_type == m_type);
else else
return ( UTTypeConformsTo( (CFStringRef) m_format , (CFStringRef) format.m_format ) ); return ( UTTypeConformsTo( m_format , (CFStringRef) format.m_format ) );
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@@ -238,419 +232,248 @@ bool wxDataObject::IsSupportedFormat( const wxDataFormat& rFormat, Direction vDi
} }
else else
{ {
wxDataFormat *pFormats = new wxDataFormat[nFormatCount]; wxScopedArray<wxDataFormat> array(nFormatCount);
GetAllFormats( pFormats, vDir ); GetAllFormats( array.get(), vDir );
for (size_t n = 0; n < nFormatCount; n++) for (size_t n = 0; n < nFormatCount; n++)
{ {
if (pFormats[n] == rFormat) if (array[n] == rFormat)
{ {
found = true; found = true;
break; break;
} }
} }
delete [] pFormats;
} }
return found; return found;
} }
void wxDataObject::AddToPasteboard( void * pb, wxIntPtr itemID ) void wxDataObject::WriteToSink(wxOSXDataSink * datatransfer) const
{ {
PasteboardRef pasteboard = (PasteboardRef) pb;
// get formats from wxDataObjects // get formats from wxDataObjects
wxDataFormat *array = new wxDataFormat[ GetFormatCount() ]; wxScopedArray<wxDataFormat> array(GetFormatCount());
GetAllFormats( array ); GetAllFormats( array.get() );
wxOSXDataSinkItem* sinkItem = NULL;
for (size_t i = 0; i < GetFormatCount(); i++) for (size_t i = 0; i < GetFormatCount(); i++)
{ {
wxDataFormat thisFormat = array[ 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 datasize = GetDataSize( thisFormat );
if ( datasize == wxCONV_FAILED && thisFormat.GetType() == wxDF_TEXT) if ( datasize == wxCONV_FAILED && thisFormat.GetType() == wxDF_TEXT)
{ {
// conversion to local text failed, so we must use unicode // conversion to local text failed, so we must use unicode
// if wxDF_UNICODETEXT is already on the 'todo' list, skip this iteration // if wxDF_UNICODETEXT is already on the 'todo' list, skip this iteration
// otherwise force it // otherwise force it
size_t j = 0; bool hasUnicodeFormat = false;
for (j = 0; j < GetFormatCount(); j++) for (size_t j = 0; j < GetFormatCount(); j++)
{ {
if ( array[j].GetType() == wxDF_UNICODETEXT ) if ( array[j].GetType() == wxDF_UNICODETEXT )
{
hasUnicodeFormat = true;
break; break;
}
} }
if ( j < GetFormatCount() ) if ( hasUnicodeFormat )
continue; continue;
thisFormat.SetType(wxDF_UNICODETEXT); thisFormat.SetType(wxDF_UNICODETEXT);
datasize = GetDataSize( thisFormat ); 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; size_t sz = datasize + 4;
void* buf = malloc( sz ); wxMemoryBuffer databuf( datasize+4 );
void* buf = databuf.GetWriteBuf(datasize+4);
if ( buf != NULL ) if ( buf != NULL )
{ {
// empty the buffer because in some case GetDataHere does not fill buf // empty the buffer because in some case GetDataHere does not fill buf
memset( buf, 0, sz ); 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 ) if ( thisFormat.GetType() == wxDF_FILENAME )
{ {
wxIntPtr counter = 1; wxString filenames;
// 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");
}
#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 else
{ {
CFDataRef data = CFDataCreate( kCFAllocatorDefault, (UInt8*)buf, datasize ); sinkItem->SetData(thisFormat.GetFormatId(), databuf.GetData(), databuf.GetDataLen());
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 ) bool wxDataObject::ReadFromSource(wxOSXDataSource * source)
{ {
PasteboardRef pasteboard = (PasteboardRef) pb; bool transferred = false;
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(wxDataObject::Set); size_t formatcount = GetFormatCount(wxDataObject::Set);
wxScopedArray<wxDataFormat> array(formatcount); wxScopedArray<wxDataFormat> array(formatcount);
GetAllFormats(array.get(), wxDataObject::Set); GetAllFormats(array.get(), wxDataObject::Set);
ItemCount itemCount = 0;
wxString filenamesPassed; wxString filenamesPassed;
bool transferred = false;
// we synchronize here once again, so we don't mind which flags get returned for (size_t i = 0; !transferred && i < formatcount; i++)
PasteboardSynchronize( pasteboard );
OSStatus err = PasteboardGetItemCount( pasteboard, &itemCount );
if ( err == noErr )
{ {
bool pastelocationset = false; // go through the data in our order of preference
for (size_t i = 0; !transferred && i < formatcount; i++) wxDataFormat dataFormat = array[i];
if (source->IsSupported(dataFormat))
{ {
// go through the data in our order of preference wxCFMutableArrayRef<CFStringRef> typesarray;
wxDataFormat dataFormat = array[ i ]; dataFormat.AddSupportedTypes(typesarray);
size_t itemCount = source->GetItemCount();
for( UInt32 itemIndex = 1; itemIndex <= itemCount && transferred == false ; itemIndex++ ) for ( size_t itemIndex = 0; itemIndex < itemCount && !transferred; ++itemIndex)
{ {
PasteboardItemID itemID = 0; wxScopedPtr<const wxOSXDataSourceItem> sitem(source->GetItem(itemIndex));
CFArrayRef flavorTypeArray = NULL;
CFIndex flavorCount = 0;
err = PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ); wxDataFormat::NativeFormat nativeFormat = sitem->AvailableType(typesarray);
if ( err != noErr ) CFDataRef flavorData = sitem->DoGetData(nativeFormat);
continue; if (flavorData)
err = PasteboardCopyItemFlavors( pasteboard, itemID, &flavorTypeArray );
if ( err != noErr )
continue;
flavorCount = CFArrayGetCount( flavorTypeArray );
for( CFIndex flavorIndex = 0; !transferred && flavorIndex < flavorCount ; flavorIndex++ )
{ {
CFStringRef flavorType; CFIndex flavorDataSize = CFDataGetLength(flavorData);
CFDataRef flavorData; size_t sz = flavorDataSize + 4;
CFIndex flavorDataSize; wxMemoryBuffer databuf( sz );
void* buf = databuf.GetWriteBuf( sz );
flavorType = (CFStringRef)CFArrayGetValueAtIndex( flavorTypeArray, if (buf)
flavorIndex );
wxDataFormat flavorFormat( (wxDataFormat::NativeFormat) flavorType );
if ( dataFormat == flavorFormat )
{ {
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"; wxMBConvUTF16 UTF16Converter;
char* result = mkdtemp((char*)tempdir.fn_str().data());
if (!result) wxString s((char*)buf, wxConvUTF8, flavorDataSize);
continue;
wxCFRef<CFURLRef> dest(CFURLCreateFromFileSystemRepresentation(NULL,(const UInt8*)result,strlen(result),true)); const wxCharBuffer cb = s.mb_str(UTF16Converter);
PasteboardSetPasteLocation(pasteboard, dest); flavorDataSize = cb.length();
pastelocationset = true; sz = flavorDataSize + 2;
} buf = databuf.GetWriteBuf(sz);
} memset(buf, 0, sz);
else if ( flavorFormat.GetType() != wxDF_PRIVATE ) memcpy(buf, cb.data(), flavorDataSize);
{ databuf.UngetWriteBuf(flavorDataSize);
// indicate the expected format for the type, benefiting from native conversions eg utf8 -> utf16
flavorType = (CFStringRef) wxDataFormat( flavorFormat.GetType()).GetFormatId();
}
err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType , &flavorData );
if ( err == noErr )
{
flavorDataSize = CFDataGetLength( flavorData );
if (dataFormat.GetType() == wxDF_FILENAME )
{
// revert the translation and decomposition to arrive at a proper utf8 string again
CFURLRef url = CFURLCreateWithBytes( kCFAllocatorDefault, CFDataGetBytePtr( flavorData ), flavorDataSize, kCFStringEncodingUTF8, NULL );
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<char*>(buf); *p; p++)
if (*p == '\r')
*p = '\n';
}
else if (dataFormat.GetType() == wxDF_UNICODETEXT)
{
for (wxChar16* p = static_cast<wxChar16*>(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 ); if (dataFormat.GetType() == wxDF_FILENAME)
{
// revert the translation and decomposition to arrive at a proper utf8 string again
wxCFRef<CFURLRef> 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 )
{
wxCharBuffer filenamebuf = filenamesPassed.char_str();
SetData(dataFormat, filenamebuf.length(), filenamebuf.data());
transferred = true; 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<char*>(buf); *p; p++)
if (*p == '\r')
*p = '\n';
}
else if (dataFormat.GetType() == wxDF_UNICODETEXT)
{
for (wxChar16* p = static_cast<wxChar16*>(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; 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); size_t formatcount = GetFormatCount(wxDataObject::Set);
wxScopedArray<wxDataFormat> array(formatcount); wxScopedArray<wxDataFormat> array(formatcount);
GetAllFormats(array.get(), wxDataObject::Set); 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 wxString filenamesPassed;
PasteboardSynchronize( pasteboard );
OSStatus err = PasteboardGetItemCount( pasteboard, &itemCount ); for (size_t i = 0; !hasData && i < formatcount; i++)
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];
if (source->IsSupported(dataFormat))
{ {
// go through the data in our order of preference hasData = true;
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; return hasData;
} }
#if wxOSX_USE_COCOA
void wxDataObject::AddSupportedTypes( void* cfarray) void wxDataObject::AddSupportedTypes( CFMutableArrayRef cfarray) const
{ {
size_t nFormats = GetFormatCount(wxDataObject::Set); size_t nFormats = GetFormatCount(wxDataObject::Set);
wxDataFormat *array = new wxDataFormat[nFormats]; wxScopedArray<wxDataFormat> array(GetFormatCount());
GetAllFormats(array, wxDataObject::Set); GetAllFormats(array.get(), wxDataObject::Set);
for (size_t i = 0; i < nFormats; i++) for (size_t i = 0; i < nFormats; i++)
{ array[i].AddSupportedTypes(cfarray);
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 // wxTextDataObject
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -95,9 +95,7 @@ wxMetafileRefData::wxMetafileRefData( const wxString& filename )
if ( !filename.empty() ) if ( !filename.empty() )
{ {
wxCFRef<CFMutableStringRef> cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(filename))); wxCFRef<CFURLRef> url(wxOSXCreateURLFromFileSystemPath(filename));
CFStringNormalize(cfMutableString,kCFStringNormalizationFormD);
wxCFRef<CFURLRef> url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false));
m_pdfDoc.reset(CGPDFDocumentCreateWithURL(url)); m_pdfDoc.reset(CGPDFDocumentCreateWithURL(url));
} }
} }

View File

@@ -17,6 +17,8 @@
#if wxUSE_DRAG_AND_DROP #if wxUSE_DRAG_AND_DROP
#include "wx/dnd.h" #include "wx/dnd.h"
#include "wx/clipbrd.h"
#include "wx/filename.h"
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/app.h" #include "wx/app.h"
@@ -29,6 +31,217 @@
#include "wx/osx/private.h" #include "wx/osx/private.h"
wxOSXDataSinkItem::~wxOSXDataSinkItem()
{
}
void wxOSXDataSinkItem::SetFilename(const wxString& filename)
{
wxCFRef<CFURLRef> url(wxOSXCreateURLFromFileSystemPath(filename));
wxCFRef<CFDataRef> data(CFURLCreateData(NULL,url,kCFStringEncodingUTF8,true));
DoSetData( kUTTypeFileURL, data);
}
wxOSXDataSourceItem::~wxOSXDataSourceItem()
{
}
bool wxOSXDataSource::IsSupported(const wxDataFormat &dataFormat)
{
wxCFMutableArrayRef<CFStringRef> typesarray;
dataFormat.AddSupportedTypes(typesarray);
return HasData(typesarray);
}
bool wxOSXDataSource::IsSupported(const wxDataObject &dataobj)
{
wxCFMutableArrayRef<CFStringRef> 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<CFDataRef> 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<CFURLRef> 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<wxOSXDataSinkItem*>::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<wxOSXDataSinkItem*>::iterator it = m_sinkItems.begin();
it != m_sinkItems.end();
++it)
{
wxOSXPasteboardSinkItem* item = dynamic_cast<wxOSXPasteboardSinkItem*>(*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; wxDropSource* gCurrentSource = NULL;
wxDragResult NSDragOperationToWxDragResult(NSDragOperation code) wxDragResult NSDragOperationToWxDragResult(NSDragOperation code)
@@ -230,23 +443,13 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
NSView* view = m_window->GetPeer()->GetWXWidget(); NSView* view = m_window->GetPeer()->GetWXWidget();
if (view) if (view)
{ {
NSPasteboard *pboard; NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
wxOSXPasteboard dragPasteboard( pboard );
dragPasteboard.Clear();
pboard = [NSPasteboard pasteboardWithName:NSDragPboard]; m_data->WriteToSink( &dragPasteboard);
OSStatus err = noErr; dragPasteboard.Flush();
PasteboardRef pboardRef;
PasteboardCreate((CFStringRef)[pboard name], &pboardRef);
err = PasteboardClear( pboardRef );
if ( err != noErr )
{
CFRelease( pboardRef );
return wxDragNone;
}
PasteboardSynchronize( pboardRef );
m_data->AddToPasteboard( pboardRef, 1 );
NSEvent* theEvent = (NSEvent*)wxTheApp->MacGetCurrentEvent(); NSEvent* theEvent = (NSEvent*)wxTheApp->MacGetCurrentEvent();
wxASSERT_MSG(theEvent, "DoDragDrop must be called in response to a mouse down or drag event."); wxASSERT_MSG(theEvent, "DoDragDrop must be called in response to a mouse down or drag event.");
@@ -271,7 +474,6 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
[image unlockFocus]; [image unlockFocus];
DropSourceDelegate* delegate = [[DropSourceDelegate alloc] init]; DropSourceDelegate* delegate = [[DropSourceDelegate alloc] init];
[delegate setImplementation:this flags:flags]; [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)

View File

@@ -32,6 +32,7 @@
#if wxUSE_DRAG_AND_DROP #if wxUSE_DRAG_AND_DROP
#include "wx/dnd.h" #include "wx/dnd.h"
#include "wx/clipbrd.h"
#endif #endif
#if wxUSE_TOOLTIPS #if wxUSE_TOOLTIPS
@@ -1006,9 +1007,6 @@ void wxOSX_insertText(NSView* self, SEL _cmd, NSString* text);
#if wxUSE_DRAG_AND_DROP #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 <NSDraggingInfo>sender ) NSDragOperation wxOSX_draggingEntered( id self, SEL _cmd, id <NSDraggingInfo>sender )
{ {
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self ); wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
@@ -1290,8 +1288,16 @@ namespace
unsigned int wxOnDraggingEnteredOrUpdated(wxWidgetCocoaImpl* viewImpl, unsigned int wxOnDraggingEnteredOrUpdated(wxWidgetCocoaImpl* viewImpl,
void *s, bool entered) void *s, bool entered)
{ {
wxWindow* wxpeer = viewImpl->GetWXPeer();
if ( wxpeer == NULL )
return NSDragOperationNone;
wxDropTarget* target = wxpeer->GetDropTarget();
if ( target == NULL )
return NSDragOperationNone;
id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s; id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
NSPasteboard *pboard = [sender draggingPasteboard]; wxOSXPasteboard pb([sender draggingPasteboard]);
/* /*
sourceDragMask contains a flag field with drag operations permitted by sourceDragMask contains a flag field with drag operations permitted by
the source: the source:
@@ -1311,14 +1317,6 @@ unsigned int wxOnDraggingEnteredOrUpdated(wxWidgetCocoaImpl* viewImpl,
*/ */
NSDragOperation sourceDragMask = [sender draggingSourceOperationMask]; 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]; NSPoint nspoint = [viewImpl->GetWXWidget() convertPoint:[sender draggingLocation] fromView:nil];
wxPoint pt = wxFromNSPoint( viewImpl->GetWXWidget(), nspoint ); wxPoint pt = wxFromNSPoint( viewImpl->GetWXWidget(), nspoint );
@@ -1345,9 +1343,7 @@ unsigned int wxOnDraggingEnteredOrUpdated(wxWidgetCocoaImpl* viewImpl,
else if (sourceDragMask & NSDragOperationLink) else if (sourceDragMask & NSDragOperationLink)
result = wxDragLink; result = wxDragLink;
PasteboardRef pboardRef; target->SetCurrentDragSource(&pb);
PasteboardCreate((CFStringRef)[pboard name], &pboardRef);
target->SetCurrentDragPasteboard(pboardRef);
if (entered) if (entered)
{ {
// Drag entered // Drag entered
@@ -1359,8 +1355,6 @@ unsigned int wxOnDraggingEnteredOrUpdated(wxWidgetCocoaImpl* viewImpl,
result = target->OnDragOver(pt.x, pt.y, result); result = target->OnDragOver(pt.x, pt.y, result);
} }
CFRelease(pboardRef);
NSDragOperation nsresult = NSDragOperationNone; NSDragOperation nsresult = NSDragOperationNone;
switch (result ) 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)) void wxWidgetCocoaImpl::draggingExited(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
{ {
id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
NSPasteboard *pboard = [sender draggingPasteboard];
wxWindow* wxpeer = GetWXPeer(); wxWindow* wxpeer = GetWXPeer();
if ( wxpeer == NULL ) if ( wxpeer == NULL )
return; return;
@@ -1402,11 +1393,11 @@ void wxWidgetCocoaImpl::draggingExited(void* s, WXWidget WXUNUSED(slf), void *WX
if ( target == NULL ) if ( target == NULL )
return; return;
PasteboardRef pboardRef; id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
PasteboardCreate((CFStringRef)[pboard name], &pboardRef); wxOSXPasteboard pb([sender draggingPasteboard]);
target->SetCurrentDragPasteboard(pboardRef);
target->SetCurrentDragSource(&pb);
target->OnLeave(); target->OnLeave();
CFRelease(pboardRef);
} }
unsigned int wxWidgetCocoaImpl::draggingUpdated(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd)) 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)) bool wxWidgetCocoaImpl::performDragOperation(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
{ {
id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s; wxWindow* wxpeer = GetWXPeer();
if ( wxpeer == NULL )
return false;
wxDropTarget* target = wxpeer->GetDropTarget();
if ( target == NULL )
return false;
NSPasteboard *pboard = [sender draggingPasteboard]; id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
wxOSXPasteboard pb([sender draggingPasteboard]);
NSDragOperation sourceDragMask = [sender draggingSourceOperationMask]; NSDragOperation sourceDragMask = [sender draggingSourceOperationMask];
wxWindow* wxpeer = GetWXPeer();
wxDropTarget* target = wxpeer->GetDropTarget();
wxDragResult result = wxDragNone; wxDragResult result = wxDragNone;
NSPoint nspoint = [m_osxView convertPoint:[sender draggingLocation] fromView:nil]; NSPoint nspoint = [m_osxView convertPoint:[sender draggingLocation] fromView:nil];
wxPoint pt = wxFromNSPoint( m_osxView, nspoint ); wxPoint pt = wxFromNSPoint( m_osxView, nspoint );
@@ -1435,15 +1430,11 @@ bool wxWidgetCocoaImpl::performDragOperation(void* s, WXWidget WXUNUSED(slf), vo
else if (sourceDragMask & NSDragOperationLink) else if (sourceDragMask & NSDragOperationLink)
result = wxDragLink; result = wxDragLink;
PasteboardRef pboardRef; target->SetCurrentDragSource(&pb);
PasteboardCreate((CFStringRef)[pboard name], &pboardRef);
target->SetCurrentDragPasteboard(pboardRef);
if (target->OnDrop(pt.x, pt.y)) if (target->OnDrop(pt.x, pt.y))
result = target->OnData(pt.x, pt.y, result); result = target->OnData(pt.x, pt.y, result);
CFRelease(pboardRef);
return result != wxDragNone; return result != wxDragNone;
} }
#endif // wxUSE_DRAG_AND_DROP #endif // wxUSE_DRAG_AND_DROP
@@ -3124,21 +3115,20 @@ void wxWidgetCocoaImpl::SetDropTarget(wxDropTarget* target)
{ {
[m_osxView unregisterDraggedTypes]; [m_osxView unregisterDraggedTypes];
if ( target == NULL ) if (target == NULL)
return; return;
wxDataObject* dobj = target->GetDataObject(); wxDataObject* dobj = target->GetDataObject();
if( dobj ) if (dobj)
{ {
CFMutableArrayRef typesarray = CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks); wxCFMutableArrayRef<CFStringRef> typesarray;
dobj->AddSupportedTypes(typesarray); dobj->AddSupportedTypes(typesarray);
NSView* targetView = m_osxView; NSView* targetView = m_osxView;
if ( [m_osxView isKindOfClass:[NSScrollView class] ] ) if ([m_osxView isKindOfClass:[NSScrollView class]])
targetView = [(NSScrollView*) m_osxView documentView]; targetView = [(NSScrollView*)m_osxView documentView];
[targetView registerForDraggedTypes:(NSArray*)typesarray]; [targetView registerForDraggedTypes:typesarray];
CFRelease(typesarray);
} }
} }
#endif // wxUSE_DRAG_AND_DROP #endif // wxUSE_DRAG_AND_DROP

View File

@@ -20,9 +20,10 @@
#endif #endif
#include "wx/osx/core/cfstring.h" #include "wx/osx/core/cfstring.h"
#include "wx/osx/core/cfdataref.h"
#include <CoreFoundation/CoreFoundation.h> #include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFData.h>
const wxString sCR((wxChar)13); const wxString sCR((wxChar)13);
const wxString sLF((wxChar)10); const wxString sLF((wxChar)10);
@@ -695,38 +696,3 @@ wxString wxCFStringRef::AsStringWithNormalizationFormC( NSString* ref, wxFontEnc
} }
#endif #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 ;
}

View File

@@ -134,9 +134,7 @@ bool wxSound::Create(const wxString& fileName, bool isResource)
{ {
wxCHECK_MSG( !isResource, false, "not implemented" ); wxCHECK_MSG( !isResource, false, "not implemented" );
wxCFRef<CFMutableStringRef> cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(fileName))); wxCFRef<CFURLRef> url(wxOSXCreateURLFromFileSystemPath(fileName));
CFStringNormalize(cfMutableString,kCFStringNormalizationFormD);
wxCFRef<CFURLRef> url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false));
SystemSoundID soundID; SystemSoundID soundID;
OSStatus err = AudioServicesCreateSystemSoundID(url, &soundID); OSStatus err = AudioServicesCreateSystemSoundID(url, &soundID);

View File

@@ -233,6 +233,41 @@ WXDLLIMPEXP_BASE wxMBConv* new_wxMBConv_cf(wxFontEncoding encoding)
return usedBufLen; 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__ #endif // __DARWIN__

View File

@@ -41,9 +41,6 @@
#include "wx/osx/core/cfstring.h" #include "wx/osx/core/cfstring.h"
#include "wx/osx/core/private.h" #include "wx/osx/core/private.h"
// Default path style
#define kDefaultPathStyle kCFURLPOSIXPathStyle
#if wxUSE_SOCKETS #if wxUSE_SOCKETS
// global pointer which lives in the base library, set from the net one (see // 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 // 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( CFURLCreateWithFileSystemPath(
kCFAllocatorDefault, kCFAllocatorDefault,
wxCFStringRef(path), wxCFStringRef(path),
kDefaultPathStyle, kCFURLPOSIXPathStyle,
true); //false == not a directory true); //false == not a directory
// Check for error from the CFURL // Check for error from the CFURL
@@ -163,7 +160,7 @@ bool wxMacLaunch(const char* const* argv)
cfurlCurrentFile = CFURLCreateWithFileSystemPath( cfurlCurrentFile = CFURLCreateWithFileSystemPath(
kCFAllocatorDefault, kCFAllocatorDefault,
wxCFStringRef(*argv), wxCFStringRef(*argv),
kDefaultPathStyle, kCFURLPOSIXPathStyle,
true); //true == directory true); //true == directory
} }
else if(argfn.FileExists()) else if(argfn.FileExists())
@@ -173,7 +170,7 @@ bool wxMacLaunch(const char* const* argv)
cfurlCurrentFile = CFURLCreateWithFileSystemPath( cfurlCurrentFile = CFURLCreateWithFileSystemPath(
kCFAllocatorDefault, kCFAllocatorDefault,
wxCFStringRef(*argv), wxCFStringRef(*argv),
kDefaultPathStyle, kCFURLPOSIXPathStyle,
false); //false == regular file false); //false == regular file
} }
else else

View File

@@ -13,6 +13,7 @@
#if wxUSE_DRAG_AND_DROP #if wxUSE_DRAG_AND_DROP
#include "wx/dnd.h" #include "wx/dnd.h"
#include "wx/scopedarray.h"
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/app.h" #include "wx/app.h"
@@ -73,8 +74,8 @@ bool wxDropTarget::CurrentDragHasSupportedFormat()
if ( data ) if ( data )
{ {
size_t formatcount = data->GetFormatCount(); size_t formatcount = data->GetFormatCount();
wxDataFormat *array = new wxDataFormat[formatcount]; wxScopedArray<wxDataFormat> array(formatcount);
data->GetAllFormats( array ); data->GetAllFormats( array.get() );
for (size_t i = 0; !supported && i < formatcount; i++) for (size_t i = 0; !supported && i < formatcount; i++)
{ {
wxDataFormat format = array[i]; wxDataFormat format = array[i];
@@ -84,14 +85,12 @@ bool wxDropTarget::CurrentDragHasSupportedFormat()
break; break;
} }
} }
delete [] array;
} }
} }
if ( !supported ) if ( !supported )
{ {
supported = m_dataObject->HasDataInPasteboard( m_currentDragPasteboard ); supported = m_dataObject->CanReadFromSource( m_currentDragPasteboard );
} }
return supported; return supported;
@@ -113,8 +112,8 @@ bool wxDropTarget::GetData()
if (data != NULL) if (data != NULL)
{ {
size_t formatcount = data->GetFormatCount(); size_t formatcount = data->GetFormatCount();
wxDataFormat *array = new wxDataFormat[formatcount]; wxScopedArray<wxDataFormat> array(formatcount);
data->GetAllFormats( array ); data->GetAllFormats( array.get() );
for (size_t i = 0; !transferred && i < formatcount; i++) for (size_t i = 0; !transferred && i < formatcount; i++)
{ {
wxDataFormat format = array[i]; wxDataFormat format = array[i];
@@ -135,14 +134,12 @@ bool wxDropTarget::GetData()
} }
} }
} }
delete [] array;
} }
} }
if ( !transferred ) if ( !transferred )
{ {
transferred = m_dataObject->GetFromPasteboard( m_currentDragPasteboard ); transferred = m_dataObject->ReadFromSource(m_currentDragPasteboard);
} }
return transferred; return transferred;

View File

@@ -19,6 +19,8 @@
#include "wx/fswatcher.h" #include "wx/fswatcher.h"
#include "wx/osx/core/cfstring.h" #include "wx/osx/core/cfstring.h"
#include "wx/osx/core/private/strconv_cf.h"
#include <CoreFoundation/CoreFoundation.h> #include <CoreFoundation/CoreFoundation.h>
// A small class that we will give the FSEvents // A small class that we will give the FSEvents

View File

@@ -65,9 +65,7 @@ bool wxLaunchDefaultApplication(const wxString& document, int flags)
{ {
wxUnusedVar(flags); wxUnusedVar(flags);
wxCFRef<CFMutableStringRef> cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(document))); wxCFRef<CFURLRef> curl(wxOSXCreateURLFromFileSystemPath(document));
CFStringNormalize(cfMutableString,kCFStringNormalizationFormD);
wxCFRef<CFURLRef> curl(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false));
OSStatus err = LSOpenCFURLRef( curl , NULL ); OSStatus err = LSOpenCFURLRef( curl , NULL );
if (err == noErr) if (err == noErr)