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