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:
@@ -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
|
||||
|
||||
|
@@ -12,8 +12,6 @@
|
||||
#ifndef __WX_CFSTRINGHOLDER_H__
|
||||
#define __WX_CFSTRINGHOLDER_H__
|
||||
|
||||
#include <CoreFoundation/CFString.h>
|
||||
|
||||
#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__
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <CoreFoundation/CFString.h>
|
||||
#include <CoreFoundation/CFStringEncodingExt.h>
|
||||
#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 ;
|
||||
};
|
||||
|
@@ -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,8 +43,8 @@ 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);
|
||||
|
||||
@@ -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
|
||||
|
@@ -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
|
||||
};
|
||||
|
||||
|
@@ -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 ;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
@@ -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"
|
||||
|
113
include/wx/osx/private/datatransfer.h
Normal file
113
include/wx/osx/private/datatransfer.h
Normal 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
|
@@ -27,6 +27,7 @@
|
||||
|
||||
#ifdef __WXMAC__
|
||||
#include "wx/osx/core/cfstring.h"
|
||||
#include <CoreFoundation/CFString.h>
|
||||
#include <CoreFoundation/CFStringEncodingExt.h>
|
||||
|
||||
wxUint16 gMacEncodings[wxFONTENCODING_MACMAX-wxFONTENCODING_MACMIN+1][128] ;
|
||||
|
@@ -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<CFURLRef> 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<CFMutableStringRef> cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(path)));
|
||||
CFStringNormalize(cfMutableString,kCFStringNormalizationFormD);
|
||||
return CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false);
|
||||
}
|
||||
|
||||
#ifndef __LP64__
|
||||
|
||||
wxString wxMacFSSpec2MacFilename( const FSSpec *spec )
|
||||
|
@@ -66,9 +66,10 @@
|
||||
|
||||
#if defined(__WXOSX__)
|
||||
#include "wx/osx/core/cfref.h"
|
||||
#include "wx/osx/core/cfstring.h"
|
||||
#include <CoreFoundation/CFLocale.h>
|
||||
#include <CoreFoundation/CFDateFormatter.h>
|
||||
#include "wx/osx/core/cfstring.h"
|
||||
#include <CoreFoundation/CFString.h>
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@@ -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<wxDataFormat> 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;
|
||||
}
|
||||
|
||||
|
@@ -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,419 +232,248 @@ bool wxDataObject::IsSupportedFormat( const wxDataFormat& rFormat, Direction vDi
|
||||
}
|
||||
else
|
||||
{
|
||||
wxDataFormat *pFormats = new wxDataFormat[nFormatCount];
|
||||
GetAllFormats( pFormats, vDir );
|
||||
wxScopedArray<wxDataFormat> 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<wxDataFormat> 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<wxDataFormat> 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 ];
|
||||
wxCFMutableArrayRef<CFStringRef> typesarray;
|
||||
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;
|
||||
CFArrayRef flavorTypeArray = NULL;
|
||||
CFIndex flavorCount = 0;
|
||||
wxScopedPtr<const wxOSXDataSourceItem> sitem(source->GetItem(itemIndex));
|
||||
|
||||
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++ )
|
||||
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());
|
||||
wxMBConvUTF16 UTF16Converter;
|
||||
|
||||
if (!result)
|
||||
continue;
|
||||
wxString s((char*)buf, wxConvUTF8, flavorDataSize);
|
||||
|
||||
wxCFRef<CFURLRef> dest(CFURLCreateFromFileSystemRepresentation(NULL,(const UInt8*)result,strlen(result),true));
|
||||
PasteboardSetPasteLocation(pasteboard, dest);
|
||||
pastelocationset = true;
|
||||
}
|
||||
}
|
||||
else if ( flavorFormat.GetType() != wxDF_PRIVATE )
|
||||
{
|
||||
// indicate the expected format for the type, benefiting from native conversions eg utf8 -> utf16
|
||||
flavorType = (CFStringRef) wxDataFormat( flavorFormat.GetType()).GetFormatId();
|
||||
}
|
||||
|
||||
err = PasteboardCopyItemFlavorData( pasteboard, itemID, flavorType , &flavorData );
|
||||
if ( err == noErr )
|
||||
{
|
||||
flavorDataSize = CFDataGetLength( flavorData );
|
||||
if (dataFormat.GetType() == wxDF_FILENAME )
|
||||
{
|
||||
// revert the translation and decomposition to arrive at a proper utf8 string again
|
||||
CFURLRef url = CFURLCreateWithBytes( kCFAllocatorDefault, CFDataGetBytePtr( flavorData ), flavorDataSize, kCFStringEncodingUTF8, NULL );
|
||||
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");
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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<wxDataFormat> 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 );
|
||||
wxString filenamesPassed;
|
||||
|
||||
OSStatus err = PasteboardGetItemCount( pasteboard, &itemCount );
|
||||
if ( err == noErr )
|
||||
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);
|
||||
wxScopedArray<wxDataFormat> array(GetFormatCount());
|
||||
GetAllFormats(array.get(), wxDataObject::Set);
|
||||
|
||||
for (size_t i = 0; i < nFormats; i++)
|
||||
{
|
||||
wxDataFormat dataFormat = array[ i ];
|
||||
array[i].AddSupportedTypes(cfarray);
|
||||
|
||||
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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@@ -95,9 +95,7 @@ wxMetafileRefData::wxMetafileRefData( const wxString& filename )
|
||||
|
||||
if ( !filename.empty() )
|
||||
{
|
||||
wxCFRef<CFMutableStringRef> cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(filename)));
|
||||
CFStringNormalize(cfMutableString,kCFStringNormalizationFormD);
|
||||
wxCFRef<CFURLRef> url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false));
|
||||
wxCFRef<CFURLRef> url(wxOSXCreateURLFromFileSystemPath(filename));
|
||||
m_pdfDoc.reset(CGPDFDocumentCreateWithURL(url));
|
||||
}
|
||||
}
|
||||
|
@@ -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<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;
|
||||
|
||||
wxDragResult NSDragOperationToWxDragResult(NSDragOperation code)
|
||||
@@ -230,23 +443,13 @@ wxDragResult wxDropSource::DoDragDrop(int flags)
|
||||
NSView* view = m_window->GetPeer()->GetWXWidget();
|
||||
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;
|
||||
PasteboardRef pboardRef;
|
||||
PasteboardCreate((CFStringRef)[pboard name], &pboardRef);
|
||||
|
||||
err = PasteboardClear( pboardRef );
|
||||
if ( err != noErr )
|
||||
{
|
||||
CFRelease( pboardRef );
|
||||
return wxDragNone;
|
||||
}
|
||||
PasteboardSynchronize( pboardRef );
|
||||
|
||||
m_data->AddToPasteboard( pboardRef, 1 );
|
||||
dragPasteboard.Flush();
|
||||
|
||||
NSEvent* theEvent = (NSEvent*)wxTheApp->MacGetCurrentEvent();
|
||||
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];
|
||||
|
||||
|
||||
DropSourceDelegate* delegate = [[DropSourceDelegate alloc] init];
|
||||
[delegate setImplementation:this flags:flags];
|
||||
[view dragImage:image at:p offset:NSMakeSize(0.0,0.0)
|
||||
|
@@ -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 <NSDraggingInfo>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 <NSDraggingInfo>sender = (id <NSDraggingInfo>) 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 <NSDraggingInfo>sender = (id <NSDraggingInfo>) 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 <NSDraggingInfo>sender = (id <NSDraggingInfo>) 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 <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];
|
||||
|
||||
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
|
||||
@@ -3124,21 +3115,20 @@ 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<CFStringRef> 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
|
||||
|
@@ -20,9 +20,10 @@
|
||||
#endif
|
||||
|
||||
#include "wx/osx/core/cfstring.h"
|
||||
#include "wx/osx/core/cfdataref.h"
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
#include <CoreFoundation/CFData.h>
|
||||
|
||||
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 ;
|
||||
}
|
||||
|
@@ -134,9 +134,7 @@ bool wxSound::Create(const wxString& fileName, bool isResource)
|
||||
{
|
||||
wxCHECK_MSG( !isResource, false, "not implemented" );
|
||||
|
||||
wxCFRef<CFMutableStringRef> cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(fileName)));
|
||||
CFStringNormalize(cfMutableString,kCFStringNormalizationFormD);
|
||||
wxCFRef<CFURLRef> url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false));
|
||||
wxCFRef<CFURLRef> url(wxOSXCreateURLFromFileSystemPath(fileName));
|
||||
|
||||
SystemSoundID soundID;
|
||||
OSStatus err = AudioServicesCreateSystemSoundID(url, &soundID);
|
||||
|
@@ -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__
|
||||
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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<wxDataFormat> 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<wxDataFormat> 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;
|
||||
|
@@ -19,6 +19,8 @@
|
||||
|
||||
#include "wx/fswatcher.h"
|
||||
#include "wx/osx/core/cfstring.h"
|
||||
#include "wx/osx/core/private/strconv_cf.h"
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
// A small class that we will give the FSEvents
|
||||
|
@@ -65,9 +65,7 @@ bool wxLaunchDefaultApplication(const wxString& document, int flags)
|
||||
{
|
||||
wxUnusedVar(flags);
|
||||
|
||||
wxCFRef<CFMutableStringRef> cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(document)));
|
||||
CFStringNormalize(cfMutableString,kCFStringNormalizationFormD);
|
||||
wxCFRef<CFURLRef> curl(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false));
|
||||
wxCFRef<CFURLRef> curl(wxOSXCreateURLFromFileSystemPath(document));
|
||||
OSStatus err = LSOpenCFURLRef( curl , NULL );
|
||||
|
||||
if (err == noErr)
|
||||
|
Reference in New Issue
Block a user