1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Clipboard functionality
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
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"
29 #include "wx/mac/uma.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
;
50 switch (dataFormat
.GetType())
53 dataFormat
= wxDF_TEXT
;
58 case wxDF_UNICODETEXT
:
65 wxLogError(_("Unsupported clipboard format."));
73 err
= GetCurrentScrap( &scrapRef
);
74 if ( err
!= noTypeErr
&& err
!= memFullErr
)
76 ScrapFlavorFlags flavorFlags
;
78 if (( err
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags
)) == noErr
)
80 if (( err
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount
)) == noErr
)
82 Size allocSize
= byteCount
;
83 if ( dataFormat
.GetType() == wxDF_TEXT
)
85 else if ( dataFormat
.GetType() == wxDF_UNICODETEXT
)
88 data
= new char[ allocSize
] ;
90 if (( err
= GetScrapFlavorData( scrapRef
, dataFormat
.GetFormatId(), &byteCount
, data
)) == noErr
)
93 if ( dataFormat
.GetType() == wxDF_TEXT
)
94 ((char*)data
)[byteCount
] = 0 ;
95 if ( dataFormat
.GetType() == wxDF_UNICODETEXT
)
96 ((wxChar
*)data
)[byteCount
/2] = 0 ;
100 delete[] ((char *)data
) ;
109 Handle datahandle
= NewHandle(0) ;
110 HLock( datahandle
) ;
111 GetScrap( datahandle
, dataFormat
.GetFormatId() , &offset
) ;
112 HUnlock( datahandle
) ;
113 if ( GetHandleSize( datahandle
) > 0 )
115 byteCount
= GetHandleSize( datahandle
) ;
116 Size allocSize
= byteCount
;
117 if ( dataFormat
.GetType() == wxDF_TEXT
)
119 else if ( dataFormat
.GetType() == wxDF_UNICODETEXT
)
122 data
= new char[ allocSize
] ;
124 memcpy( (char*) data
, (char*) *datahandle
, byteCount
) ;
125 if ( dataFormat
.GetType() == wxDF_TEXT
)
126 ((char*)data
)[byteCount
] = 0 ;
127 if ( dataFormat
.GetType() == wxDF_UNICODETEXT
)
128 ((wxChar
*)data
)[byteCount
/2] = 0 ;
131 DisposeHandle( datahandle
) ;
135 wxLogSysError(_("Failed to get clipboard data."));
140 if ( dataFormat
.GetType() == wxDF_TEXT
&& wxApp::s_macDefaultEncodingIsPC
)
142 wxString st
= wxMacMakeStringFromCString( (char*) data
) ;
144 wxCharBuffer buf
= st
.ToAscii() ;
148 char* newdata
= new char[strlen(buf
)+1] ;
149 memcpy( newdata
, buf
, strlen(buf
)+1 ) ;
150 delete[] ((char*) data
) ;
159 * Generalized clipboard implementation by Matthew Flatt
162 IMPLEMENT_DYNAMIC_CLASS(wxClipboard
, wxObject
)
164 wxClipboard::wxClipboard()
170 wxClipboard::~wxClipboard()
175 m_data
= (wxDataObject
*) NULL
;
179 void wxClipboard::Clear()
184 m_data
= (wxDataObject
*) NULL
;
188 err
= ClearCurrentScrap( );
195 wxLogSysError(_("Failed to empty the clipboard."));
199 bool wxClipboard::Flush()
204 bool wxClipboard::Open()
206 wxCHECK_MSG( !m_open
, FALSE
, wxT("clipboard already open") );
211 bool wxClipboard::IsOpened() const
216 bool wxClipboard::SetData( wxDataObject
*data
)
218 wxCHECK_MSG( m_open
, FALSE
, wxT("clipboard not open") );
220 wxCHECK_MSG( data
, FALSE
, wxT("data is invalid") );
224 return AddData( data
);
227 bool wxClipboard::AddData( wxDataObject
*data
)
229 wxCHECK_MSG( m_open
, FALSE
, wxT("clipboard not open") );
231 wxCHECK_MSG( data
, FALSE
, wxT("data is invalid") );
233 /* we can only store one wxDataObject */
238 /* get formats from wxDataObjects */
239 wxDataFormat
*array
= new wxDataFormat
[ m_data
->GetFormatCount() ];
240 m_data
->GetAllFormats( array
);
242 for (size_t i
= 0; i
< m_data
->GetFormatCount(); i
++)
244 wxLogTrace( TRACE_CLIPBOARD
,
245 wxT("wxClipboard now supports atom %s"),
246 array
[i
].GetId().c_str() );
251 OSStatus err
= noErr
;
254 switch ( array
[i
].GetType() )
259 wxTextDataObject
* textDataObject
= (wxTextDataObject
*) data
;
260 wxString
str(textDataObject
->GetText());
261 wxCharBuffer buf
= wxMacStringToCString( str
) ;
262 err
= UMAPutScrap( strlen(buf
) , kScrapFlavorTypeText
, (void*) buf
.data() ) ;
266 case wxDF_UNICODETEXT
:
268 wxTextDataObject
* textDataObject
= (wxTextDataObject
*) data
;
269 wxString
str(textDataObject
->GetText());
270 err
= UMAPutScrap( str
.Length() * sizeof(wxChar
) , kScrapFlavorTypeUnicode
, (void*) str
.wc_str() ) ;
274 #if wxUSE_DRAG_AND_DROP
277 wxMetafileDataObject
* metaFileDataObject
=
278 (wxMetafileDataObject
*) data
;
279 wxMetafile metaFile
= metaFileDataObject
->GetMetafile();
280 PicHandle pict
= (PicHandle
) metaFile
.GetHMETAFILE() ;
281 HLock( (Handle
) pict
) ;
282 err
= UMAPutScrap( GetHandleSize( (Handle
) pict
) , kScrapFlavorTypePicture
, *pict
) ;
283 HUnlock( (Handle
) pict
) ;
290 bool created
= false ;
291 PicHandle pict
= NULL
;
293 wxBitmapDataObject
* bitmapDataObject
= (wxBitmapDataObject
*) data
;
294 pict
= (PicHandle
) bitmapDataObject
->GetBitmap().GetPict( &created
) ;
296 HLock( (Handle
) pict
) ;
297 err
= UMAPutScrap( GetHandleSize( (Handle
) pict
) , kScrapFlavorTypePicture
, *pict
) ;
298 HUnlock( (Handle
) pict
) ;
300 KillPicture( pict
) ;
313 void wxClipboard::Close()
318 bool wxClipboard::IsSupported( const wxDataFormat
&dataFormat
)
322 return m_data
->IsSupported( dataFormat
) ;
325 OSStatus err
= noErr
;
328 err
= GetCurrentScrap( &scrapRef
);
329 if ( err
!= noTypeErr
&& err
!= memFullErr
)
331 ScrapFlavorFlags flavorFlags
;
334 if (( err
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags
)) == noErr
)
336 if (( err
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount
)) == noErr
)
346 Handle datahandle
= NewHandle(0) ;
347 HLock( datahandle
) ;
348 GetScrap( datahandle
, dataFormat
.GetFormatId() , &offset
) ;
349 HUnlock( datahandle
) ;
350 bool hasData
= GetHandleSize( datahandle
) > 0 ;
351 DisposeHandle( datahandle
) ;
356 bool wxClipboard::GetData( wxDataObject
& data
)
358 wxCHECK_MSG( m_open
, FALSE
, wxT("clipboard not open") );
360 size_t formatcount
= data
.GetFormatCount() + 1 ;
361 wxDataFormat
*array
= new wxDataFormat
[ formatcount
];
362 array
[0] = data
.GetPreferredFormat();
363 data
.GetAllFormats( &array
[1] );
365 bool transferred
= false ;
369 for (size_t i
= 0; !transferred
&& i
< formatcount
; i
++)
371 wxDataFormat format
= array
[i
] ;
372 if ( m_data
->IsSupported( format
) )
374 int size
= m_data
->GetDataSize( format
);
379 data
.SetData(format
, 0 , 0 ) ;
383 char *d
= new char[size
];
384 m_data
->GetDataHere( format
, (void*) d
);
385 data
.SetData( format
, size
, d
) ;
391 /* get formats from wxDataObjects */
394 for (size_t i
= 0; !transferred
&& i
< formatcount
; i
++)
396 wxDataFormat format
= array
[i
] ;
398 switch ( format
.GetType() )
406 char* s
= (char*)wxGetClipboardData(format
, &len
);
409 data
.SetData( format
, len
, s
) ;