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 
&& wxApp::s_macDefaultEncodingIsPC 
) 
 141         wxString st 
= wxMacMakeStringFromCString( (char*) data 
) ; 
 143         wxCharBuffer buf 
= st
.ToAscii() ; 
 145         const char* buf 
= st 
; 
 147         char* newdata 
= new char[strlen(buf
)+1] ; 
 148         memcpy( newdata 
, buf 
, strlen(buf
)+1 ) ; 
 149         delete[] ((char*) data 
) ; 
 158  * Generalized clipboard implementation by Matthew Flatt 
 161 IMPLEMENT_DYNAMIC_CLASS(wxClipboard
, wxObject
) 
 163 wxClipboard::wxClipboard() 
 169 wxClipboard::~wxClipboard() 
 174         m_data 
= (wxDataObject
*) NULL
; 
 178 void wxClipboard::Clear() 
 183         m_data 
= (wxDataObject
*) NULL
; 
 187     err 
= ClearCurrentScrap( ); 
 194         wxLogSysError(_("Failed to empty the clipboard.")); 
 198 bool wxClipboard::Flush() 
 203 bool wxClipboard::Open() 
 205     wxCHECK_MSG( !m_open
, FALSE
, wxT("clipboard already open") ); 
 210 bool wxClipboard::IsOpened() const 
 215 bool wxClipboard::SetData( wxDataObject 
*data 
) 
 217     // as we can only store one wxDataObject, this is the same in this 
 219     return AddData( data 
); 
 222 bool wxClipboard::AddData( wxDataObject 
*data 
) 
 224     wxCHECK_MSG( m_open
, FALSE
, wxT("clipboard not open") ); 
 226     wxCHECK_MSG( data
, FALSE
, wxT("data is invalid") ); 
 228     /* we can only store one wxDataObject */ 
 233     /* get formats from wxDataObjects */ 
 234     wxDataFormat 
*array 
= new wxDataFormat
[ m_data
->GetFormatCount() ]; 
 235     m_data
->GetAllFormats( array 
); 
 237     for (size_t i 
= 0; i 
< m_data
->GetFormatCount(); i
++) 
 239         wxLogTrace( TRACE_CLIPBOARD
, 
 240                     wxT("wxClipboard now supports atom %s"), 
 241                     array
[i
].GetId().c_str() ); 
 246         OSStatus err 
= noErr 
; 
 249        switch ( array
[i
].GetType() ) 
 254                wxTextDataObject
* textDataObject 
= (wxTextDataObject
*) data
; 
 255                wxString 
str(textDataObject
->GetText()); 
 256                wxCharBuffer buf 
= wxMacStringToCString( str 
) ; 
 257                err 
= UMAPutScrap( strlen(buf
) , kScrapFlavorTypeText 
, (void*) buf
.data()  ) ; 
 261            case wxDF_UNICODETEXT 
: 
 263                wxTextDataObject
* textDataObject 
= (wxTextDataObject
*) data
; 
 264                wxString 
str(textDataObject
->GetText()); 
 265                err 
= UMAPutScrap( str
.Length() * sizeof(wxChar
) , kScrapFlavorTypeUnicode 
, (void*) str
.wc_str()  ) ; 
 269 #if wxUSE_DRAG_AND_DROP 
 272                 wxMetafileDataObject
* metaFileDataObject 
= 
 273                 (wxMetafileDataObject
*) data
; 
 274                   wxMetafile metaFile 
= metaFileDataObject
->GetMetafile(); 
 275                 PicHandle pict 
= (PicHandle
) metaFile
.GetHMETAFILE() ; 
 276                   HLock( (Handle
) pict 
) ; 
 277                   err 
= UMAPutScrap( GetHandleSize(  (Handle
) pict 
) , kScrapFlavorTypePicture 
, *pict 
) ; 
 278                   HUnlock(  (Handle
) pict 
) ; 
 285                    bool created 
= false ; 
 286                    PicHandle pict 
= NULL 
; 
 288                    wxBitmapDataObject
* bitmapDataObject 
= (wxBitmapDataObject
*) data 
; 
 289                    pict 
= (PicHandle
) bitmapDataObject
->GetBitmap().GetPict( &created 
) ; 
 291                   HLock( (Handle
) pict 
) ; 
 292                   err 
= UMAPutScrap( GetHandleSize(  (Handle
) pict 
) , kScrapFlavorTypePicture 
, *pict 
) ; 
 293                   HUnlock(  (Handle
) pict 
) ; 
 295                       KillPicture( pict 
) ; 
 308 void wxClipboard::Close() 
 313 bool wxClipboard::IsSupported( const wxDataFormat 
&dataFormat 
) 
 317     return m_data
->IsSupported( dataFormat 
) ; 
 320     OSStatus err 
= noErr
; 
 323     err 
= GetCurrentScrap( &scrapRef 
); 
 324     if ( err 
!= noTypeErr 
&& err 
!= memFullErr 
) 
 326         ScrapFlavorFlags    flavorFlags
; 
 329         if (( err 
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags 
)) == noErr
) 
 331             if (( err 
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount 
)) == noErr
) 
 341     Handle datahandle 
= NewHandle(0) ; 
 342     HLock( datahandle 
) ; 
 343     GetScrap( datahandle 
, dataFormat
.GetFormatId() , &offset 
) ; 
 344     HUnlock( datahandle 
) ; 
 345     bool hasData 
= GetHandleSize( datahandle 
) > 0 ; 
 346     DisposeHandle( datahandle 
) ; 
 351 bool wxClipboard::GetData( wxDataObject
& data 
) 
 353     wxCHECK_MSG( m_open
, FALSE
, wxT("clipboard not open") ); 
 355     size_t formatcount 
= data
.GetFormatCount() + 1 ; 
 356     wxDataFormat 
*array 
= new wxDataFormat
[ formatcount  
]; 
 357     array
[0] = data
.GetPreferredFormat(); 
 358     data
.GetAllFormats( &array
[1] ); 
 360     bool transferred 
= false ; 
 364       for (size_t i 
= 0; !transferred 
&& i 
< formatcount 
; i
++) 
 366           wxDataFormat format 
= array
[i
] ; 
 367           if ( m_data
->IsSupported( format 
) ) 
 369             int size 
= m_data
->GetDataSize( format 
); 
 374               data
.SetData(format 
, 0 , 0 ) ; 
 378               char *d 
= new char[size
]; 
 379               m_data
->GetDataHere( format 
, (void*) d 
); 
 380               data
.SetData( format 
, size 
, d 
) ; 
 386     /* get formats from wxDataObjects */ 
 389       for (size_t i 
= 0; !transferred 
&& i 
< formatcount 
; i
++) 
 391           wxDataFormat format 
= array
[i
] ; 
 393           switch ( format
.GetType() ) 
 401                   char* s 
= (char*)wxGetClipboardData(format
, &len 
); 
 404                     data
.SetData( format 
, len 
, s 
) ;