X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/88a7a4e10ed18f81a576dcd866cfbf02bf404c00..f5d7fd083771b7fee5524f0503f17bda8cf07e85:/src/mac/carbon/clipbrd.cpp diff --git a/src/mac/carbon/clipbrd.cpp b/src/mac/carbon/clipbrd.cpp index f884aae4f7..99a8fba35c 100644 --- a/src/mac/carbon/clipbrd.cpp +++ b/src/mac/carbon/clipbrd.cpp @@ -2,7 +2,7 @@ // Name: src/mac/carbon/clipbrd.cpp // Purpose: Clipboard functionality // Author: Stefan Csomor; -// Generalized clipboard implementation by Matthew Flatt +// Generalized clipboard implementation by Matthew Flatt // Modified by: // Created: 1998-01-01 // RCS-ID: $Id$ @@ -18,18 +18,14 @@ #ifndef WX_PRECOMP #include "wx/intl.h" + #include "wx/log.h" + #include "wx/app.h" + #include "wx/utils.h" + #include "wx/frame.h" + #include "wx/bitmap.h" #endif -#include "wx/app.h" -#include "wx/frame.h" -#include "wx/bitmap.h" -#include "wx/utils.h" #include "wx/metafile.h" -#include "wx/log.h" - -#ifndef __DARWIN__ -#include -#endif #include "wx/mac/uma.h" @@ -43,150 +39,90 @@ // (there will be a *lot* of them!) static const wxChar *TRACE_CLIPBOARD = wxT("clipboard"); +IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject) + +// in order to keep the binary interface the same this class +// serves just to have a few additional member variables inside +// the clipboard class -void * wxGetClipboardData( wxDataFormat dataFormat, long *len ) +class wxMacBinaryCompatHelper : public wxDataObject { - OSStatus err = noErr; - void * data = NULL; - Size byteCount; - - switch (dataFormat.GetType()) +public : + wxMacBinaryCompatHelper() { - case wxDF_OEMTEXT: - dataFormat = wxDF_TEXT; - break; - - case wxDF_TEXT: - case wxDF_UNICODETEXT: - break; - - case wxDF_BITMAP: - case wxDF_METAFILE: - break; - - default: - // custom datatype - break; + m_trueData = NULL; } -#if TARGET_CARBON - ScrapRef scrapRef; - - err = GetCurrentScrap( &scrapRef ); - if ( err != noTypeErr && err != memFullErr ) + ~wxMacBinaryCompatHelper() { - ScrapFlavorFlags flavorFlags; + if (m_trueData != NULL) + { + delete m_trueData; + m_trueData = NULL; + } + } - err = GetScrapFlavorFlags( scrapRef, dataFormat.GetFormatId(), &flavorFlags ); - if (err == noErr) + virtual wxDataFormat GetPreferredFormat(Direction dir = Get) const { - err = GetScrapFlavorSize( scrapRef, dataFormat.GetFormatId(), &byteCount ); - if (err == noErr) - { - Size allocSize = byteCount; - if ( dataFormat.GetType() == wxDF_TEXT ) - allocSize += 1; - else if ( dataFormat.GetType() == wxDF_UNICODETEXT ) - allocSize += 2; - - data = new char[ allocSize ]; + return wxDataFormat(); + } - if (( err = GetScrapFlavorData( scrapRef, dataFormat.GetFormatId(), &byteCount , data )) == noErr ) + virtual size_t GetFormatCount(Direction dir = Get) const { - *len = allocSize; - if ( dataFormat.GetType() == wxDF_TEXT ) - ((char*)data)[ byteCount ] = 0; - if ( dataFormat.GetType() == wxDF_UNICODETEXT ) - { - // "data" format is UTF16, so 2 bytes = one character - // wxChar size depends on platform, so just clear last 2 bytes - ((char*)data)[ byteCount + 0 ] = - ((char*)data)[ byteCount + 1 ] = 0; + return 0; } - } - else + + virtual void GetAllFormats(wxDataFormat *formats, + Direction dir = Get) const { - delete [] (char*)data; - data = NULL; - } - } - } } -#else - long offset; - Handle datahandle = NewHandle( 0 ); - HLock( datahandle ); - err = (OSStatus)GetScrap( datahandle, dataFormat.GetFormatId(), &offset ); - HUnlock( datahandle ); - if ( GetHandleSize( datahandle ) > 0 ) + virtual size_t GetDataSize(const wxDataFormat& format) const { - byteCount = GetHandleSize( datahandle ); - Size allocSize = byteCount; - if ( dataFormat.GetType() == wxDF_TEXT ) - allocSize += 1; - else if ( dataFormat.GetType() == wxDF_UNICODETEXT ) - allocSize += 2; - - data = new char[ allocSize ]; - - memcpy( (char*) data, (char*) *datahandle, byteCount ); - if ( dataFormat.GetType() == wxDF_TEXT ) - ((char*)data)[ byteCount ] = 0; - else if ( dataFormat.GetType() == wxDF_UNICODETEXT ) - ((wxChar*)data)[ byteCount / 2 ] = 0; - *len = byteCount; + return 0; } - DisposeHandle( datahandle ); -#endif - - if (err != noErr) + virtual bool GetDataHere(const wxDataFormat& format, void *buf) const { - wxLogSysError(wxT("Failed to get clipboard data.")); - - return NULL; + return false; } - if (dataFormat.GetType() == wxDF_TEXT) - wxMacConvertNewlines10To13( (char*)data ); + // only relevant from here on - return data; -} + wxDataObject* m_trueData; + wxCFRef m_pasteboard; +}; -IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject) +#define M_CLIPBOARD ((wxMacBinaryCompatHelper*)m_data) wxClipboard::wxClipboard() { m_open = false; - m_data = NULL; + m_data = new wxMacBinaryCompatHelper() ; + PasteboardRef clipboard = 0; + OSStatus err = PasteboardCreate( kPasteboardClipboard, &clipboard ); + if (err != noErr) + { + wxLogSysError( wxT("Failed to create the clipboard.") ); + } + M_CLIPBOARD->m_pasteboard.reset(clipboard); } wxClipboard::~wxClipboard() { - if (m_data != NULL) - { + M_CLIPBOARD->m_pasteboard.reset((PasteboardRef)0); delete m_data; - m_data = NULL; - } } void wxClipboard::Clear() { - if (m_data != NULL) + if (M_CLIPBOARD->m_trueData != NULL) { - delete m_data; - m_data = NULL; + delete M_CLIPBOARD->m_trueData; + M_CLIPBOARD->m_trueData = NULL; } -#if TARGET_CARBON - OSStatus err; - err = ClearCurrentScrap(); -#else - OSErr err; - err = ZeroScrap(); -#endif - + OSStatus err = PasteboardClear( M_CLIPBOARD->m_pasteboard ); if (err != noErr) { wxLogSysError( wxT("Failed to empty the clipboard.") ); @@ -214,6 +150,9 @@ bool wxClipboard::IsOpened() const bool wxClipboard::SetData( wxDataObject *data ) { + if ( IsUsingPrimarySelection() ) + return false; + wxCHECK_MSG( m_open, false, wxT("clipboard not open") ); wxCHECK_MSG( data, false, wxT("data is invalid") ); @@ -226,78 +165,22 @@ bool wxClipboard::SetData( wxDataObject *data ) bool wxClipboard::AddData( wxDataObject *data ) { + if ( IsUsingPrimarySelection() ) + return false; + wxCHECK_MSG( m_open, false, wxT("clipboard not open") ); wxCHECK_MSG( data, false, wxT("data is invalid") ); // we can only store one wxDataObject Clear(); - m_data = data; + PasteboardSyncFlags syncFlags = PasteboardSynchronize( M_CLIPBOARD->m_pasteboard ); + wxCHECK_MSG( !(syncFlags&kPasteboardModified), false, wxT("clipboard modified after clear") ); + wxCHECK_MSG( (syncFlags&kPasteboardClientIsOwner), false, wxT("client couldn't own clipboard") ); - // get formats from wxDataObjects - wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ]; - m_data->GetAllFormats( array ); + M_CLIPBOARD->m_trueData = data; - for (size_t i = 0; i < m_data->GetFormatCount(); i++) - { - if (array[i].IsStandard()) - { - wxLogTrace( TRACE_CLIPBOARD, - wxT("wxClipboard now supports standard atom type %d"), - array[i].GetType() ); - } - else - { - wxLogTrace( TRACE_CLIPBOARD, - wxT("wxClipboard now supports atom %s"), - array[i].GetId().c_str() ); - } - - size_t sz = data->GetDataSize( array[ i ] ); - void* buf = malloc( sz + 1 ); - if ( buf != NULL ) - { - // empty the buffer because in some case GetDataHere does not fill buf - memset( buf, 0, sz + 1 ); - data->GetDataHere( array[ i ], buf ); - OSType mactype = 0; - switch ( array[i].GetType() ) - { - case wxDF_TEXT: - case wxDF_OEMTEXT: - mactype = kScrapFlavorTypeText; - sz -= 1; - break; - -#if wxUSE_UNICODE - case wxDF_UNICODETEXT: - mactype = kScrapFlavorTypeUnicode; - sz -= 2; - break; -#endif - -#if wxUSE_DRAG_AND_DROP - case wxDF_METAFILE: - mactype = kScrapFlavorTypePicture; - break; -#endif - - case wxDF_BITMAP: - case wxDF_DIB: - mactype = kScrapFlavorTypePicture; - break; - - default: - mactype = (OSType)(array[ i ].GetFormatId()); - break; - } - - UMAPutScrap( sz , mactype , buf ); - free( buf ); - } - } - - delete [] array; + data->AddToPasteboard( M_CLIPBOARD->m_pasteboard, 1 ); return true; } @@ -311,65 +194,25 @@ void wxClipboard::Close() // Get rid of cached object. // If this is not done, copying data from // another application will only work once - if (m_data) + if (M_CLIPBOARD->m_trueData) { - delete m_data; - m_data = (wxDataObject*) NULL; + delete M_CLIPBOARD->m_trueData; + M_CLIPBOARD->m_trueData = (wxDataObject*) NULL; } } bool wxClipboard::IsSupported( const wxDataFormat &dataFormat ) { - if ( m_data ) - return m_data->IsSupported( dataFormat ); - - bool hasData = false; - -#if TARGET_CARBON - OSStatus err = noErr; - ScrapRef scrapRef; - - err = GetCurrentScrap( &scrapRef ); - if ( err != noTypeErr && err != memFullErr ) - { - ScrapFlavorFlags flavorFlags; - Size byteCount; - - err = GetScrapFlavorFlags( scrapRef, dataFormat.GetFormatId(), &flavorFlags ); - if (err == noErr) - { - err = GetScrapFlavorSize( scrapRef, dataFormat.GetFormatId(), &byteCount ); - if (err == noErr) - hasData = true; - } - else if ( dataFormat.GetType() == wxDF_UNICODETEXT ) - { - err = GetScrapFlavorFlags( scrapRef, 'TEXT', &flavorFlags ); - if (err == noErr) - { - err = GetScrapFlavorSize( scrapRef, 'TEXT', &byteCount ); - if (err == noErr) - hasData = true; - } - } - } - -#else - - long offset = 0; - Handle datahandle = NewHandle( 0 ); - HLock( datahandle ); - GetScrap( datahandle, dataFormat.GetFormatId(), &offset ); - HUnlock( datahandle ); - hasData = GetHandleSize( datahandle ) > 0; - DisposeHandle( datahandle ); -#endif - - return hasData; + if ( M_CLIPBOARD->m_trueData ) + return M_CLIPBOARD->m_trueData->IsSupported( dataFormat ); + return wxDataObject::IsFormatInPasteboard( M_CLIPBOARD->m_pasteboard, dataFormat ); } bool wxClipboard::GetData( wxDataObject& data ) { + if ( IsUsingPrimarySelection() ) + return false; + wxCHECK_MSG( m_open, false, wxT("clipboard not open") ); size_t formatcount = data.GetFormatCount() + 1; @@ -379,14 +222,14 @@ bool wxClipboard::GetData( wxDataObject& data ) bool transferred = false; - if ( m_data ) + if ( M_CLIPBOARD->m_trueData ) { for (size_t i = 0; !transferred && i < formatcount; i++) { wxDataFormat format = array[ i ]; - if ( m_data->IsSupported( format ) ) + if ( M_CLIPBOARD->m_trueData->IsSupported( format ) ) { - int dataSize = m_data->GetDataSize( format ); + int dataSize = M_CLIPBOARD->m_trueData->GetDataSize( format ); transferred = true; if (dataSize == 0) @@ -396,7 +239,7 @@ bool wxClipboard::GetData( wxDataObject& data ) else { char *d = new char[ dataSize ]; - m_data->GetDataHere( format, (void*)d ); + M_CLIPBOARD->m_trueData->GetDataHere( format, (void*)d ); data.SetData( format, dataSize, d ); delete [] d; } @@ -407,33 +250,7 @@ bool wxClipboard::GetData( wxDataObject& data ) // get formats from wxDataObjects if ( !transferred ) { - for (size_t i = 0; !transferred && i < formatcount; i++) - { - wxDataFormat format = array[ i ]; - - switch ( format.GetType() ) - { - // NOTE: this is usable for all data types - case wxDF_TEXT: - case wxDF_UNICODETEXT: - case wxDF_OEMTEXT: - case wxDF_BITMAP: - case wxDF_METAFILE: - default: - { - long len; - char* s = (char*)wxGetClipboardData( format, &len ); - if (s != NULL) - { - data.SetData( format, len, s ); - delete [] s; - - transferred = true; - } - } - break; - } - } + transferred = data.GetFromPasteboard( M_CLIPBOARD->m_pasteboard ) ; } delete [] array;