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