1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Clipboard functionality 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "clipbrd.h" 
  18 #include "wx/bitmap.h" 
  20 #include "wx/metafile.h" 
  21 #include "wx/clipbrd.h" 
  28 #include "wx/mac/uma.h" 
  30 #define wxUSE_DATAOBJ 1 
  34 // the trace mask we use with wxLogTrace() - call 
  35 // wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here 
  36 // (there will be a *lot* of them!) 
  37 static const wxChar 
*TRACE_CLIPBOARD 
= _T("clipboard"); 
  39 void *wxGetClipboardData(wxDataFormat dataFormat
, long *len
) 
  44     OSStatus err 
= noErr 
; 
  49     switch (dataFormat
.GetType()) 
  52         dataFormat 
= wxDF_TEXT
; 
  57     case wxDF_UNICODETEXT
: 
  64             wxLogError(_("Unsupported clipboard format.")); 
  72     err 
= GetCurrentScrap( &scrapRef 
); 
  73     if ( err 
!= noTypeErr 
&& err 
!= memFullErr 
) 
  75         ScrapFlavorFlags    flavorFlags
; 
  77         if (( err 
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags 
)) == noErr
) 
  79             if (( err 
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount 
)) == noErr
) 
  81                 Size allocSize 
= byteCount 
; 
  82                 if ( dataFormat
.GetType() == wxDF_TEXT 
) 
  84                 else if ( dataFormat
.GetType() == wxDF_UNICODETEXT 
) 
  87                 data 
= new char[ allocSize 
] ; 
  89                 if (( err 
= GetScrapFlavorData( scrapRef
, dataFormat
.GetFormatId(), &byteCount 
, data 
)) == noErr 
) 
  92                     if ( dataFormat
.GetType() == wxDF_TEXT 
) 
  93                         ((char*)data
)[byteCount
] = 0 ; 
  94                     if ( dataFormat
.GetType() == wxDF_UNICODETEXT 
) 
  95                         ((wxChar
*)data
)[byteCount
/2] = 0 ; 
  99                     delete[] ((char *)data
) ; 
 108     Handle datahandle 
= NewHandle(0) ; 
 109     HLock( datahandle 
) ; 
 110     GetScrap( datahandle 
, dataFormat
.GetFormatId() , &offset 
) ; 
 111     HUnlock( datahandle 
) ; 
 112     if ( GetHandleSize( datahandle 
) > 0 ) 
 114         byteCount 
= GetHandleSize( datahandle 
) ; 
 115         Size allocSize 
= byteCount 
; 
 116         if ( dataFormat
.GetType() == wxDF_TEXT 
) 
 118         else if ( dataFormat
.GetType() == wxDF_UNICODETEXT 
) 
 121         data 
= new char[ allocSize 
] ; 
 123         memcpy( (char*) data 
, (char*) *datahandle 
, byteCount 
) ; 
 124         if ( dataFormat
.GetType() == wxDF_TEXT 
) 
 125             ((char*)data
)[byteCount
] = 0 ; 
 126         if ( dataFormat
.GetType() == wxDF_UNICODETEXT 
) 
 127             ((wxChar
*)data
)[byteCount
/2] = 0 ; 
 130     DisposeHandle( datahandle 
) ; 
 134         wxLogSysError(_("Failed to get clipboard data.")); 
 139     if ( dataFormat
.GetType() == wxDF_TEXT 
) 
 141         wxMacConvertNewlines10To13( (char*) data 
) ; 
 149  * Generalized clipboard implementation by Matthew Flatt 
 152 IMPLEMENT_DYNAMIC_CLASS(wxClipboard
, wxObject
) 
 154 wxClipboard::wxClipboard() 
 160 wxClipboard::~wxClipboard() 
 165         m_data 
= (wxDataObject
*) NULL
; 
 169 void wxClipboard::Clear() 
 174         m_data 
= (wxDataObject
*) NULL
; 
 178     err 
= ClearCurrentScrap( ); 
 185         wxLogSysError(_("Failed to empty the clipboard.")); 
 189 bool wxClipboard::Flush() 
 194 bool wxClipboard::Open() 
 196     wxCHECK_MSG( !m_open
, FALSE
, wxT("clipboard already open") ); 
 201 bool wxClipboard::IsOpened() const 
 206 bool wxClipboard::SetData( wxDataObject 
*data 
) 
 208     wxCHECK_MSG( m_open
, FALSE
, wxT("clipboard not open") ); 
 210     wxCHECK_MSG( data
, FALSE
, wxT("data is invalid") ); 
 213     // as we can only store one wxDataObject, this is the same in this 
 215     return AddData( data 
); 
 218 bool wxClipboard::AddData( wxDataObject 
*data 
) 
 220     wxCHECK_MSG( m_open
, FALSE
, wxT("clipboard not open") ); 
 222     wxCHECK_MSG( data
, FALSE
, wxT("data is invalid") ); 
 224     /* we can only store one wxDataObject */ 
 229     /* get formats from wxDataObjects */ 
 230     wxDataFormat 
*array 
= new wxDataFormat
[ m_data
->GetFormatCount() ]; 
 231     m_data
->GetAllFormats( array 
); 
 233     for (size_t i 
= 0; i 
< m_data
->GetFormatCount(); i
++) 
 235         wxLogTrace( TRACE_CLIPBOARD
, 
 236                     wxT("wxClipboard now supports atom %s"), 
 237                     array
[i
].GetId().c_str() ); 
 242         OSStatus err 
= noErr 
; 
 244         size_t sz 
= data
->GetDataSize( array
[i
] ) ; 
 245         void* buf 
= malloc( sz 
+ 1 ) ; 
 248             data
->GetDataHere( array
[i
] , buf 
) ; 
 250             switch ( array
[i
].GetType() ) 
 254                     mactype 
= kScrapFlavorTypeText 
; 
 257                case wxDF_UNICODETEXT 
: 
 258                     mactype 
= kScrapFlavorTypeUnicode 
; 
 261     #if wxUSE_DRAG_AND_DROP 
 263                     mactype 
= kScrapFlavorTypePicture 
; 
 268                     mactype 
= kScrapFlavorTypePicture 
; 
 273             UMAPutScrap( sz 
, mactype 
, buf 
) ; 
 283 void wxClipboard::Close() 
 285     wxCHECK_RET( m_open
, wxT("clipboard not open") ); 
 289         // Get rid of cached object.  If this is not done copying from another application will 
 294         m_data 
= (wxDataObject
*) NULL
; 
 299 bool wxClipboard::IsSupported( const wxDataFormat 
&dataFormat 
) 
 303     return m_data
->IsSupported( dataFormat 
) ; 
 306     OSStatus err 
= noErr
; 
 309     err 
= GetCurrentScrap( &scrapRef 
); 
 310     if ( err 
!= noTypeErr 
&& err 
!= memFullErr 
) 
 312         ScrapFlavorFlags    flavorFlags
; 
 315         if (( err 
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags 
)) == noErr
) 
 317             if (( err 
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount 
)) == noErr
) 
 327     Handle datahandle 
= NewHandle(0) ; 
 328     HLock( datahandle 
) ; 
 329     GetScrap( datahandle 
, dataFormat
.GetFormatId() , &offset 
) ; 
 330     HUnlock( datahandle 
) ; 
 331     bool hasData 
= GetHandleSize( datahandle 
) > 0 ; 
 332     DisposeHandle( datahandle 
) ; 
 337 bool wxClipboard::GetData( wxDataObject
& data 
) 
 339     wxCHECK_MSG( m_open
, FALSE
, wxT("clipboard not open") ); 
 341     size_t formatcount 
= data
.GetFormatCount() + 1 ; 
 342     wxDataFormat 
*array 
= new wxDataFormat
[ formatcount  
]; 
 343     array
[0] = data
.GetPreferredFormat(); 
 344     data
.GetAllFormats( &array
[1] ); 
 346     bool transferred 
= false ; 
 350       for (size_t i 
= 0; !transferred 
&& i 
< formatcount 
; i
++) 
 352           wxDataFormat format 
= array
[i
] ; 
 353           if ( m_data
->IsSupported( format 
) ) 
 355             int size 
= m_data
->GetDataSize( format 
); 
 360               data
.SetData(format 
, 0 , 0 ) ; 
 364               char *d 
= new char[size
]; 
 365               m_data
->GetDataHere( format 
, (void*) d 
); 
 366               data
.SetData( format 
, size 
, d 
) ; 
 372     /* get formats from wxDataObjects */ 
 375       for (size_t i 
= 0; !transferred 
&& i 
< formatcount 
; i
++) 
 377           wxDataFormat format 
= array
[i
] ; 
 379           switch ( format
.GetType() ) 
 387                   char* s 
= (char*)wxGetClipboardData(format
, &len 
); 
 390                     data
.SetData( format 
, len 
, s 
) ;