]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/carbon/clipbrd.cpp
added wxListView class: this is going to be a wxListCtrl with human (inter)face
[wxWidgets.git] / src / mac / carbon / clipbrd.cpp
... / ...
CommitLineData
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!)
32static const wxChar *TRACE_CLIPBOARD = _T("clipboard");
33
34void *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
129IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxClipboardBase)
130
131wxClipboard::wxClipboard()
132{
133 m_open = false ;
134 m_data = NULL ;
135}
136
137wxClipboard::~wxClipboard()
138{
139 if (m_data)
140 {
141 delete m_data;
142 m_data = (wxDataObject*) NULL;
143 }
144}
145
146void 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
166bool wxClipboard::Flush()
167{
168 return FALSE;
169}
170
171bool wxClipboard::Open()
172{
173 wxCHECK_MSG( !m_open, FALSE, wxT("clipboard already open") );
174 m_open = true ;
175 return true ;
176}
177
178bool wxClipboard::IsOpened() const
179{
180 return m_open;
181}
182
183bool 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
194bool 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
285void wxClipboard::Close()
286{
287 m_open = false ;
288}
289
290bool 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
328bool 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}