1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Clipboard functionality
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
14 #include "wx/bitmap.h"
16 #include "wx/metafile.h"
17 #include "wx/clipbrd.h"
24 #include "wx/mac/uma.h"
26 #define wxUSE_DATAOBJ 1
30 // the trace mask we use with wxLogTrace() - call
31 // wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here
32 // (there will be a *lot* of them!)
33 static const wxChar
*TRACE_CLIPBOARD
= _T("clipboard");
35 void *wxGetClipboardData(wxDataFormat dataFormat
, long *len
)
40 OSStatus err
= noErr
;
45 switch (dataFormat
.GetType())
48 dataFormat
= wxDF_TEXT
;
53 case wxDF_UNICODETEXT
:
60 wxLogError(_("Unsupported clipboard format."));
68 err
= GetCurrentScrap( &scrapRef
);
69 if ( err
!= noTypeErr
&& err
!= memFullErr
)
71 ScrapFlavorFlags flavorFlags
;
73 if (( err
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags
)) == noErr
)
75 if (( err
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount
)) == noErr
)
77 Size allocSize
= byteCount
;
78 if ( dataFormat
.GetType() == wxDF_TEXT
)
80 else if ( dataFormat
.GetType() == wxDF_UNICODETEXT
)
83 data
= new char[ allocSize
] ;
85 if (( err
= GetScrapFlavorData( scrapRef
, dataFormat
.GetFormatId(), &byteCount
, data
)) == noErr
)
88 if ( dataFormat
.GetType() == wxDF_TEXT
)
89 ((char*)data
)[byteCount
] = 0 ;
90 if ( dataFormat
.GetType() == wxDF_UNICODETEXT
)
91 ((wxChar
*)data
)[byteCount
/2] = 0 ;
95 delete[] ((char *)data
) ;
104 Handle datahandle
= NewHandle(0) ;
105 HLock( datahandle
) ;
106 GetScrap( datahandle
, dataFormat
.GetFormatId() , &offset
) ;
107 HUnlock( datahandle
) ;
108 if ( GetHandleSize( datahandle
) > 0 )
110 byteCount
= GetHandleSize( datahandle
) ;
111 Size allocSize
= byteCount
;
112 if ( dataFormat
.GetType() == wxDF_TEXT
)
114 else if ( dataFormat
.GetType() == wxDF_UNICODETEXT
)
117 data
= new char[ allocSize
] ;
119 memcpy( (char*) data
, (char*) *datahandle
, byteCount
) ;
120 if ( dataFormat
.GetType() == wxDF_TEXT
)
121 ((char*)data
)[byteCount
] = 0 ;
122 if ( dataFormat
.GetType() == wxDF_UNICODETEXT
)
123 ((wxChar
*)data
)[byteCount
/2] = 0 ;
126 DisposeHandle( datahandle
) ;
130 wxLogSysError(_("Failed to get clipboard data."));
135 if ( dataFormat
.GetType() == wxDF_TEXT
)
137 wxMacConvertNewlines10To13( (char*) data
) ;
145 * Generalized clipboard implementation by Matthew Flatt
148 IMPLEMENT_DYNAMIC_CLASS(wxClipboard
, wxObject
)
150 wxClipboard::wxClipboard()
156 wxClipboard::~wxClipboard()
161 m_data
= (wxDataObject
*) NULL
;
165 void wxClipboard::Clear()
170 m_data
= (wxDataObject
*) NULL
;
174 err
= ClearCurrentScrap( );
181 wxLogSysError(_("Failed to empty the clipboard."));
185 bool wxClipboard::Flush()
190 bool wxClipboard::Open()
192 wxCHECK_MSG( !m_open
, FALSE
, wxT("clipboard already open") );
197 bool wxClipboard::IsOpened() const
202 bool wxClipboard::SetData( wxDataObject
*data
)
204 wxCHECK_MSG( m_open
, FALSE
, wxT("clipboard not open") );
206 wxCHECK_MSG( data
, FALSE
, wxT("data is invalid") );
209 // as we can only store one wxDataObject, this is the same in this
211 return AddData( data
);
214 bool wxClipboard::AddData( wxDataObject
*data
)
216 wxCHECK_MSG( m_open
, FALSE
, wxT("clipboard not open") );
218 wxCHECK_MSG( data
, FALSE
, wxT("data is invalid") );
220 /* we can only store one wxDataObject */
225 /* get formats from wxDataObjects */
226 wxDataFormat
*array
= new wxDataFormat
[ m_data
->GetFormatCount() ];
227 m_data
->GetAllFormats( array
);
229 for (size_t i
= 0; i
< m_data
->GetFormatCount(); i
++)
231 wxLogTrace( TRACE_CLIPBOARD
,
232 wxT("wxClipboard now supports atom %s"),
233 array
[i
].GetId().c_str() );
238 OSStatus err
= noErr
;
240 size_t sz
= data
->GetDataSize( array
[i
] ) ;
241 void* buf
= malloc( sz
+ 1 ) ;
244 data
->GetDataHere( array
[i
] , buf
) ;
246 switch ( array
[i
].GetType() )
250 mactype
= kScrapFlavorTypeText
;
253 case wxDF_UNICODETEXT
:
254 mactype
= kScrapFlavorTypeUnicode
;
257 #if wxUSE_DRAG_AND_DROP
259 mactype
= kScrapFlavorTypePicture
;
264 mactype
= kScrapFlavorTypePicture
;
269 UMAPutScrap( sz
, mactype
, buf
) ;
279 void wxClipboard::Close()
281 wxCHECK_RET( m_open
, wxT("clipboard not open") );
285 // Get rid of cached object. If this is not done copying from another application will
290 m_data
= (wxDataObject
*) NULL
;
295 bool wxClipboard::IsSupported( const wxDataFormat
&dataFormat
)
299 return m_data
->IsSupported( dataFormat
) ;
302 OSStatus err
= noErr
;
305 err
= GetCurrentScrap( &scrapRef
);
306 if ( err
!= noTypeErr
&& err
!= memFullErr
)
308 ScrapFlavorFlags flavorFlags
;
311 if (( err
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags
)) == noErr
)
313 if (( err
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount
)) == noErr
)
323 Handle datahandle
= NewHandle(0) ;
324 HLock( datahandle
) ;
325 GetScrap( datahandle
, dataFormat
.GetFormatId() , &offset
) ;
326 HUnlock( datahandle
) ;
327 bool hasData
= GetHandleSize( datahandle
) > 0 ;
328 DisposeHandle( datahandle
) ;
333 bool wxClipboard::GetData( wxDataObject
& data
)
335 wxCHECK_MSG( m_open
, FALSE
, wxT("clipboard not open") );
337 size_t formatcount
= data
.GetFormatCount() + 1 ;
338 wxDataFormat
*array
= new wxDataFormat
[ formatcount
];
339 array
[0] = data
.GetPreferredFormat();
340 data
.GetAllFormats( &array
[1] );
342 bool transferred
= false ;
346 for (size_t i
= 0; !transferred
&& i
< formatcount
; i
++)
348 wxDataFormat format
= array
[i
] ;
349 if ( m_data
->IsSupported( format
) )
351 int size
= m_data
->GetDataSize( format
);
356 data
.SetData(format
, 0 , 0 ) ;
360 char *d
= new char[size
];
361 m_data
->GetDataHere( format
, (void*) d
);
362 data
.SetData( format
, size
, d
) ;
368 /* get formats from wxDataObjects */
371 for (size_t i
= 0; !transferred
&& i
< formatcount
; i
++)
373 wxDataFormat format
= array
[i
] ;
375 switch ( format
.GetType() )
383 char* s
= (char*)wxGetClipboardData(format
, &len
);
386 data
.SetData( format
, len
, s
) ;