]> git.saurik.com Git - wxWidgets.git/blob - src/mac/clipbrd.cpp
Applied patch [ 549256 ] fix minor bug in widgets sample
[wxWidgets.git] / src / mac / clipbrd.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: clipbrd.cpp
3 // Purpose: Clipboard functionality
4 // Author: AUTHOR
5 // Modified by:
6 // Created: ??/??/98
7 // RCS-ID: $Id$
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation
14 #pragma implementation "clipbrd.h"
15 #endif
16
17 #include "wx/app.h"
18 #include "wx/frame.h"
19 #include "wx/bitmap.h"
20 #include "wx/utils.h"
21 #include "wx/metafile.h"
22 #include "wx/clipbrd.h"
23 #include "wx/intl.h"
24 #include "wx/log.h"
25
26 #include "wx/mac/private.h"
27 #ifndef __DARWIN__
28 #include <Scrap.h>
29 #endif
30
31 #define wxUSE_DATAOBJ 1
32
33 #include <string.h>
34
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");
39
40 void *wxGetClipboardData(wxDataFormat dataFormat, long *len)
41 {
42 #if !TARGET_CARBON
43 OSErr err = noErr ;
44 #else
45 OSStatus err = noErr ;
46 #endif
47 void * data = NULL ;
48
49 switch (dataFormat.GetType())
50 {
51 case wxDF_OEMTEXT:
52 dataFormat = wxDF_TEXT;
53 // fall through
54
55 case wxDF_TEXT:
56 break;
57 default:
58 {
59 wxLogError(_("Unsupported clipboard format."));
60 return NULL;
61 }
62 }
63
64 #if TARGET_CARBON
65 ScrapRef scrapRef;
66
67 err = GetCurrentScrap( &scrapRef );
68 if ( err != noTypeErr && err != memFullErr )
69 {
70 ScrapFlavorFlags flavorFlags;
71 Size byteCount;
72
73 if (( err = GetScrapFlavorFlags( scrapRef, dataFormat.GetFormatId(), &flavorFlags )) == noErr)
74 {
75 if (( err = GetScrapFlavorSize( scrapRef, dataFormat.GetFormatId(), &byteCount )) == noErr)
76 {
77 if ( dataFormat.GetType() == wxDF_TEXT )
78 byteCount++ ;
79
80 data = new char[ byteCount ] ;
81 if (( err = GetScrapFlavorData( scrapRef, dataFormat.GetFormatId(), &byteCount , data )) == noErr )
82 {
83 *len = byteCount ;
84 if ( dataFormat.GetType() == wxDF_TEXT )
85 ((char*)data)[byteCount] = 0 ;
86 }
87 else
88 {
89 delete[] ((char *)data) ;
90 data = NULL ;
91 }
92 }
93 }
94 }
95
96 #else
97 long offset ;
98 Handle datahandle = NewHandle(0) ;
99 HLock( datahandle ) ;
100 GetScrap( datahandle , dataFormat.GetFormatId() , &offset ) ;
101 HUnlock( datahandle ) ;
102 if ( GetHandleSize( datahandle ) > 0 )
103 {
104 long byteCount = GetHandleSize( datahandle ) ;
105 if ( dataFormat.GetType() == wxDF_TEXT )
106 data = new char[ byteCount + 1] ;
107 else
108 data = new char[ byteCount ] ;
109
110 memcpy( (char*) data , (char*) *datahandle , byteCount ) ;
111 if ( dataFormat.GetType() == wxDF_TEXT )
112 ((char*)data)[byteCount] = 0 ;
113 * len = byteCount ;
114 }
115 DisposeHandle( datahandle ) ;
116 #endif
117 if ( err )
118 {
119 wxLogSysError(_("Failed to get clipboard data."));
120
121 return NULL ;
122 }
123 if ( dataFormat.GetType() == wxDF_TEXT && wxApp::s_macDefaultEncodingIsPC )
124 {
125 wxMacConvertToPC((char*)data) ;
126 }
127 return data;
128 }
129
130
131 /*
132 * Generalized clipboard implementation by Matthew Flatt
133 */
134
135 IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
136
137 wxClipboard::wxClipboard()
138 {
139 m_open = false ;
140 m_data = NULL ;
141 }
142
143 wxClipboard::~wxClipboard()
144 {
145 if (m_data)
146 {
147 delete m_data;
148 m_data = (wxDataObject*) NULL;
149 }
150 }
151
152 void wxClipboard::Clear()
153 {
154 if (m_data)
155 {
156 delete m_data;
157 m_data = (wxDataObject*) NULL;
158 }
159 #if TARGET_CARBON
160 OSStatus err ;
161 err = ClearCurrentScrap( );
162 #else
163 OSErr err ;
164 err = ZeroScrap( );
165 #endif
166 if ( err )
167 {
168 wxLogSysError(_("Failed to empty the clipboard."));
169 }
170 }
171
172 bool wxClipboard::Flush()
173 {
174 return FALSE;
175 }
176
177 bool wxClipboard::Open()
178 {
179 wxCHECK_MSG( !m_open, FALSE, wxT("clipboard already open") );
180 m_open = true ;
181 return true ;
182 }
183
184 bool wxClipboard::IsOpened() const
185 {
186 return m_open;
187 }
188
189 bool wxClipboard::SetData( wxDataObject *data )
190 {
191 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
192
193 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
194
195 Clear();
196
197 return AddData( data );
198 }
199
200 bool wxClipboard::AddData( wxDataObject *data )
201 {
202 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
203
204 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
205
206 /* we can only store one wxDataObject */
207 Clear();
208
209 m_data = data;
210
211 /* get formats from wxDataObjects */
212 wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ];
213 m_data->GetAllFormats( array );
214
215 for (size_t i = 0; i < m_data->GetFormatCount(); i++)
216 {
217 wxLogTrace( TRACE_CLIPBOARD,
218 wxT("wxClipboard now supports atom %s"),
219 array[i].GetId().c_str() );
220
221 #if !TARGET_CARBON
222 OSErr err = noErr ;
223 #else
224 OSStatus err = noErr ;
225 #endif
226
227 switch ( array[i].GetType() )
228 {
229 case wxDF_TEXT:
230 case wxDF_OEMTEXT:
231 {
232 wxTextDataObject* textDataObject = (wxTextDataObject*) data;
233 wxString str(textDataObject->GetText());
234 wxString mac ;
235 if ( wxApp::s_macDefaultEncodingIsPC )
236 {
237 mac = wxMacMakeMacStringFromPC(textDataObject->GetText()) ;
238 }
239 else
240 {
241 mac = textDataObject->GetText() ;
242 }
243 #if !TARGET_CARBON
244 err = PutScrap( mac.Length() , 'TEXT' , mac.c_str() ) ;
245 #else
246 ScrapRef scrap;
247 err = GetCurrentScrap (&scrap);
248 if ( !err )
249 {
250 err = PutScrapFlavor (scrap, 'TEXT', 0, mac.Length(), mac.c_str());
251 }
252 #endif
253 }
254 break ;
255
256 #if wxUSE_DRAG_AND_DROP
257 case wxDF_METAFILE:
258 {
259 wxMetafileDataObject* metaFileDataObject =
260 (wxMetafileDataObject*) data;
261 wxMetafile metaFile = metaFileDataObject->GetMetafile();
262 PicHandle pict = (PicHandle) metaFile.GetHMETAFILE() ;
263 HLock( (Handle) pict ) ;
264 #if !TARGET_CARBON
265 err = PutScrap( GetHandleSize( (Handle) pict ) , 'PICT' , *pict ) ;
266 #else
267 ScrapRef scrap;
268 err = GetCurrentScrap (&scrap);
269 if ( !err )
270 {
271 err = PutScrapFlavor (scrap, 'PICT', 0, GetHandleSize((Handle) pict), *pict);
272 }
273 #endif
274 HUnlock( (Handle) pict ) ;
275 }
276 break ;
277 #endif
278 case wxDF_BITMAP:
279 case wxDF_DIB:
280 default:
281 break ;
282 }
283
284 }
285
286 delete[] array;
287
288 return true ;
289 }
290
291 void wxClipboard::Close()
292 {
293 m_open = false ;
294 }
295
296 bool wxClipboard::IsSupported( const wxDataFormat &dataFormat )
297 {
298 if ( m_data )
299 {
300 return m_data->IsSupported( dataFormat ) ;
301 }
302 #if TARGET_CARBON
303 OSStatus err = noErr;
304 ScrapRef scrapRef;
305
306 err = GetCurrentScrap( &scrapRef );
307 if ( err != noTypeErr && err != memFullErr )
308 {
309 ScrapFlavorFlags flavorFlags;
310 Size byteCount;
311
312 if (( err = GetScrapFlavorFlags( scrapRef, dataFormat.GetFormatId(), &flavorFlags )) == noErr)
313 {
314 if (( err = GetScrapFlavorSize( scrapRef, dataFormat.GetFormatId(), &byteCount )) == noErr)
315 {
316 return TRUE ;
317 }
318 }
319 }
320 return FALSE;
321
322 #else
323 long offset ;
324 Handle datahandle = NewHandle(0) ;
325 HLock( datahandle ) ;
326 GetScrap( datahandle , dataFormat.GetFormatId() , &offset ) ;
327 HUnlock( datahandle ) ;
328 bool hasData = GetHandleSize( datahandle ) > 0 ;
329 DisposeHandle( datahandle ) ;
330 return hasData ;
331 #endif
332 }
333
334 bool wxClipboard::GetData( wxDataObject& data )
335 {
336 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
337
338 size_t formatcount = data.GetFormatCount() + 1 ;
339 wxDataFormat *array = new wxDataFormat[ formatcount ];
340 array[0] = data.GetPreferredFormat();
341 data.GetAllFormats( &array[1] );
342
343 bool transferred = false ;
344
345 if ( m_data )
346 {
347 for (size_t i = 0; !transferred && i < formatcount ; i++)
348 {
349 wxDataFormat format = array[i] ;
350 if ( m_data->IsSupported( format ) )
351 {
352 int size = m_data->GetDataSize( format );
353 transferred = true ;
354
355 if (size == 0)
356 {
357 data.SetData(format , 0 , 0 ) ;
358 }
359 else
360 {
361 char *d = new char[size];
362 m_data->GetDataHere( format , (void*) d );
363 data.SetData( format , size , d ) ;
364 delete[] d ;
365 }
366 }
367 }
368 }
369 /* get formats from wxDataObjects */
370 if ( !transferred )
371 {
372 for (size_t i = 0; !transferred && i < formatcount ; i++)
373 {
374 wxDataFormat format = array[i] ;
375
376 switch ( format.GetType() )
377 {
378 case wxDF_TEXT:
379 case wxDF_OEMTEXT:
380 {
381 long len ;
382 char* s = (char*)wxGetClipboardData(format, &len );
383 if ( s )
384 {
385 data.SetData( format , len , s ) ;
386 delete [] s;
387
388 transferred = true ;
389 }
390 }
391 break ;
392
393 default :
394 break ;
395 }
396 }
397 }
398
399 delete[] array ;
400 return transferred ;
401 }