]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/clipbrd.cpp
applied correction from Marc Newsam in calculations of linesize
[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
7c74e7fe 29// open/close
2f1ae414
SC
30
31bool clipboard_opened = false ;
32
e9576ca5
SC
33bool wxOpenClipboard()
34{
2f1ae414 35 clipboard_opened = true ;
519cb848 36 return TRUE;
e9576ca5
SC
37}
38
39bool wxCloseClipboard()
40{
2f1ae414 41 clipboard_opened = false ;
7c74e7fe 42 return TRUE;
e9576ca5
SC
43}
44
7c74e7fe 45bool wxIsClipboardOpened()
e9576ca5 46{
2f1ae414 47 return clipboard_opened;
e9576ca5
SC
48}
49
7c74e7fe 50bool wxEmptyClipboard()
e9576ca5 51{
2f1ae414
SC
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 }
7c74e7fe 65 return TRUE;
e9576ca5
SC
66}
67
2f1ae414
SC
68// get/set data
69
70// clipboard formats
71
72bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
e9576ca5 73{
2f1ae414
SC
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
e9576ca5
SC
102}
103
2f1ae414 104bool wxSetClipboardData(wxDataFormat dataFormat,const void *data,int width , int height)
e9576ca5 105{
2f1ae414
SC
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 }
e9576ca5 151
2f1ae414
SC
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 }
7c74e7fe 165
2f1ae414
SC
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 }
7c74e7fe 195
2f1ae414
SC
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;
e9576ca5
SC
233}
234
7c74e7fe 235wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat)
e9576ca5 236{
7c74e7fe 237 return wxDataFormat();
e9576ca5
SC
238}
239
7c74e7fe 240int wxRegisterClipboardFormat(wxChar *formatName)
e9576ca5 241{
e9576ca5
SC
242 return 0;
243}
244
7c74e7fe 245bool wxGetClipboardFormatName(wxDataFormat dataFormat, wxChar *formatName, int maxCount)
e9576ca5 246{
e9576ca5
SC
247 return FALSE;
248}
249
2f1ae414
SC
250void *wxGetClipboardData(wxDataFormat dataFormat, long *len)
251{
252 return NULL;
253}
254
255
e9576ca5
SC
256/*
257 * Generalized clipboard implementation by Matthew Flatt
258 */
259
2f1ae414 260IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxClipboardBase)
7c74e7fe 261
e7549107
SC
262wxClipboard::wxClipboard()
263{
264 m_clearOnExit = FALSE;
265}
e9576ca5 266
e7549107 267wxClipboard::~wxClipboard()
e9576ca5 268{
e7549107
SC
269 if ( m_clearOnExit )
270 {
271 Clear();
272 }
e9576ca5
SC
273}
274
e7549107 275void wxClipboard::Clear()
e9576ca5 276{
e9576ca5
SC
277}
278
e7549107 279bool wxClipboard::Flush()
e9576ca5 280{
e7549107
SC
281 return FALSE;
282}
283
284bool wxClipboard::Open()
285{
286 return wxOpenClipboard();
287}
288
289bool wxClipboard::IsOpened() const
290{
291 return wxIsClipboardOpened();
e9576ca5
SC
292}
293
294static int FormatStringToID(char *str)
295{
296 if (!strcmp(str, "TEXT"))
297 return wxDF_TEXT;
298
299 return wxRegisterClipboardFormat(str);
300}
301
e7549107
SC
302bool wxClipboard::SetData( wxDataObject *data )
303{
304 (void)wxEmptyClipboard();
305
306 if ( data )
307 return AddData(data);
308 else
309 return TRUE;
310}
311
312bool 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
2f1ae414 319 wxDataFormat format = data->GetPreferredFormat();
e7549107 320
2f1ae414 321 switch ( format.GetType() )
e7549107
SC
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());
2f1ae414 336 return wxSetClipboardData(format, &bitmap);
e7549107
SC
337 }
338
2f1ae414 339#if 0 // wxUSE_METAFILE
e7549107
SC
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:
2f1ae414
SC
352 // return wxSetClipboardData(data);
353 break ;
e7549107
SC
354 }
355#else // !wxUSE_DATAOBJ
e7549107 356#endif
2f1ae414 357 return FALSE;
e7549107
SC
358}
359
360void wxClipboard::Close()
361{
362 wxCloseClipboard();
363}
364
2f1ae414 365bool wxClipboard::IsSupported( const wxDataFormat &format )
e7549107
SC
366{
367 return wxIsClipboardFormatAvailable(format);
368}
369
370bool wxClipboard::GetData( wxDataObject& data )
371{
372#if wxUSE_DATAOBJ
373 wxCHECK_MSG( wxIsClipboardOpened(), FALSE, wxT("clipboard not open") );
374
2f1ae414 375 wxDataFormat format = data.GetPreferredFormat();
e7549107
SC
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;
2f1ae414 396 wxBitmap* bitmap = (wxBitmap *)wxGetClipboardData(format );
e7549107
SC
397 if ( !bitmap )
398 return FALSE;
399
400 bitmapDataObject.SetBitmap(*bitmap);
401 delete bitmap;
402
403 return TRUE;
404 }
2f1ae414 405#if 0 // wxUSE_METAFILE
e7549107
SC
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/*
e9576ca5
SC
426void 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
467wxClipboardClient *wxClipboard::GetClipboardClient()
468{
469 return clipOwner;
470}
471
472void wxClipboard::SetClipboardString(char *str, long time)
e7549107 473{
e9576ca5
SC
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}
e9576ca5
SC
500char *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
e7549107 514
e9576ca5
SC
515char *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}
e7549107 538*/
e9576ca5 539