1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Clipboard functionality
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.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
:
70 err
= GetCurrentScrap( &scrapRef
);
71 if ( err
!= noTypeErr
&& err
!= memFullErr
)
73 ScrapFlavorFlags flavorFlags
;
75 if (( err
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags
)) == noErr
)
77 if (( err
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount
)) == noErr
)
79 Size allocSize
= byteCount
;
80 if ( dataFormat
.GetType() == wxDF_TEXT
)
82 else if ( dataFormat
.GetType() == wxDF_UNICODETEXT
)
85 data
= new char[ allocSize
] ;
87 if (( err
= GetScrapFlavorData( scrapRef
, dataFormat
.GetFormatId(), &byteCount
, data
)) == noErr
)
90 if ( dataFormat
.GetType() == wxDF_TEXT
)
91 ((char*)data
)[byteCount
] = 0 ;
92 if ( dataFormat
.GetType() == wxDF_UNICODETEXT
)
94 // "data" format is UTF16, so 2 bytes = one character
95 // wxChar size depends on platform, so just clear last 2 bytes
96 ((char*)data
)[byteCount
] = 0;
97 ((char*)data
)[byteCount
+1] = 0;
102 delete[] ((char *)data
) ;
111 Handle datahandle
= NewHandle(0) ;
112 HLock( datahandle
) ;
113 GetScrap( datahandle
, dataFormat
.GetFormatId() , &offset
) ;
114 HUnlock( datahandle
) ;
115 if ( GetHandleSize( datahandle
) > 0 )
117 byteCount
= GetHandleSize( datahandle
) ;
118 Size allocSize
= byteCount
;
119 if ( dataFormat
.GetType() == wxDF_TEXT
)
121 else if ( dataFormat
.GetType() == wxDF_UNICODETEXT
)
124 data
= new char[ allocSize
] ;
126 memcpy( (char*) data
, (char*) *datahandle
, byteCount
) ;
127 if ( dataFormat
.GetType() == wxDF_TEXT
)
128 ((char*)data
)[byteCount
] = 0 ;
129 if ( dataFormat
.GetType() == wxDF_UNICODETEXT
)
130 ((wxChar
*)data
)[byteCount
/2] = 0 ;
133 DisposeHandle( datahandle
) ;
137 wxLogSysError(_("Failed to get clipboard data."));
142 if ( dataFormat
.GetType() == wxDF_TEXT
)
144 wxMacConvertNewlines10To13( (char*) data
) ;
152 * Generalized clipboard implementation by Matthew Flatt
155 IMPLEMENT_DYNAMIC_CLASS(wxClipboard
, wxObject
)
157 wxClipboard::wxClipboard()
163 wxClipboard::~wxClipboard()
168 m_data
= (wxDataObject
*) NULL
;
172 void wxClipboard::Clear()
177 m_data
= (wxDataObject
*) NULL
;
181 err
= ClearCurrentScrap( );
188 wxLogSysError(_("Failed to empty the clipboard."));
192 bool wxClipboard::Flush()
197 bool wxClipboard::Open()
199 wxCHECK_MSG( !m_open
, false, wxT("clipboard already open") );
204 bool wxClipboard::IsOpened() const
209 bool wxClipboard::SetData( wxDataObject
*data
)
211 wxCHECK_MSG( m_open
, false, wxT("clipboard not open") );
213 wxCHECK_MSG( data
, false, wxT("data is invalid") );
216 // as we can only store one wxDataObject, this is the same in this
218 return AddData( data
);
221 bool wxClipboard::AddData( wxDataObject
*data
)
223 wxCHECK_MSG( m_open
, false, wxT("clipboard not open") );
225 wxCHECK_MSG( data
, false, wxT("data is invalid") );
227 // we can only store one wxDataObject
232 // get formats from wxDataObjects
233 wxDataFormat
*array
= new wxDataFormat
[ m_data
->GetFormatCount() ];
234 m_data
->GetAllFormats( array
);
236 for (size_t i
= 0; i
< m_data
->GetFormatCount(); i
++)
238 wxLogTrace( TRACE_CLIPBOARD
,
239 wxT("wxClipboard now supports atom %s"),
240 array
[i
].GetId().c_str() );
242 size_t sz
= data
->GetDataSize( array
[i
] ) ;
243 void* buf
= malloc( sz
+ 1 ) ;
246 // empty the buffer because in some case GetDataHere does not fill buf
247 memset(buf
, 0, sz
+1);
248 data
->GetDataHere( array
[i
] , buf
) ;
250 switch ( array
[i
].GetType() )
254 mactype
= kScrapFlavorTypeText
;
258 case wxDF_UNICODETEXT
:
259 mactype
= kScrapFlavorTypeUnicode
;
263 #if wxUSE_DRAG_AND_DROP
265 mactype
= kScrapFlavorTypePicture
;
270 mactype
= kScrapFlavorTypePicture
;
273 mactype
= (OSType
)(array
[i
].GetFormatId());
276 UMAPutScrap( sz
, mactype
, buf
) ;
286 void wxClipboard::Close()
288 wxCHECK_RET( m_open
, wxT("clipboard not open") );
292 // Get rid of cached object. If this is not done copying from another application will
297 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
) ;
375 // get formats from wxDataObjects
378 for (size_t i
= 0; !transferred
&& i
< formatcount
; i
++)
380 wxDataFormat format
= array
[i
] ;
382 switch ( format
.GetType() )
384 // NOTE: this is usable for all data types
386 case wxDF_UNICODETEXT
:
393 char* s
= (char*)wxGetClipboardData(format
, &len
);
396 data
.SetData( format
, len
, s
) ;