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
)
141 wxMacConvertNewlines10To13( (char*) data
) ;
149 * Generalized clipboard implementation by Matthew Flatt
152 IMPLEMENT_DYNAMIC_CLASS(wxClipboard
, wxObject
)
154 wxClipboard::wxClipboard()
160 wxClipboard::~wxClipboard()
165 m_data
= (wxDataObject
*) NULL
;
169 void wxClipboard::Clear()
174 m_data
= (wxDataObject
*) NULL
;
178 err
= ClearCurrentScrap( );
185 wxLogSysError(_("Failed to empty the clipboard."));
189 bool wxClipboard::Flush()
194 bool wxClipboard::Open()
196 wxCHECK_MSG( !m_open
, FALSE
, wxT("clipboard already open") );
201 bool wxClipboard::IsOpened() const
206 bool wxClipboard::SetData( wxDataObject
*data
)
208 // as we can only store one wxDataObject, this is the same in this
210 return AddData( data
);
213 bool wxClipboard::AddData( wxDataObject
*data
)
215 wxCHECK_MSG( m_open
, FALSE
, wxT("clipboard not open") );
217 wxCHECK_MSG( data
, FALSE
, wxT("data is invalid") );
219 /* we can only store one wxDataObject */
224 /* get formats from wxDataObjects */
225 wxDataFormat
*array
= new wxDataFormat
[ m_data
->GetFormatCount() ];
226 m_data
->GetAllFormats( array
);
228 for (size_t i
= 0; i
< m_data
->GetFormatCount(); i
++)
230 wxLogTrace( TRACE_CLIPBOARD
,
231 wxT("wxClipboard now supports atom %s"),
232 array
[i
].GetId().c_str() );
237 OSStatus err
= noErr
;
240 switch ( array
[i
].GetType() )
245 wxTextDataObject
* textDataObject
= (wxTextDataObject
*) data
;
246 wxCharBuffer buf
= textDataObject
->GetText().mb_str() ;
247 err
= UMAPutScrap( strlen(buf
) , kScrapFlavorTypeText
, (void*) buf
.data() ) ;
251 case wxDF_UNICODETEXT
:
253 wxTextDataObject
* textDataObject
= (wxTextDataObject
*) data
;
254 wxString
str(textDataObject
->GetText());
255 err
= UMAPutScrap( str
.Length() * sizeof(wxChar
) , kScrapFlavorTypeUnicode
, (void*) str
.wc_str() ) ;
259 #if wxUSE_DRAG_AND_DROP
262 wxMetafileDataObject
* metaFileDataObject
=
263 (wxMetafileDataObject
*) data
;
264 wxMetafile metaFile
= metaFileDataObject
->GetMetafile();
265 PicHandle pict
= (PicHandle
) metaFile
.GetHMETAFILE() ;
266 HLock( (Handle
) pict
) ;
267 err
= UMAPutScrap( GetHandleSize( (Handle
) pict
) , kScrapFlavorTypePicture
, *pict
) ;
268 HUnlock( (Handle
) pict
) ;
275 bool created
= false ;
276 PicHandle pict
= NULL
;
278 wxBitmapDataObject
* bitmapDataObject
= (wxBitmapDataObject
*) data
;
279 pict
= (PicHandle
) bitmapDataObject
->GetBitmap().GetPict( &created
) ;
281 HLock( (Handle
) pict
) ;
282 err
= UMAPutScrap( GetHandleSize( (Handle
) pict
) , kScrapFlavorTypePicture
, *pict
) ;
283 HUnlock( (Handle
) pict
) ;
285 KillPicture( pict
) ;
298 void wxClipboard::Close()
302 // Get rid of cached object. If this is not done copying from another application will
307 m_data
= (wxDataObject
*) NULL
;
312 bool wxClipboard::IsSupported( const wxDataFormat
&dataFormat
)
316 return m_data
->IsSupported( dataFormat
) ;
319 OSStatus err
= noErr
;
322 err
= GetCurrentScrap( &scrapRef
);
323 if ( err
!= noTypeErr
&& err
!= memFullErr
)
325 ScrapFlavorFlags flavorFlags
;
328 if (( err
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags
)) == noErr
)
330 if (( err
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount
)) == noErr
)
340 Handle datahandle
= NewHandle(0) ;
341 HLock( datahandle
) ;
342 GetScrap( datahandle
, dataFormat
.GetFormatId() , &offset
) ;
343 HUnlock( datahandle
) ;
344 bool hasData
= GetHandleSize( datahandle
) > 0 ;
345 DisposeHandle( datahandle
) ;
350 bool wxClipboard::GetData( wxDataObject
& data
)
352 wxCHECK_MSG( m_open
, FALSE
, wxT("clipboard not open") );
354 size_t formatcount
= data
.GetFormatCount() + 1 ;
355 wxDataFormat
*array
= new wxDataFormat
[ formatcount
];
356 array
[0] = data
.GetPreferredFormat();
357 data
.GetAllFormats( &array
[1] );
359 bool transferred
= false ;
363 for (size_t i
= 0; !transferred
&& i
< formatcount
; i
++)
365 wxDataFormat format
= array
[i
] ;
366 if ( m_data
->IsSupported( format
) )
368 int size
= m_data
->GetDataSize( format
);
373 data
.SetData(format
, 0 , 0 ) ;
377 char *d
= new char[size
];
378 m_data
->GetDataHere( format
, (void*) d
);
379 data
.SetData( format
, size
, d
) ;
385 /* get formats from wxDataObjects */
388 for (size_t i
= 0; !transferred
&& i
< formatcount
; i
++)
390 wxDataFormat format
= array
[i
] ;
392 switch ( format
.GetType() )
400 char* s
= (char*)wxGetClipboardData(format
, &len
);
403 data
.SetData( format
, len
, s
) ;