1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Clipboard functionality 
   8 // Copyright:   (c) AUTHOR 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation 
  14 #pragma implementation "clipbrd.h" 
  19 #include "wx/bitmap.h" 
  21 #include "wx/metafile.h" 
  22 #include "wx/clipbrd.h" 
  26 #include "wx/mac/private.h" 
  31 #define wxUSE_DATAOBJ 1 
  35 // the trace mask we use with wxLogTrace() - call 
  36 // wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here 
  37 // (there will be a *lot* of them!) 
  38 static const wxChar 
*TRACE_CLIPBOARD 
= _T("clipboard"); 
  40 void *wxGetClipboardData(wxDataFormat dataFormat
, long *len
) 
  45     OSStatus err 
= noErr 
; 
  49     switch (dataFormat
.GetType()) 
  52             dataFormat 
= wxDF_TEXT
; 
  59                 wxLogError(_("Unsupported clipboard format.")); 
  67     err 
= GetCurrentScrap( &scrapRef 
); 
  68     if ( err 
!= noTypeErr 
&& err 
!= memFullErr 
)     
  70         ScrapFlavorFlags    flavorFlags
; 
  73         if (( err 
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags 
)) == noErr
) 
  75             if (( err 
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount 
)) == noErr
) 
  77               if ( dataFormat
.GetType() == wxDF_TEXT 
) 
  80           data 
= new char[ byteCount 
] ; 
  81           if (( err 
= GetScrapFlavorData( scrapRef
, dataFormat
.GetFormatId(), &byteCount 
, data 
)) == noErr 
) 
  84                 if ( dataFormat
.GetType() == wxDF_TEXT 
)   
  85                 ((char*)data
)[byteCount
] = 0 ; 
  89             delete[] ((char *)data
) ; 
  98     Handle datahandle 
= NewHandle(0) ; 
 100     GetScrap( datahandle 
, dataFormat
.GetFormatId() , &offset 
) ; 
 101     HUnlock( datahandle 
) ; 
 102     if ( GetHandleSize( datahandle 
) > 0 ) 
 104       long byteCount 
= GetHandleSize( datahandle 
) ; 
 105       if ( dataFormat
.GetType() == wxDF_TEXT 
)   
 106         data 
= new char[ byteCount 
+ 1] ; 
 108         data 
= new char[ byteCount 
] ; 
 110       memcpy( (char*) data 
, (char*) *datahandle 
, byteCount 
) ; 
 111       if ( dataFormat
.GetType() == wxDF_TEXT 
)   
 112           ((char*)data
)[byteCount
] = 0 ; 
 115     DisposeHandle( datahandle 
) ; 
 119         wxLogSysError(_("Failed to get clipboard data.")); 
 123     if ( dataFormat
.GetType() == wxDF_TEXT 
&& wxApp::s_macDefaultEncodingIsPC 
) 
 125       wxMacConvertToPC((char*)data
) ; 
 132  * Generalized clipboard implementation by Matthew Flatt 
 135 IMPLEMENT_DYNAMIC_CLASS(wxClipboard
, wxObject
) 
 137 wxClipboard::wxClipboard() 
 143 wxClipboard::~wxClipboard() 
 148         m_data 
= (wxDataObject
*) NULL
; 
 152 void wxClipboard::Clear() 
 157         m_data 
= (wxDataObject
*) NULL
; 
 161     err 
= ClearCurrentScrap( ); 
 168         wxLogSysError(_("Failed to empty the clipboard.")); 
 172 bool wxClipboard::Flush() 
 177 bool wxClipboard::Open() 
 179     wxCHECK_MSG( !m_open
, FALSE
, wxT("clipboard already open") ); 
 184 bool wxClipboard::IsOpened() const 
 189 bool wxClipboard::SetData( wxDataObject 
*data 
) 
 191     wxCHECK_MSG( m_open
, FALSE
, wxT("clipboard not open") ); 
 193     wxCHECK_MSG( data
, FALSE
, wxT("data is invalid") ); 
 197     return AddData( data 
); 
 200 bool wxClipboard::AddData( wxDataObject 
*data 
) 
 202     wxCHECK_MSG( m_open
, FALSE
, wxT("clipboard not open") ); 
 204     wxCHECK_MSG( data
, FALSE
, wxT("data is invalid") ); 
 206     /* we can only store one wxDataObject */ 
 211     /* get formats from wxDataObjects */ 
 212     wxDataFormat 
*array 
= new wxDataFormat
[ m_data
->GetFormatCount() ]; 
 213     m_data
->GetAllFormats( array 
); 
 215     for (size_t i 
= 0; i 
< m_data
->GetFormatCount(); i
++) 
 217         wxLogTrace( TRACE_CLIPBOARD
, 
 218                     wxT("wxClipboard now supports atom %s"), 
 219                     array
[i
].GetId().c_str() ); 
 224         OSStatus err 
= noErr 
; 
 227        switch ( array
[i
].GetType() ) 
 232                wxTextDataObject
* textDataObject 
= (wxTextDataObject
*) data
; 
 233                wxString 
str(textDataObject
->GetText()); 
 235                 if ( wxApp::s_macDefaultEncodingIsPC 
) 
 237                     mac 
= wxMacMakeMacStringFromPC(textDataObject
->GetText()) ; 
 241                     mac 
= textDataObject
->GetText() ; 
 244                         err 
= PutScrap( mac
.Length() , 'TEXT' , mac
.c_str() ) ; 
 247                         err 
= GetCurrentScrap (&scrap
);  
 250                             err 
= PutScrapFlavor (scrap
, 'TEXT', 0, mac
.Length(), mac
.c_str()); 
 256 #if wxUSE_DRAG_AND_DROP 
 259               wxMetafileDataObject
* metaFileDataObject 
= 
 260                 (wxMetafileDataObject
*) data
; 
 261               wxMetafile metaFile 
= metaFileDataObject
->GetMetafile(); 
 262                     PicHandle pict 
= (PicHandle
) metaFile
.GetHMETAFILE() ; 
 263                     HLock( (Handle
) pict 
) ; 
 265                     err 
= PutScrap( GetHandleSize(  (Handle
) pict 
) , 'PICT' , *pict 
) ; 
 268                     err 
= GetCurrentScrap (&scrap
);  
 271                         err 
= PutScrapFlavor (scrap
, 'PICT', 0, GetHandleSize((Handle
) pict
), *pict
); 
 274                     HUnlock(  (Handle
) pict 
) ; 
 291 void wxClipboard::Close() 
 296 bool wxClipboard::IsSupported( const wxDataFormat 
&dataFormat 
) 
 300     return m_data
->IsSupported( dataFormat 
) ; 
 303     OSStatus err 
= noErr
; 
 306     err 
= GetCurrentScrap( &scrapRef 
); 
 307     if ( err 
!= noTypeErr 
&& err 
!= memFullErr 
)     
 309         ScrapFlavorFlags    flavorFlags
; 
 312         if (( err 
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags 
)) == noErr
) 
 314             if (( err 
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount 
)) == noErr
) 
 324     Handle datahandle 
= NewHandle(0) ; 
 325     HLock( datahandle 
) ; 
 326     GetScrap( datahandle 
, dataFormat
.GetFormatId() , &offset 
) ; 
 327     HUnlock( datahandle 
) ; 
 328     bool hasData 
= GetHandleSize( datahandle 
) > 0 ; 
 329     DisposeHandle( datahandle 
) ; 
 334 bool wxClipboard::GetData( wxDataObject
& data 
) 
 336     wxCHECK_MSG( m_open
, FALSE
, wxT("clipboard not open") ); 
 338     size_t formatcount 
= data
.GetFormatCount() + 1 ; 
 339     wxDataFormat 
*array 
= new wxDataFormat
[ formatcount  
]; 
 340     array
[0] = data
.GetPreferredFormat(); 
 341     data
.GetAllFormats( &array
[1] ); 
 343     bool transferred 
= false ; 
 347       for (size_t i 
= 0; !transferred 
&& i 
< formatcount 
; i
++) 
 349           wxDataFormat format 
= array
[i
] ; 
 350           if ( m_data
->IsSupported( format 
) )  
 352             int size 
= m_data
->GetDataSize( format 
); 
 357               data
.SetData(format 
, 0 , 0 ) ; 
 361               char *d 
= new char[size
]; 
 362               m_data
->GetDataHere( format 
, (void*) d 
); 
 363               data
.SetData( format 
, size 
, d 
) ; 
 369     /* get formats from wxDataObjects */ 
 372       for (size_t i 
= 0; !transferred 
&& i 
< formatcount 
; i
++) 
 374           wxDataFormat format 
= array
[i
] ; 
 376           switch ( format
.GetType() ) 
 382                   char* s 
= (char*)wxGetClipboardData(format
, &len 
); 
 385                     data
.SetData( format 
, len 
, s 
) ;