]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/clipbrd.cpp
Translated a double click into just a second click for Scintilla
[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 ;
97af5088
SC
96 Handle datahandle = NewHandle(0) ;
97 HLock( datahandle ) ;
98 GetScrap( datahandle , dataFormat.GetFormatId() , &offset ) ;
99 HUnlock( datahandle ) ;
100 bool hasData = GetHandleSize( datahandle ) > 0 ;
101 DisposeHandle( datahandle ) ;
102 return hasData ;
2f1ae414 103#endif
e9576ca5
SC
104}
105
2f1ae414 106bool wxSetClipboardData(wxDataFormat dataFormat,const void *data,int width , int height)
e9576ca5 107{
2f1ae414
SC
108#if !TARGET_CARBON
109 OSErr err = noErr ;
110#else
111 OSStatus err = noErr ;
112#endif
113
114 switch (dataFormat.GetType())
115 {
116 case wxDF_BITMAP:
117 {
118 /*
119 wxBitmap *bitmap = (wxBitmap *)data;
120
121 HDC hdcMem = CreateCompatibleDC((HDC) NULL);
122 HDC hdcSrc = CreateCompatibleDC((HDC) NULL);
123 HBITMAP old = (HBITMAP)
124 ::SelectObject(hdcSrc, (HBITMAP)bitmap->GetHBITMAP());
125 HBITMAP hBitmap = CreateCompatibleBitmap(hdcSrc,
126 bitmap->GetWidth(),
127 bitmap->GetHeight());
128 if (!hBitmap)
129 {
130 SelectObject(hdcSrc, old);
131 DeleteDC(hdcMem);
132 DeleteDC(hdcSrc);
133 return FALSE;
134 }
135
136 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hBitmap);
137 BitBlt(hdcMem, 0, 0, bitmap->GetWidth(), bitmap->GetHeight(),
138 hdcSrc, 0, 0, SRCCOPY);
139
140 // Select new bitmap out of memory DC
141 SelectObject(hdcMem, old1);
142
143 // Set the data
144 handle = ::SetClipboardData(CF_BITMAP, hBitmap);
145
146 // Clean up
147 SelectObject(hdcSrc, old);
148 DeleteDC(hdcSrc);
149 DeleteDC(hdcMem);
150 */
151 break;
152 }
e9576ca5 153
2f1ae414
SC
154 case wxDF_DIB:
155 {
156 /*
157#if wxUSE_IMAGE_LOADING_IN_MSW
158 wxBitmap *bitmap = (wxBitmap *)data;
159 HBITMAP hBitmap = (HBITMAP)bitmap->GetHBITMAP();
160 // NULL palette means to use the system one
161 HANDLE hDIB = wxBitmapToDIB(hBitmap, (HPALETTE)NULL);
162 handle = SetClipboardData(CF_DIB, hDIB);
163#endif // wxUSE_IMAGE_LOADING_IN_MSW
164*/
165 break;
166 }
7c74e7fe 167
2f1ae414
SC
168#if wxUSE_METAFILE
169 case wxDF_METAFILE:
170 {
171 wxMetafile *wxMF = (wxMetafile *)data;
172 PicHandle pict = wxMF->GetHMETAFILE() ;
173 HLock( (Handle) pict ) ;
174#if !TARGET_CARBON
175 err = PutScrap( GetHandleSize( (Handle) pict ) , 'PICT' , *pict ) ;
176#else
177 ScrapRef scrap;
178 err = GetCurrentScrap (&scrap);
179 if ( !err )
180 {
181 err = PutScrapFlavor (scrap, 'PICT', 0, GetHandleSize((Handle) pict), *pict);
182 }
183#endif
184 HUnlock( (Handle) pict ) ;
185 break;
186 }
187#endif
188 case wxDF_SYLK:
189 case wxDF_DIF:
190 case wxDF_TIFF:
191 case wxDF_PALETTE:
192 default:
193 {
194 wxLogError(_("Unsupported clipboard format."));
195 return FALSE;
196 }
7c74e7fe 197
2f1ae414
SC
198 case wxDF_OEMTEXT:
199 dataFormat = wxDF_TEXT;
200 // fall through
201
202 case wxDF_TEXT:
203 {
204 wxString mac ;
205 if ( wxApp::s_macDefaultEncodingIsPC )
206 {
207 mac = wxMacMakeMacStringFromPC((char *)data) ;
208 }
209 else
210 {
211 mac = (char *)data ;
212 }
213#if !TARGET_CARBON
214 err = PutScrap( mac.Length() , 'TEXT' , mac.c_str() ) ;
215#else
216 ScrapRef scrap;
217 err = GetCurrentScrap (&scrap);
218 if ( !err )
219 {
220 err = PutScrapFlavor (scrap, 'TEXT', 0, mac.Length(), mac.c_str());
221 }
222#endif
223 break;
224 }
225 }
226
227 if ( err )
228 {
229 wxLogSysError(_("Failed to set clipboard data."));
230
231 return FALSE;
232 }
233
234 return TRUE;
e9576ca5
SC
235}
236
7c74e7fe 237wxDataFormat wxEnumClipboardFormats(wxDataFormat dataFormat)
e9576ca5 238{
7c74e7fe 239 return wxDataFormat();
e9576ca5
SC
240}
241
7c74e7fe 242int wxRegisterClipboardFormat(wxChar *formatName)
e9576ca5 243{
e9576ca5
SC
244 return 0;
245}
246
7c74e7fe 247bool wxGetClipboardFormatName(wxDataFormat dataFormat, wxChar *formatName, int maxCount)
e9576ca5 248{
e9576ca5
SC
249 return FALSE;
250}
251
2f1ae414
SC
252void *wxGetClipboardData(wxDataFormat dataFormat, long *len)
253{
97af5088
SC
254#if !TARGET_CARBON
255 OSErr err = noErr ;
256#else
257 OSStatus err = noErr ;
258#endif
259 void * data = NULL ;
260
261 switch (dataFormat.GetType())
262 {
263 case wxDF_BITMAP:
264 case wxDF_DIB:
265#if wxUSE_METAFILE
266 case wxDF_METAFILE:
267#endif
268 case wxDF_SYLK:
269 case wxDF_DIF:
270 case wxDF_TIFF:
271 case wxDF_PALETTE:
272 default:
273 {
274 wxLogError(_("Unsupported clipboard format."));
275 return NULL;
276 }
277
278 case wxDF_OEMTEXT:
279 dataFormat = wxDF_TEXT;
280 // fall through
281
282 case wxDF_TEXT:
283 break;
284 }
285
286#if TARGET_CARBON
287 ScrapRef scrapRef;
288
289 err = GetCurrentScrap( &scrapRef );
290 if ( err != noTypeErr && err != memFullErr )
291 {
292 ScrapFlavorFlags flavorFlags;
293 Size byteCount;
294
295 if (( err = GetScrapFlavorFlags( scrapRef, dataFormat.GetFormatId(), &flavorFlags )) == noErr)
296 {
297 if (( err = GetScrapFlavorSize( scrapRef, dataFormat.GetFormatId(), &byteCount )) == noErr)
298 {
299 if ( dataFormat.GetType() == wxDF_TEXT )
300 byteCount++ ;
301
302 data = new char[ byteCount ] ;
303 if (( err = GetScrapFlavorData( scrapRef, dataFormat.GetFormatId(), &byteCount , data )) == noErr )
304 {
305 *len = byteCount ;
306 if ( dataFormat.GetType() == wxDF_TEXT )
307 ((char*)data)[byteCount] = 0 ;
308 }
309 else
310 {
311 delete[] data ;
312 data = NULL ;
313 }
314 }
315 }
316 }
317
318#else
319 long offset ;
320 Handle datahandle = NewHandle(0) ;
321 HLock( datahandle ) ;
322 GetScrap( datahandle , dataFormat.GetFormatId() , &offset ) ;
323 HUnlock( datahandle ) ;
324 if ( GetHandleSize( datahandle ) > 0 )
325 {
326 long byteCount = GetHandleSize( datahandle ) ;
327 if ( dataFormat.GetType() == wxDF_TEXT )
328 data = new char[ byteCount + 1] ;
329 else
330 data = new char[ byteCount ] ;
331
332 memcpy( (char*) data , (char*) *datahandle , byteCount ) ;
333 if ( dataFormat.GetType() == wxDF_TEXT )
334 ((char*)data)[byteCount] = 0 ;
335 * len = byteCount ;
336 }
337 DisposeHandle( datahandle ) ;
338#endif
339 if ( err )
340 {
341 wxLogSysError(_("Failed to get clipboard data."));
342
343 return NULL ;
344 }
345 if ( dataFormat.GetType() == wxDF_TEXT && wxApp::s_macDefaultEncodingIsPC )
346 {
347 wxMacConvertToPC((char*)data) ;
348 }
349 return data;
2f1ae414
SC
350}
351
352
e9576ca5
SC
353/*
354 * Generalized clipboard implementation by Matthew Flatt
355 */
356
2f1ae414 357IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxClipboardBase)
7c74e7fe 358
e7549107
SC
359wxClipboard::wxClipboard()
360{
361 m_clearOnExit = FALSE;
362}
e9576ca5 363
e7549107 364wxClipboard::~wxClipboard()
e9576ca5 365{
e7549107
SC
366 if ( m_clearOnExit )
367 {
368 Clear();
369 }
e9576ca5
SC
370}
371
e7549107 372void wxClipboard::Clear()
e9576ca5 373{
e9576ca5
SC
374}
375
e7549107 376bool wxClipboard::Flush()
e9576ca5 377{
e7549107
SC
378 return FALSE;
379}
380
381bool wxClipboard::Open()
382{
383 return wxOpenClipboard();
384}
385
386bool wxClipboard::IsOpened() const
387{
388 return wxIsClipboardOpened();
e9576ca5
SC
389}
390
391static int FormatStringToID(char *str)
392{
393 if (!strcmp(str, "TEXT"))
394 return wxDF_TEXT;
395
396 return wxRegisterClipboardFormat(str);
397}
398
e7549107
SC
399bool wxClipboard::SetData( wxDataObject *data )
400{
401 (void)wxEmptyClipboard();
402
403 if ( data )
404 return AddData(data);
405 else
406 return TRUE;
407}
408
409bool wxClipboard::AddData( wxDataObject *data )
410{
411 wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
412
413#if wxUSE_DATAOBJ
414 wxCHECK_MSG( wxIsClipboardOpened(), FALSE, wxT("clipboard not open") );
415
2f1ae414 416 wxDataFormat format = data->GetPreferredFormat();
e7549107 417
2f1ae414 418 switch ( format.GetType() )
e7549107
SC
419 {
420 case wxDF_TEXT:
421 case wxDF_OEMTEXT:
422 {
423 wxTextDataObject* textDataObject = (wxTextDataObject*) data;
424 wxString str(textDataObject->GetText());
425 return wxSetClipboardData(format, str.c_str());
426 }
427
428 case wxDF_BITMAP:
429 case wxDF_DIB:
430 {
431 wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
432 wxBitmap bitmap(bitmapDataObject->GetBitmap());
2f1ae414 433 return wxSetClipboardData(format, &bitmap);
e7549107
SC
434 }
435
2f1ae414 436#if 0 // wxUSE_METAFILE
e7549107
SC
437 case wxDF_METAFILE:
438 {
439 wxMetafileDataObject* metaFileDataObject =
440 (wxMetafileDataObject*) data;
441 wxMetafile metaFile = metaFileDataObject->GetMetafile();
442 return wxSetClipboardData(wxDF_METAFILE, &metaFile,
443 metaFileDataObject->GetWidth(),
444 metaFileDataObject->GetHeight());
445 }
446#endif // wxUSE_METAFILE
447
448 default:
2f1ae414
SC
449 // return wxSetClipboardData(data);
450 break ;
e7549107
SC
451 }
452#else // !wxUSE_DATAOBJ
e7549107 453#endif
2f1ae414 454 return FALSE;
e7549107
SC
455}
456
457void wxClipboard::Close()
458{
459 wxCloseClipboard();
460}
461
2f1ae414 462bool wxClipboard::IsSupported( const wxDataFormat &format )
e7549107
SC
463{
464 return wxIsClipboardFormatAvailable(format);
465}
466
467bool wxClipboard::GetData( wxDataObject& data )
468{
469#if wxUSE_DATAOBJ
470 wxCHECK_MSG( wxIsClipboardOpened(), FALSE, wxT("clipboard not open") );
471
2f1ae414 472 wxDataFormat format = data.GetPreferredFormat();
97af5088 473 switch ( format.GetType() )
e7549107
SC
474 {
475 case wxDF_TEXT:
476 case wxDF_OEMTEXT:
477 {
478 wxTextDataObject& textDataObject = (wxTextDataObject &)data;
479 char* s = (char*)wxGetClipboardData(format);
480 if ( !s )
481 return FALSE;
482
483 textDataObject.SetText(s);
484 delete [] s;
485
486 return TRUE;
487 }
488
489 case wxDF_BITMAP:
490 case wxDF_DIB:
491 {
492 wxBitmapDataObject& bitmapDataObject = (wxBitmapDataObject &)data;
2f1ae414 493 wxBitmap* bitmap = (wxBitmap *)wxGetClipboardData(format );
e7549107
SC
494 if ( !bitmap )
495 return FALSE;
496
497 bitmapDataObject.SetBitmap(*bitmap);
498 delete bitmap;
499
500 return TRUE;
501 }
2f1ae414 502#if 0 // wxUSE_METAFILE
e7549107
SC
503 case wxDF_METAFILE:
504 {
505 wxMetafileDataObject& metaFileDataObject = (wxMetafileDataObject &)data;
506 wxMetafile* metaFile = (wxMetafile *)wxGetClipboardData(wxDF_METAFILE);
507 if ( !metaFile )
508 return FALSE;
509
510 metaFileDataObject.SetMetafile(*metaFile);
511 delete metaFile;
512
513 return TRUE;
514 }
515#endif // wxUSE_METAFILE
516 }
517#else // !wxUSE_DATAOBJ
518 wxFAIL_MSG( wxT("no clipboard implementation") );
519#endif
520 return FALSE;
521}
522/*
e9576ca5
SC
523void wxClipboard::SetClipboardClient(wxClipboardClient *client, long time)
524{
525 bool got_selection;
526
527 if (clipOwner)
528 clipOwner->BeingReplaced();
529 clipOwner = client;
530 if (cbString) {
531 delete[] cbString;
532 cbString = NULL;
533 }
534
535 if (wxOpenClipboard()) {
536 char **formats, *data;
537 int i;
538 int ftype;
539 long size;
540
541 formats = clipOwner->formats.ListToArray(FALSE);
542 for (i = clipOwner->formats.Number(); i--; ) {
543 ftype = FormatStringToID(formats[i]);
544 data = clipOwner->GetData(formats[i], &size);
545 if (!wxSetClipboardData(ftype, (wxObject *)data, size, 1)) {
546 got_selection = FALSE;
547 break;
548 }
549 }
550
551 if (i < 0)
552 got_selection = wxCloseClipboard();
553 } else
554 got_selection = FALSE;
555
556 got_selection = FALSE; // Assume another process takes over
557
558 if (!got_selection) {
559 clipOwner->BeingReplaced();
560 clipOwner = NULL;
561 }
562}
563
564wxClipboardClient *wxClipboard::GetClipboardClient()
565{
566 return clipOwner;
567}
568
569void wxClipboard::SetClipboardString(char *str, long time)
e7549107 570{
e9576ca5
SC
571 bool got_selection;
572
573 if (clipOwner) {
574 clipOwner->BeingReplaced();
575 clipOwner = NULL;
576 }
577 if (cbString)
578 delete[] cbString;
579
580 cbString = str;
581
582 if (wxOpenClipboard()) {
583 if (!wxSetClipboardData(wxDF_TEXT, (wxObject *)str))
584 got_selection = FALSE;
585 else
586 got_selection = wxCloseClipboard();
587 } else
588 got_selection = FALSE;
589
590 got_selection = FALSE; // Assume another process takes over
591
592 if (!got_selection) {
593 delete[] cbString;
594 cbString = NULL;
595 }
596}
e9576ca5
SC
597char *wxClipboard::GetClipboardString(long time)
598{
599 char *str;
600 long length;
601
602 str = GetClipboardData("TEXT", &length, time);
603 if (!str) {
604 str = new char[1];
605 *str = 0;
606 }
607
608 return str;
609}
610
e7549107 611
e9576ca5
SC
612char *wxClipboard::GetClipboardData(char *format, long *length, long time)
613{
614 if (clipOwner) {
615 if (clipOwner->formats.Member(format))
616 return clipOwner->GetData(format, length);
617 else
618 return NULL;
619 } else if (cbString) {
620 if (!strcmp(format, "TEXT"))
621 return copystring(cbString);
622 else
623 return NULL;
624 } else {
625 if (wxOpenClipboard()) {
626 receivedString = (char *)wxGetClipboardData(FormatStringToID(format),
627 length);
628 wxCloseClipboard();
629 } else
630 receivedString = NULL;
631
632 return receivedString;
633 }
634}
e7549107 635*/
e9576ca5 636