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