]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/clipbrd.cpp
- better behaviour of wxMGL's wxTimer w.r.t. memory allocations
[wxWidgets.git] / src / mac / carbon / clipbrd.cpp
CommitLineData
e9576ca5
SC
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"
5fde6fcc 23#include "wx/intl.h"
e9576ca5 24
2f1ae414
SC
25#define wxUSE_DATAOBJ 1
26
e9576ca5
SC
27#include <string.h>
28
f0822896
SC
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!)
32static const wxChar *TRACE_CLIPBOARD = _T("clipboard");
2f1ae414 33
f0822896 34void *wxGetClipboardData(wxDataFormat dataFormat, long *len)
e9576ca5 35{
2f1ae414
SC
36#if !TARGET_CARBON
37 OSErr err = noErr ;
38#else
39 OSStatus err = noErr ;
40#endif
f0822896 41 void * data = NULL ;
2f1ae414
SC
42
43 switch (dataFormat.GetType())
44 {
2f1ae414
SC
45 case wxDF_OEMTEXT:
46 dataFormat = wxDF_TEXT;
47 // fall through
48
49 case wxDF_TEXT:
2f1ae414 50 break;
97af5088
SC
51 default:
52 {
53 wxLogError(_("Unsupported clipboard format."));
54 return NULL;
55 }
97af5088
SC
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 {
6d5e7307 83 delete[] ((char *)data) ;
97af5088
SC
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;
2f1ae414
SC
122}
123
124
e9576ca5
SC
125/*
126 * Generalized clipboard implementation by Matthew Flatt
127 */
128
2f1ae414 129IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxClipboardBase)
7c74e7fe 130
e7549107
SC
131wxClipboard::wxClipboard()
132{
f0822896
SC
133 m_open = false ;
134 m_data = NULL ;
e7549107 135}
e9576ca5 136
e7549107 137wxClipboard::~wxClipboard()
e9576ca5 138{
f0822896 139 if (m_data)
e7549107 140 {
f0822896
SC
141 delete m_data;
142 m_data = (wxDataObject*) NULL;
e7549107 143 }
e9576ca5
SC
144}
145
e7549107 146void wxClipboard::Clear()
e9576ca5 147{
f0822896
SC
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 }
e9576ca5
SC
164}
165
e7549107 166bool wxClipboard::Flush()
e9576ca5 167{
e7549107
SC
168 return FALSE;
169}
170
171bool wxClipboard::Open()
172{
f0822896
SC
173 wxCHECK_MSG( !m_open, FALSE, wxT("clipboard already open") );
174 m_open = true ;
175 return true ;
e7549107
SC
176}
177
178bool wxClipboard::IsOpened() const
179{
f0822896 180 return m_open;
e9576ca5
SC
181}
182
f0822896 183bool wxClipboard::SetData( wxDataObject *data )
e9576ca5 184{
f0822896 185 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
e9576ca5 186
f0822896 187 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
e9576ca5 188
f0822896 189 Clear();
e7549107 190
f0822896 191 return AddData( data );
e7549107
SC
192}
193
194bool wxClipboard::AddData( wxDataObject *data )
195{
f0822896 196 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
e7549107 197
f0822896 198 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
e7549107 199
2f1ae414 200 wxDataFormat format = data->GetPreferredFormat();
e7549107 201
f0822896
SC
202 /* we can only store one wxDataObject */
203 Clear();
e7549107 204
f0822896 205 m_data = data;
e7549107 206
f0822896
SC
207 /* get formats from wxDataObjects */
208 wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ];
209 m_data->GetAllFormats( array );
e7549107 210
f0822896
SC
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() );
e7549107 216
f0822896
SC
217#if !TARGET_CARBON
218 OSErr err = noErr ;
219#else
220 OSStatus err = noErr ;
221#endif
e7549107 222
f0822896
SC
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
e7549107 252 case wxDF_METAFILE:
f0822896
SC
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 }
e7549107 271#endif
f0822896
SC
272 case wxDF_BITMAP:
273 case wxDF_DIB:
274 default:
275 break ;
276 }
e9576ca5 277
e9576ca5
SC
278 }
279
f0822896 280 delete[] array;
e9576ca5 281
f0822896 282 return true ;
e9576ca5
SC
283}
284
f0822896 285void wxClipboard::Close()
e9576ca5 286{
f0822896 287 m_open = false ;
e9576ca5
SC
288}
289
f0822896 290bool wxClipboard::IsSupported( const wxDataFormat &dataFormat )
e7549107 291{
f0822896
SC
292 if ( m_data )
293 {
294 return m_data->IsSupported( dataFormat ) ;
e9576ca5 295 }
f0822896
SC
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
e9576ca5 326}
f0822896
SC
327
328bool wxClipboard::GetData( wxDataObject& data )
e9576ca5 329{
f0822896 330 wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
e9576ca5 331
f0822896
SC
332 int formatcount = data.GetFormatCount() + 1 ;
333 wxDataFormat *array = new wxDataFormat[ formatcount ];
334 array[0] = data.GetPreferredFormat();
335 data.GetAllFormats( &array[1] );
e9576ca5 336
f0822896 337 bool transferred = false ;
e9576ca5 338
f0822896
SC
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 ;
e7549107 348
f0822896
SC
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 {
f0822896
SC
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 }
e9576ca5 390
f0822896
SC
391 delete[] array ;
392 return transferred ;
393}