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