X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/99b62b5ffc006137f1bee20f6618ed7a0b7871e1..f5d7fd083771b7fee5524f0503f17bda8cf07e85:/src/mac/carbon/clipbrd.cpp diff --git a/src/mac/carbon/clipbrd.cpp b/src/mac/carbon/clipbrd.cpp index 1252a067fc..99a8fba35c 100644 --- a/src/mac/carbon/clipbrd.cpp +++ b/src/mac/carbon/clipbrd.cpp @@ -1,7 +1,8 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: clipbrd.cpp +// Name: src/mac/carbon/clipbrd.cpp // Purpose: Clipboard functionality -// Author: Stefan Csomor +// Author: Stefan Csomor; +// Generalized clipboard implementation by Matthew Flatt // Modified by: // Created: 1998-01-01 // RCS-ID: $Id$ @@ -9,202 +10,137 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma implementation "clipbrd.h" -#endif - #include "wx/wxprec.h" #if wxUSE_CLIPBOARD -#include "wx/app.h" -#include "wx/frame.h" -#include "wx/bitmap.h" -#include "wx/utils.h" -#include "wx/metafile.h" #include "wx/clipbrd.h" -#include "wx/intl.h" -#include "wx/log.h" -#ifndef __DARWIN__ -#include +#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/metafile.h" + #include "wx/mac/uma.h" #define wxUSE_DATAOBJ 1 #include + // the trace mask we use with wxLogTrace() - call // wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here // (there will be a *lot* of them!) -static const wxChar *TRACE_CLIPBOARD = _T("clipboard"); +static const wxChar *TRACE_CLIPBOARD = wxT("clipboard"); -void *wxGetClipboardData(wxDataFormat dataFormat, long *len) -{ -#if !TARGET_CARBON - OSErr err = noErr ; -#else - OSStatus err = noErr ; -#endif - void * data = NULL ; - Size byteCount; +IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject) - switch (dataFormat.GetType()) +// in order to keep the binary interface the same this class +// serves just to have a few additional member variables inside +// the clipboard class + +class wxMacBinaryCompatHelper : public wxDataObject +{ +public : + wxMacBinaryCompatHelper() { - case wxDF_OEMTEXT: - dataFormat = wxDF_TEXT; - // fall through - - case wxDF_TEXT: - break; - case wxDF_UNICODETEXT: - break; - case wxDF_BITMAP : - case wxDF_METAFILE : - break ; - default: - { - wxLogError(_("Unsupported clipboard format.")); - return NULL; - } + 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; + } + } - if (( err = GetScrapFlavorFlags( scrapRef, dataFormat.GetFormatId(), &flavorFlags )) == noErr) + virtual wxDataFormat GetPreferredFormat(Direction dir = Get) const { - if (( err = GetScrapFlavorSize( scrapRef, dataFormat.GetFormatId(), &byteCount )) == 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 ) ; - GetScrap( datahandle , dataFormat.GetFormatId() , &offset ) ; - HUnlock( datahandle ) ; - if ( GetHandleSize( datahandle ) > 0 ) - { - 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 ; - if ( dataFormat.GetType() == wxDF_UNICODETEXT ) - ((wxChar*)data)[byteCount/2] = 0 ; - *len = byteCount ; - } - DisposeHandle( datahandle ) ; -#endif - if ( err ) + virtual size_t GetDataSize(const wxDataFormat& format) const { - wxLogSysError(_("Failed to get clipboard data.")); - - return NULL ; + return 0; } - if ( dataFormat.GetType() == wxDF_TEXT ) + virtual bool GetDataHere(const wxDataFormat& format, void *buf) const { - wxMacConvertNewlines10To13( (char*) data ) ; + return false; } - return data; -} + // only relevant from here on + wxDataObject* m_trueData; + wxCFRef m_pasteboard; +}; -/* - * Generalized clipboard implementation by Matthew Flatt - */ - -IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject) +#define M_CLIPBOARD ((wxMacBinaryCompatHelper*)m_data) wxClipboard::wxClipboard() { - m_open = false ; - m_data = NULL ; + m_open = false; + 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) - { + M_CLIPBOARD->m_pasteboard.reset((PasteboardRef)0); delete m_data; - m_data = (wxDataObject*) NULL; - } } void wxClipboard::Clear() { - if (m_data) + if (M_CLIPBOARD->m_trueData != NULL) { - delete m_data; - m_data = (wxDataObject*) NULL; + delete M_CLIPBOARD->m_trueData; + M_CLIPBOARD->m_trueData = NULL; } -#if TARGET_CARBON - OSStatus err ; - err = ClearCurrentScrap( ); -#else - OSErr err ; - err = ZeroScrap( ); -#endif - if ( err ) + + OSStatus err = PasteboardClear( M_CLIPBOARD->m_pasteboard ); + if (err != noErr) { - wxLogSysError(_("Failed to empty the clipboard.")); + wxLogSysError( wxT("Failed to empty the clipboard.") ); } } bool wxClipboard::Flush() { - return FALSE; + return false; } bool wxClipboard::Open() { - wxCHECK_MSG( !m_open, FALSE, wxT("clipboard already open") ); - m_open = true ; - return true ; + wxCHECK_MSG( !m_open, false, wxT("clipboard already open") ); + + m_open = true; + + return true; } bool wxClipboard::IsOpened() const @@ -214,204 +150,112 @@ bool wxClipboard::IsOpened() const bool wxClipboard::SetData( wxDataObject *data ) { - wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") ); + if ( IsUsingPrimarySelection() ) + return false; - wxCHECK_MSG( data, FALSE, wxT("data is invalid") ); + wxCHECK_MSG( m_open, false, wxT("clipboard not open") ); + wxCHECK_MSG( data, false, wxT("data is invalid") ); Clear(); - // as we can only store one wxDataObject, this is the same in this - // implementation + + // as we can only store one wxDataObject, + // this is the same in this implementation return AddData( data ); } bool wxClipboard::AddData( wxDataObject *data ) { - wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") ); + if ( IsUsingPrimarySelection() ) + return false; - wxCHECK_MSG( data, FALSE, wxT("data is invalid") ); + wxCHECK_MSG( m_open, false, wxT("clipboard not open") ); + wxCHECK_MSG( data, false, wxT("data is invalid") ); - /* we can only store one wxDataObject */ + // 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++) - { - 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 ) - { - // 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: - break ; - } - UMAPutScrap( sz , mactype , buf ) ; - free( buf ) ; - } - } - - delete[] array; + data->AddToPasteboard( M_CLIPBOARD->m_pasteboard, 1 ); - return true ; + return true; } void wxClipboard::Close() { wxCHECK_RET( m_open, wxT("clipboard not open") ); - m_open = false ; - - // Get rid of cached object. If this is not done copying from another application will - // only work once - if (m_data) + m_open = false; + + // Get rid of cached object. + // If this is not done, copying data from + // another application will only work once + 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 ) ; - } -#if TARGET_CARBON - OSStatus err = noErr; - ScrapRef scrapRef; - - err = GetCurrentScrap( &scrapRef ); - if ( err != noTypeErr && err != memFullErr ) - { - ScrapFlavorFlags flavorFlags; - Size byteCount; - - if (( err = GetScrapFlavorFlags( scrapRef, dataFormat.GetFormatId(), &flavorFlags )) == noErr) - { - if (( err = GetScrapFlavorSize( scrapRef, dataFormat.GetFormatId(), &byteCount )) == noErr) - { - return TRUE ; - } - } - } - return FALSE; - -#else - long offset ; - Handle datahandle = NewHandle(0) ; - HLock( datahandle ) ; - GetScrap( datahandle , dataFormat.GetFormatId() , &offset ) ; - HUnlock( datahandle ) ; - bool hasData = GetHandleSize( datahandle ) > 0 ; - DisposeHandle( datahandle ) ; - return hasData ; -#endif + 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 ) { - wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") ); + if ( IsUsingPrimarySelection() ) + return false; - size_t formatcount = data.GetFormatCount() + 1 ; - wxDataFormat *array = new wxDataFormat[ formatcount ]; + wxCHECK_MSG( m_open, false, wxT("clipboard not open") ); + + size_t formatcount = data.GetFormatCount() + 1; + wxDataFormat *array = new wxDataFormat[ formatcount ]; array[0] = data.GetPreferredFormat(); data.GetAllFormats( &array[1] ); - bool transferred = false ; + 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 ) ) - { - int size = m_data->GetDataSize( format ); - transferred = true ; - - if (size == 0) - { - data.SetData(format , 0 , 0 ) ; - } - else + for (size_t i = 0; !transferred && i < formatcount; i++) + { + wxDataFormat format = array[ i ]; + if ( M_CLIPBOARD->m_trueData->IsSupported( format ) ) { - char *d = new char[size]; - m_data->GetDataHere( format , (void*) d ); - data.SetData( format , size , d ) ; - delete[] d ; + int dataSize = M_CLIPBOARD->m_trueData->GetDataSize( format ); + transferred = true; + + if (dataSize == 0) + { + data.SetData( format, 0, 0 ); + } + else + { + char *d = new char[ dataSize ]; + M_CLIPBOARD->m_trueData->GetDataHere( format, (void*)d ); + data.SetData( format, dataSize, d ); + delete [] d; + } } - } - } + } } - /* get formats from wxDataObjects */ + + // get formats from wxDataObjects if ( !transferred ) { - for (size_t i = 0; !transferred && i < formatcount ; i++) - { - wxDataFormat format = array[i] ; - - switch ( format.GetType() ) - { - case wxDF_TEXT : - case wxDF_UNICODETEXT: - case wxDF_OEMTEXT : - case wxDF_BITMAP : - case wxDF_METAFILE : - { - long len ; - char* s = (char*)wxGetClipboardData(format, &len ); - if ( s ) - { - data.SetData( format , len , s ) ; - delete [] s; - - transferred = true ; - } - } - break ; - - default : - break ; - } - } + transferred = data.GetFromPasteboard( M_CLIPBOARD->m_pasteboard ) ; } - delete[] array ; - return transferred ; + delete [] array; + + return transferred; } #endif