]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/clipbrd.cpp
applied correction from Marc Newsam in calculations of linesize
[wxWidgets.git] / src / mac / carbon / 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 // open/close
30
31 bool clipboard_opened = false ;
32
33 bool wxOpenClipboard()
34 {
35 clipboard_opened = true ;
36 return TRUE;
37 }
38
39 bool wxCloseClipboard()
40 {
41 clipboard_opened = false ;
42 return TRUE;
43 }
44
45 bool wxIsClipboardOpened()
46 {
47 return clipboard_opened;
48 }
49
50 bool wxEmptyClipboard()
51 {
52
53 #if TARGET_CARBON
54 OSStatus err ;
55 err = ClearCurrentScrap( );
56 #else
57 OSErr err ;
58 err = ZeroScrap( );
59 #endif
60 if ( err )
61 {
62 wxLogSysError(_("Failed to empty the clipboard."));
63 return FALSE ;
64 }
65 return TRUE;
66 }
67
68 // get/set data
69
70 // clipboard formats
71
72 bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
73 {
74 #if TARGET_CARBON
75 OSStatus err = noErr;
76 ScrapRef scrapRef;
77
78 err = GetCurrentScrap( &scrapRef );
79 if ( err != noTypeErr && err != memFullErr )
80 {
81 ScrapFlavorFlags flavorFlags;
82 Size byteCount;
83
84 if (( err = GetScrapFlavorFlags( scrapRef, dataFormat.GetFormatId(), &flavorFlags )) == noErr)
85 {
86 if (( err = GetScrapFlavorSize( scrapRef, dataFormat.GetFormatId(), &byteCount )) == noErr)
87 {
88 return TRUE ;
89 }
90 }
91 }
92 return FALSE;
93
94 #else
95 long offset ;
96 if ( GetScrap( NULL , dataFormat.GetFormatId() , &offset ) > 0 )
97 {
98 return TRUE ;
99 }
100 return FALSE;
101 #endif
102 }
103
104 bool wxSetClipboardData(wxDataFormat dataFormat,const void *data,int width , int height)
105 {
106 #if !TARGET_CARBON
107 OSErr err = noErr ;
108 #else
109 OSStatus err = noErr ;
110 #endif
111
112 switch (dataFormat.GetType())
113 {
114 case wxDF_BITMAP:
115 {
116 /*
117 wxBitmap *bitmap = (wxBitmap *)data;
118
119 HDC hdcMem = CreateCompatibleDC((HDC) NULL);
120 HDC hdcSrc = CreateCompatibleDC((HDC) NULL);
121 HBITMAP old = (HBITMAP)
122 ::SelectObject(hdcSrc, (HBITMAP)bitmap->GetHBITMAP());
123 HBITMAP hBitmap = CreateCompatibleBitmap(hdcSrc,
124 bitmap->GetWidth(),
125 bitmap->GetHeight());
126 if (!hBitmap)
127 {
128 SelectObject(hdcSrc, old);
129 DeleteDC(hdcMem);
130 DeleteDC(hdcSrc);
131 return FALSE;
132 }
133
134 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hBitmap);
135 BitBlt(hdcMem, 0, 0, bitmap->GetWidth(), bitmap->GetHeight(),
136 hdcSrc, 0, 0, SRCCOPY);
137
138 // Select new bitmap out of memory DC
139 SelectObject(hdcMem, old1);
140
141 // Set the data
142 handle = ::SetClipboardData(CF_BITMAP, hBitmap);
143
144 // Clean up
145 SelectObject(hdcSrc, old);
146 DeleteDC(hdcSrc);
147 DeleteDC(hdcMem);
148 */
149 break;
150 }
151
152 case wxDF_DIB:
153 {
154 /*
155 #if wxUSE_IMAGE_LOADING_IN_MSW
156 wxBitmap *bitmap = (wxBitmap *)data;
157 HBITMAP hBitmap = (HBITMAP)bitmap->GetHBITMAP();
158 // NULL palette means to use the system one
159 HANDLE hDIB = wxBitmapToDIB(hBitmap, (HPALETTE)NULL);
160 handle = SetClipboardData(CF_DIB, hDIB);
161 #endif // wxUSE_IMAGE_LOADING_IN_MSW
162 */
163 break;
164 }
165
166 #if wxUSE_METAFILE
167 case wxDF_METAFILE:
168 {
169 wxMetafile *wxMF = (wxMetafile *)data;
170 PicHandle pict = wxMF->GetHMETAFILE() ;
171 HLock( (Handle) pict ) ;
172 #if !TARGET_CARBON
173 err = PutScrap( GetHandleSize( (Handle) pict ) , 'PICT' , *pict ) ;
174 #else
175 ScrapRef scrap;
176 err = GetCurrentScrap (&scrap);
177 if ( !err )
178 {
179 err = PutScrapFlavor (scrap, 'PICT', 0, GetHandleSize((Handle) pict), *pict);
180 }
181 #endif
182 HUnlock( (Handle) pict ) ;
183 break;
184 }
185 #endif
186 case wxDF_SYLK:
187 case wxDF_DIF:
188 case wxDF_TIFF:
189 case wxDF_PALETTE:
190 default:
191 {
192 wxLogError(_("Unsupported clipboard format."));
193 return FALSE;
194 }
195
196 case wxDF_OEMTEXT:
197 dataFormat = wxDF_TEXT;
198 // fall through
199
200 case wxDF_TEXT:
201 {
202 wxString mac ;
203 if ( wxApp::s_macDefaultEncodingIsPC )
204 {
205 mac = wxMacMakeMacStringFromPC((char *)data) ;
206 }
207 else
208 {
209 mac = (char *)data ;
210 }
211 #if !TARGET_CARBON
212 err = PutScrap( mac.Length() , 'TEXT' , mac.c_str() ) ;
213 #else
214 ScrapRef scrap;
215 err = GetCurrentScrap (&scrap);
216 if ( !err )
217 {
218 err = PutScrapFlavor (scrap, 'TEXT', 0, mac.Length(), mac.c_str());
219 }
220 #endif
221 break;
222 }
223 }
224
225 if ( err )
226 {
227 wxLogSysError(_("Failed to set clipboard data."));
228
229 return FALSE;
230 }
231
232 return TRUE;
233 }
234
235 wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat)
236 {
237 return wxDataFormat();
238 }
239
240 int wxRegisterClipboardFormat(wxChar *formatName)
241 {
242 return 0;
243 }
244
245 bool wxGetClipboardFormatName(wxDataFormat dataFormat, wxChar *formatName, int maxCount)
246 {
247 return FALSE;
248 }
249
250 void *wxGetClipboardData(wxDataFormat dataFormat, long *len)
251 {
252 return NULL;
253 }
254
255
256 /*
257 * Generalized clipboard implementation by Matthew Flatt
258 */
259
260 IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxClipboardBase)
261
262 wxClipboard::wxClipboard()
263 {
264 m_clearOnExit = FALSE;
265 }
266
267 wxClipboard::~wxClipboard()
268 {
269 if ( m_clearOnExit )
270 {
271 Clear();
272 }
273 }
274
275 void wxClipboard::Clear()
276 {
277 }
278
279 bool wxClipboard::Flush()
280 {
281 return FALSE;
282 }
283
284 bool wxClipboard::Open()
285 {
286 return wxOpenClipboard();
287 }
288
289 bool wxClipboard::IsOpened() const
290 {
291 return wxIsClipboardOpened();
292 }
293
294 static int FormatStringToID(char *str)
295 {
296 if (!strcmp(str, "TEXT"))
297 return wxDF_TEXT;
298
299 return wxRegisterClipboardFormat(str);
300 }
301
302 bool wxClipboard::SetData( wxDataObject *data )
303 {
304 (void)wxEmptyClipboard();
305
306 if ( data )
307 return AddData(data);
308 else
309 return TRUE;
310 }
311
312 bool wxClipboard::AddData( wxDataObject *data )
313 {
314 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
315
316 #if wxUSE_DATAOBJ
317 wxCHECK_MSG( wxIsClipboardOpened(), FALSE, wxT("clipboard not open") );
318
319 wxDataFormat format = data->GetPreferredFormat();
320
321 switch ( format.GetType() )
322 {
323 case wxDF_TEXT:
324 case wxDF_OEMTEXT:
325 {
326 wxTextDataObject* textDataObject = (wxTextDataObject*) data;
327 wxString str(textDataObject->GetText());
328 return wxSetClipboardData(format, str.c_str());
329 }
330
331 case wxDF_BITMAP:
332 case wxDF_DIB:
333 {
334 wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
335 wxBitmap bitmap(bitmapDataObject->GetBitmap());
336 return wxSetClipboardData(format, &bitmap);
337 }
338
339 #if 0 // wxUSE_METAFILE
340 case wxDF_METAFILE:
341 {
342 wxMetafileDataObject* metaFileDataObject =
343 (wxMetafileDataObject*) data;
344 wxMetafile metaFile = metaFileDataObject->GetMetafile();
345 return wxSetClipboardData(wxDF_METAFILE, &metaFile,
346 metaFileDataObject->GetWidth(),
347 metaFileDataObject->GetHeight());
348 }
349 #endif // wxUSE_METAFILE
350
351 default:
352 // return wxSetClipboardData(data);
353 break ;
354 }
355 #else // !wxUSE_DATAOBJ
356 #endif
357 return FALSE;
358 }
359
360 void wxClipboard::Close()
361 {
362 wxCloseClipboard();
363 }
364
365 bool wxClipboard::IsSupported( const wxDataFormat &format )
366 {
367 return wxIsClipboardFormatAvailable(format);
368 }
369
370 bool wxClipboard::GetData( wxDataObject& data )
371 {
372 #if wxUSE_DATAOBJ
373 wxCHECK_MSG( wxIsClipboardOpened(), FALSE, wxT("clipboard not open") );
374
375 wxDataFormat format = data.GetPreferredFormat();
376 switch ( format )
377 {
378 case wxDF_TEXT:
379 case wxDF_OEMTEXT:
380 {
381 wxTextDataObject& textDataObject = (wxTextDataObject &)data;
382 char* s = (char*)wxGetClipboardData(format);
383 if ( !s )
384 return FALSE;
385
386 textDataObject.SetText(s);
387 delete [] s;
388
389 return TRUE;
390 }
391
392 case wxDF_BITMAP:
393 case wxDF_DIB:
394 {
395 wxBitmapDataObject& bitmapDataObject = (wxBitmapDataObject &)data;
396 wxBitmap* bitmap = (wxBitmap *)wxGetClipboardData(format );
397 if ( !bitmap )
398 return FALSE;
399
400 bitmapDataObject.SetBitmap(*bitmap);
401 delete bitmap;
402
403 return TRUE;
404 }
405 #if 0 // wxUSE_METAFILE
406 case wxDF_METAFILE:
407 {
408 wxMetafileDataObject& metaFileDataObject = (wxMetafileDataObject &)data;
409 wxMetafile* metaFile = (wxMetafile *)wxGetClipboardData(wxDF_METAFILE);
410 if ( !metaFile )
411 return FALSE;
412
413 metaFileDataObject.SetMetafile(*metaFile);
414 delete metaFile;
415
416 return TRUE;
417 }
418 #endif // wxUSE_METAFILE
419 }
420 #else // !wxUSE_DATAOBJ
421 wxFAIL_MSG( wxT("no clipboard implementation") );
422 #endif
423 return FALSE;
424 }
425 /*
426 void wxClipboard::SetClipboardClient(wxClipboardClient *client, long time)
427 {
428 bool got_selection;
429
430 if (clipOwner)
431 clipOwner->BeingReplaced();
432 clipOwner = client;
433 if (cbString) {
434 delete[] cbString;
435 cbString = NULL;
436 }
437
438 if (wxOpenClipboard()) {
439 char **formats, *data;
440 int i;
441 int ftype;
442 long size;
443
444 formats = clipOwner->formats.ListToArray(FALSE);
445 for (i = clipOwner->formats.Number(); i--; ) {
446 ftype = FormatStringToID(formats[i]);
447 data = clipOwner->GetData(formats[i], &size);
448 if (!wxSetClipboardData(ftype, (wxObject *)data, size, 1)) {
449 got_selection = FALSE;
450 break;
451 }
452 }
453
454 if (i < 0)
455 got_selection = wxCloseClipboard();
456 } else
457 got_selection = FALSE;
458
459 got_selection = FALSE; // Assume another process takes over
460
461 if (!got_selection) {
462 clipOwner->BeingReplaced();
463 clipOwner = NULL;
464 }
465 }
466
467 wxClipboardClient *wxClipboard::GetClipboardClient()
468 {
469 return clipOwner;
470 }
471
472 void wxClipboard::SetClipboardString(char *str, long time)
473 {
474 bool got_selection;
475
476 if (clipOwner) {
477 clipOwner->BeingReplaced();
478 clipOwner = NULL;
479 }
480 if (cbString)
481 delete[] cbString;
482
483 cbString = str;
484
485 if (wxOpenClipboard()) {
486 if (!wxSetClipboardData(wxDF_TEXT, (wxObject *)str))
487 got_selection = FALSE;
488 else
489 got_selection = wxCloseClipboard();
490 } else
491 got_selection = FALSE;
492
493 got_selection = FALSE; // Assume another process takes over
494
495 if (!got_selection) {
496 delete[] cbString;
497 cbString = NULL;
498 }
499 }
500 char *wxClipboard::GetClipboardString(long time)
501 {
502 char *str;
503 long length;
504
505 str = GetClipboardData("TEXT", &length, time);
506 if (!str) {
507 str = new char[1];
508 *str = 0;
509 }
510
511 return str;
512 }
513
514
515 char *wxClipboard::GetClipboardData(char *format, long *length, long time)
516 {
517 if (clipOwner) {
518 if (clipOwner->formats.Member(format))
519 return clipOwner->GetData(format, length);
520 else
521 return NULL;
522 } else if (cbString) {
523 if (!strcmp(format, "TEXT"))
524 return copystring(cbString);
525 else
526 return NULL;
527 } else {
528 if (wxOpenClipboard()) {
529 receivedString = (char *)wxGetClipboardData(FormatStringToID(format),
530 length);
531 wxCloseClipboard();
532 } else
533 receivedString = NULL;
534
535 return receivedString;
536 }
537 }
538 */
539