1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/mac/classic/clipbrd.cpp 
   3 // Purpose:     Clipboard functionality 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #include "wx/wxprec.h" 
  14 #include "wx/clipbrd.h" 
  22     #include "wx/bitmap.h" 
  25 #include "wx/metafile.h" 
  30 #include "wx/mac/uma.h" 
  32 #define wxUSE_DATAOBJ 1 
  36 // the trace mask we use with wxLogTrace() - call 
  37 // wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here 
  38 // (there will be a *lot* of them!) 
  39 static const wxChar 
*TRACE_CLIPBOARD 
= _T("clipboard"); 
  41 void *wxGetClipboardData(wxDataFormat dataFormat
, long *len
) 
  46     OSStatus err 
= noErr 
; 
  51     switch (dataFormat
.GetType()) 
  54         dataFormat 
= wxDF_TEXT
; 
  59     case wxDF_UNICODETEXT
: 
  66             wxLogError(_("Unsupported clipboard format.")); 
  74     err 
= GetCurrentScrap( &scrapRef 
); 
  75     if ( err 
!= noTypeErr 
&& err 
!= memFullErr 
) 
  77         ScrapFlavorFlags    flavorFlags
; 
  79         if (( err 
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags 
)) == noErr
) 
  81             if (( err 
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount 
)) == noErr
) 
  83                 Size allocSize 
= byteCount 
; 
  84                 if ( dataFormat
.GetType() == wxDF_TEXT 
) 
  86                 else if ( dataFormat
.GetType() == wxDF_UNICODETEXT 
) 
  89                 data 
= new char[ allocSize 
] ; 
  91                 if (( err 
= GetScrapFlavorData( scrapRef
, dataFormat
.GetFormatId(), &byteCount 
, data 
)) == noErr 
) 
  94                     if ( dataFormat
.GetType() == wxDF_TEXT 
) 
  95                         ((char*)data
)[byteCount
] = 0 ; 
  96                     if ( dataFormat
.GetType() == wxDF_UNICODETEXT 
) 
  97                         ((wxChar
*)data
)[byteCount
/2] = 0 ; 
 101                     delete[] ((char *)data
) ; 
 110     Handle datahandle 
= NewHandle(0) ; 
 111     HLock( datahandle 
) ; 
 112     GetScrap( datahandle 
, dataFormat
.GetFormatId() , &offset 
) ; 
 113     HUnlock( datahandle 
) ; 
 114     if ( GetHandleSize( datahandle 
) > 0 ) 
 116         byteCount 
= GetHandleSize( datahandle 
) ; 
 117         Size allocSize 
= byteCount 
; 
 118         if ( dataFormat
.GetType() == wxDF_TEXT 
) 
 120         else if ( dataFormat
.GetType() == wxDF_UNICODETEXT 
) 
 123         data 
= new char[ allocSize 
] ; 
 125         memcpy( (char*) data 
, (char*) *datahandle 
, byteCount 
) ; 
 126         if ( dataFormat
.GetType() == wxDF_TEXT 
) 
 127             ((char*)data
)[byteCount
] = 0 ; 
 128         if ( dataFormat
.GetType() == wxDF_UNICODETEXT 
) 
 129             ((wxChar
*)data
)[byteCount
/2] = 0 ; 
 132     DisposeHandle( datahandle 
) ; 
 136         wxLogSysError(_("Failed to get clipboard data.")); 
 141     if ( dataFormat
.GetType() == wxDF_TEXT 
) 
 143         wxMacConvertNewlines10To13( (char*) data 
) ; 
 151  * Generalized clipboard implementation by Matthew Flatt 
 154 IMPLEMENT_DYNAMIC_CLASS(wxClipboard
, wxObject
) 
 156 wxClipboard::wxClipboard() 
 162 wxClipboard::~wxClipboard() 
 167         m_data 
= (wxDataObject
*) NULL
; 
 171 void wxClipboard::Clear() 
 176         m_data 
= (wxDataObject
*) NULL
; 
 180     err 
= ClearCurrentScrap( ); 
 187         wxLogSysError(_("Failed to empty the clipboard.")); 
 191 bool wxClipboard::Flush() 
 196 bool wxClipboard::Open() 
 198     wxCHECK_MSG( !m_open
, false, wxT("clipboard already open") ); 
 203 bool wxClipboard::IsOpened() const 
 208 bool wxClipboard::SetData( wxDataObject 
*data 
) 
 210     wxCHECK_MSG( m_open
, false, wxT("clipboard not open") ); 
 212     wxCHECK_MSG( data
, false, wxT("data is invalid") ); 
 215     // as we can only store one wxDataObject, this is the same in this 
 217     return AddData( data 
); 
 220 bool wxClipboard::AddData( wxDataObject 
*data 
) 
 222     wxCHECK_MSG( m_open
, false, wxT("clipboard not open") ); 
 224     wxCHECK_MSG( data
, false, wxT("data is invalid") ); 
 226     /* we can only store one wxDataObject */ 
 231     /* get formats from wxDataObjects */ 
 232     wxDataFormat 
*array 
= new wxDataFormat
[ m_data
->GetFormatCount() ]; 
 233     m_data
->GetAllFormats( array 
); 
 235     for (size_t i 
= 0; i 
< m_data
->GetFormatCount(); i
++) 
 237         wxLogTrace( TRACE_CLIPBOARD
, 
 238                     wxT("wxClipboard now supports atom %s"), 
 239                     array
[i
].GetId().c_str() ); 
 244         OSStatus err 
= noErr 
; 
 246         size_t sz 
= data
->GetDataSize( array
[i
] ) ; 
 247         void* buf 
= malloc( sz 
+ 1 ) ; 
 250             data
->GetDataHere( array
[i
] , buf 
) ; 
 252             switch ( array
[i
].GetType() ) 
 256                     mactype 
= kScrapFlavorTypeText 
; 
 259                case wxDF_UNICODETEXT 
: 
 260                     mactype 
= kScrapFlavorTypeUnicode 
; 
 263     #if wxUSE_DRAG_AND_DROP 
 265                     mactype 
= kScrapFlavorTypePicture 
; 
 270                     mactype 
= kScrapFlavorTypePicture 
; 
 275             UMAPutScrap( sz 
, mactype 
, buf 
) ; 
 285 void wxClipboard::Close() 
 287     wxCHECK_RET( m_open
, wxT("clipboard not open") ); 
 291     // Get rid of cached object.  If this is not done copying from another application will 
 296         m_data 
= (wxDataObject
*) NULL
; 
 301 bool wxClipboard::IsSupported( const wxDataFormat 
&dataFormat 
) 
 305     return m_data
->IsSupported( dataFormat 
) ; 
 308     OSStatus err 
= noErr
; 
 311     err 
= GetCurrentScrap( &scrapRef 
); 
 312     if ( err 
!= noTypeErr 
&& err 
!= memFullErr 
) 
 314         ScrapFlavorFlags    flavorFlags
; 
 317         if (( err 
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags 
)) == noErr
) 
 319             if (( err 
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount 
)) == noErr
) 
 329     Handle datahandle 
= NewHandle(0) ; 
 330     HLock( datahandle 
) ; 
 331     GetScrap( datahandle 
, dataFormat
.GetFormatId() , &offset 
) ; 
 332     HUnlock( datahandle 
) ; 
 333     bool hasData 
= GetHandleSize( datahandle 
) > 0 ; 
 334     DisposeHandle( datahandle 
) ; 
 339 bool wxClipboard::GetData( wxDataObject
& data 
) 
 341     wxCHECK_MSG( m_open
, false, wxT("clipboard not open") ); 
 343     size_t formatcount 
= data
.GetFormatCount() + 1 ; 
 344     wxDataFormat 
*array 
= new wxDataFormat
[ formatcount  
]; 
 345     array
[0] = data
.GetPreferredFormat(); 
 346     data
.GetAllFormats( &array
[1] ); 
 348     bool transferred 
= false ; 
 352       for (size_t i 
= 0; !transferred 
&& i 
< formatcount 
; i
++) 
 354           wxDataFormat format 
= array
[i
] ; 
 355           if ( m_data
->IsSupported( format 
) ) 
 357             int size 
= m_data
->GetDataSize( format 
); 
 362               data
.SetData(format 
, 0 , 0 ) ; 
 366               char *d 
= new char[size
]; 
 367               m_data
->GetDataHere( format 
, (void*) d 
); 
 368               data
.SetData( format 
, size 
, d 
) ; 
 374     /* get formats from wxDataObjects */ 
 377       for (size_t i 
= 0; !transferred 
&& i 
< formatcount 
; i
++) 
 379           wxDataFormat format 
= array
[i
] ; 
 381           switch ( format
.GetType() ) 
 389                   char* s 
= (char*)wxGetClipboardData(format
, &len 
); 
 392                     data
.SetData( format 
, len 
, s 
) ;