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