1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Clipboard functionality
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "clipbrd.h"
16 #include "wx/wxprec.h"
22 #include "wx/bitmap.h"
24 #include "wx/metafile.h"
25 #include "wx/clipbrd.h"
32 #include "wx/mac/uma.h"
34 #define wxUSE_DATAOBJ 1
38 // the trace mask we use with wxLogTrace() - call
39 // wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here
40 // (there will be a *lot* of them!)
41 static const wxChar
*TRACE_CLIPBOARD
= _T("clipboard");
43 void *wxGetClipboardData(wxDataFormat dataFormat
, long *len
)
48 OSStatus err
= noErr
;
53 switch (dataFormat
.GetType())
56 dataFormat
= wxDF_TEXT
;
61 case wxDF_UNICODETEXT
:
68 wxLogError(_("Unsupported clipboard format."));
76 err
= GetCurrentScrap( &scrapRef
);
77 if ( err
!= noTypeErr
&& err
!= memFullErr
)
79 ScrapFlavorFlags flavorFlags
;
81 if (( err
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags
)) == noErr
)
83 if (( err
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount
)) == noErr
)
85 Size allocSize
= byteCount
;
86 if ( dataFormat
.GetType() == wxDF_TEXT
)
88 else if ( dataFormat
.GetType() == wxDF_UNICODETEXT
)
91 data
= new char[ allocSize
] ;
93 if (( err
= GetScrapFlavorData( scrapRef
, dataFormat
.GetFormatId(), &byteCount
, data
)) == noErr
)
96 if ( dataFormat
.GetType() == wxDF_TEXT
)
97 ((char*)data
)[byteCount
] = 0 ;
98 if ( dataFormat
.GetType() == wxDF_UNICODETEXT
)
100 // "data" format is UTF16, so 2 bytes = one character
101 // wxChar size depends on platform, so just clear last 2 bytes
102 ((char*)data
)[byteCount
] = 0;
103 ((char*)data
)[byteCount
+1] = 0;
108 delete[] ((char *)data
) ;
117 Handle datahandle
= NewHandle(0) ;
118 HLock( datahandle
) ;
119 GetScrap( datahandle
, dataFormat
.GetFormatId() , &offset
) ;
120 HUnlock( datahandle
) ;
121 if ( GetHandleSize( datahandle
) > 0 )
123 byteCount
= GetHandleSize( datahandle
) ;
124 Size allocSize
= byteCount
;
125 if ( dataFormat
.GetType() == wxDF_TEXT
)
127 else if ( dataFormat
.GetType() == wxDF_UNICODETEXT
)
130 data
= new char[ allocSize
] ;
132 memcpy( (char*) data
, (char*) *datahandle
, byteCount
) ;
133 if ( dataFormat
.GetType() == wxDF_TEXT
)
134 ((char*)data
)[byteCount
] = 0 ;
135 if ( dataFormat
.GetType() == wxDF_UNICODETEXT
)
136 ((wxChar
*)data
)[byteCount
/2] = 0 ;
139 DisposeHandle( datahandle
) ;
143 wxLogSysError(_("Failed to get clipboard data."));
148 if ( dataFormat
.GetType() == wxDF_TEXT
)
150 wxMacConvertNewlines10To13( (char*) data
) ;
158 * Generalized clipboard implementation by Matthew Flatt
161 IMPLEMENT_DYNAMIC_CLASS(wxClipboard
, wxObject
)
163 wxClipboard::wxClipboard()
169 wxClipboard::~wxClipboard()
174 m_data
= (wxDataObject
*) NULL
;
178 void wxClipboard::Clear()
183 m_data
= (wxDataObject
*) NULL
;
187 err
= ClearCurrentScrap( );
194 wxLogSysError(_("Failed to empty the clipboard."));
198 bool wxClipboard::Flush()
203 bool wxClipboard::Open()
205 wxCHECK_MSG( !m_open
, false, wxT("clipboard already open") );
210 bool wxClipboard::IsOpened() const
215 bool wxClipboard::SetData( wxDataObject
*data
)
217 wxCHECK_MSG( m_open
, false, wxT("clipboard not open") );
219 wxCHECK_MSG( data
, false, wxT("data is invalid") );
222 // as we can only store one wxDataObject, this is the same in this
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() );
248 size_t sz
= data
->GetDataSize( array
[i
] ) ;
249 void* buf
= malloc( sz
+ 1 ) ;
252 // empty the buffer because in some case GetDataHere does not fill buf
253 memset(buf
, 0, sz
+1);
254 data
->GetDataHere( array
[i
] , buf
) ;
256 switch ( array
[i
].GetType() )
260 mactype
= kScrapFlavorTypeText
;
264 case wxDF_UNICODETEXT
:
265 mactype
= kScrapFlavorTypeUnicode
;
269 #if wxUSE_DRAG_AND_DROP
271 mactype
= kScrapFlavorTypePicture
;
276 mactype
= kScrapFlavorTypePicture
;
281 UMAPutScrap( sz
, mactype
, buf
) ;
291 void wxClipboard::Close()
293 wxCHECK_RET( m_open
, wxT("clipboard not open") );
297 // Get rid of cached object. If this is not done copying from another application will
302 m_data
= (wxDataObject
*) NULL
;
307 bool wxClipboard::IsSupported( const wxDataFormat
&dataFormat
)
311 return m_data
->IsSupported( dataFormat
) ;
314 OSStatus err
= noErr
;
317 err
= GetCurrentScrap( &scrapRef
);
318 if ( err
!= noTypeErr
&& err
!= memFullErr
)
320 ScrapFlavorFlags flavorFlags
;
323 if (( err
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags
)) == noErr
)
325 if (( err
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount
)) == noErr
)
335 Handle datahandle
= NewHandle(0) ;
336 HLock( datahandle
) ;
337 GetScrap( datahandle
, dataFormat
.GetFormatId() , &offset
) ;
338 HUnlock( datahandle
) ;
339 bool hasData
= GetHandleSize( datahandle
) > 0 ;
340 DisposeHandle( datahandle
) ;
345 bool wxClipboard::GetData( wxDataObject
& data
)
347 wxCHECK_MSG( m_open
, false, wxT("clipboard not open") );
349 size_t formatcount
= data
.GetFormatCount() + 1 ;
350 wxDataFormat
*array
= new wxDataFormat
[ formatcount
];
351 array
[0] = data
.GetPreferredFormat();
352 data
.GetAllFormats( &array
[1] );
354 bool transferred
= false ;
358 for (size_t i
= 0; !transferred
&& i
< formatcount
; i
++)
360 wxDataFormat format
= array
[i
] ;
361 if ( m_data
->IsSupported( format
) )
363 int size
= m_data
->GetDataSize( format
);
368 data
.SetData(format
, 0 , 0 ) ;
372 char *d
= new char[size
];
373 m_data
->GetDataHere( format
, (void*) d
);
374 data
.SetData( format
, size
, d
) ;
380 /* get formats from wxDataObjects */
383 for (size_t i
= 0; !transferred
&& i
< formatcount
; i
++)
385 wxDataFormat format
= array
[i
] ;
387 switch ( format
.GetType() )
390 case wxDF_UNICODETEXT
:
396 char* s
= (char*)wxGetClipboardData(format
, &len
);
399 data
.SetData( format
, len
, s
) ;