1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Clipboard functionality
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation
14 #pragma implementation "clipbrd.h"
19 #include "wx/bitmap.h"
21 #include "wx/metafile.h"
22 #include "wx/clipbrd.h"
25 #define wxUSE_DATAOBJ 1
31 bool clipboard_opened
= false ;
33 bool wxOpenClipboard()
35 clipboard_opened
= true ;
39 bool wxCloseClipboard()
41 clipboard_opened
= false ;
45 bool wxIsClipboardOpened()
47 return clipboard_opened
;
50 bool wxEmptyClipboard()
55 err
= ClearCurrentScrap( );
62 wxLogSysError(_("Failed to empty the clipboard."));
72 bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat
)
78 err
= GetCurrentScrap( &scrapRef
);
79 if ( err
!= noTypeErr
&& err
!= memFullErr
)
81 ScrapFlavorFlags flavorFlags
;
84 if (( err
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags
)) == noErr
)
86 if (( err
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount
)) == noErr
)
96 Handle datahandle
= NewHandle(0) ;
98 GetScrap( datahandle
, dataFormat
.GetFormatId() , &offset
) ;
99 HUnlock( datahandle
) ;
100 bool hasData
= GetHandleSize( datahandle
) > 0 ;
101 DisposeHandle( datahandle
) ;
106 bool wxSetClipboardData(wxDataFormat dataFormat
,const void *data
,int width
, int height
)
111 OSStatus err
= noErr
;
114 switch (dataFormat
.GetType())
119 wxBitmap *bitmap = (wxBitmap *)data;
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,
127 bitmap->GetHeight());
130 SelectObject(hdcSrc, old);
136 HBITMAP old1 = (HBITMAP) SelectObject(hdcMem, hBitmap);
137 BitBlt(hdcMem, 0, 0, bitmap->GetWidth(), bitmap->GetHeight(),
138 hdcSrc, 0, 0, SRCCOPY);
140 // Select new bitmap out of memory DC
141 SelectObject(hdcMem, old1);
144 handle = ::SetClipboardData(CF_BITMAP, hBitmap);
147 SelectObject(hdcSrc, old);
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
171 wxMetafile
*wxMF
= (wxMetafile
*)data
;
172 PicHandle pict
= wxMF
->GetHMETAFILE() ;
173 HLock( (Handle
) pict
) ;
175 err
= PutScrap( GetHandleSize( (Handle
) pict
) , 'PICT' , *pict
) ;
178 err
= GetCurrentScrap (&scrap
);
181 err
= PutScrapFlavor (scrap
, 'PICT', 0, GetHandleSize((Handle
) pict
), *pict
);
184 HUnlock( (Handle
) pict
) ;
194 wxLogError(_("Unsupported clipboard format."));
199 dataFormat
= wxDF_TEXT
;
205 if ( wxApp::s_macDefaultEncodingIsPC
)
207 mac
= wxMacMakeMacStringFromPC((char *)data
) ;
214 err
= PutScrap( mac
.Length() , 'TEXT' , mac
.c_str() ) ;
217 err
= GetCurrentScrap (&scrap
);
220 err
= PutScrapFlavor (scrap
, 'TEXT', 0, mac
.Length(), mac
.c_str());
229 wxLogSysError(_("Failed to set clipboard data."));
237 wxDataFormat
wxEnumClipboardFormats(wxDataFormat dataFormat
)
239 return wxDataFormat();
242 int wxRegisterClipboardFormat(wxChar
*formatName
)
247 bool wxGetClipboardFormatName(wxDataFormat dataFormat
, wxChar
*formatName
, int maxCount
)
252 void *wxGetClipboardData(wxDataFormat dataFormat
, long *len
)
257 OSStatus err
= noErr
;
261 switch (dataFormat
.GetType())
274 wxLogError(_("Unsupported clipboard format."));
279 dataFormat
= wxDF_TEXT
;
289 err
= GetCurrentScrap( &scrapRef
);
290 if ( err
!= noTypeErr
&& err
!= memFullErr
)
292 ScrapFlavorFlags flavorFlags
;
295 if (( err
= GetScrapFlavorFlags( scrapRef
, dataFormat
.GetFormatId(), &flavorFlags
)) == noErr
)
297 if (( err
= GetScrapFlavorSize( scrapRef
, dataFormat
.GetFormatId(), &byteCount
)) == noErr
)
299 if ( dataFormat
.GetType() == wxDF_TEXT
)
302 data
= new char[ byteCount
] ;
303 if (( err
= GetScrapFlavorData( scrapRef
, dataFormat
.GetFormatId(), &byteCount
, data
)) == noErr
)
306 if ( dataFormat
.GetType() == wxDF_TEXT
)
307 ((char*)data
)[byteCount
] = 0 ;
320 Handle datahandle
= NewHandle(0) ;
321 HLock( datahandle
) ;
322 GetScrap( datahandle
, dataFormat
.GetFormatId() , &offset
) ;
323 HUnlock( datahandle
) ;
324 if ( GetHandleSize( datahandle
) > 0 )
326 long byteCount
= GetHandleSize( datahandle
) ;
327 if ( dataFormat
.GetType() == wxDF_TEXT
)
328 data
= new char[ byteCount
+ 1] ;
330 data
= new char[ byteCount
] ;
332 memcpy( (char*) data
, (char*) *datahandle
, byteCount
) ;
333 if ( dataFormat
.GetType() == wxDF_TEXT
)
334 ((char*)data
)[byteCount
] = 0 ;
337 DisposeHandle( datahandle
) ;
341 wxLogSysError(_("Failed to get clipboard data."));
345 if ( dataFormat
.GetType() == wxDF_TEXT
&& wxApp::s_macDefaultEncodingIsPC
)
347 wxMacConvertToPC((char*)data
) ;
354 * Generalized clipboard implementation by Matthew Flatt
357 IMPLEMENT_DYNAMIC_CLASS(wxClipboard
, wxClipboardBase
)
359 wxClipboard::wxClipboard()
361 m_clearOnExit
= FALSE
;
364 wxClipboard::~wxClipboard()
372 void wxClipboard::Clear()
376 bool wxClipboard::Flush()
381 bool wxClipboard::Open()
383 return wxOpenClipboard();
386 bool wxClipboard::IsOpened() const
388 return wxIsClipboardOpened();
391 static int FormatStringToID(char *str
)
393 if (!strcmp(str
, "TEXT"))
396 return wxRegisterClipboardFormat(str
);
399 bool wxClipboard::SetData( wxDataObject
*data
)
401 (void)wxEmptyClipboard();
404 return AddData(data
);
409 bool wxClipboard::AddData( wxDataObject
*data
)
411 wxCHECK_MSG( data
, FALSE
, wxT("data is invalid") );
414 wxCHECK_MSG( wxIsClipboardOpened(), FALSE
, wxT("clipboard not open") );
416 wxDataFormat format
= data
->GetPreferredFormat();
418 switch ( format
.GetType() )
423 wxTextDataObject
* textDataObject
= (wxTextDataObject
*) data
;
424 wxString
str(textDataObject
->GetText());
425 return wxSetClipboardData(format
, str
.c_str());
431 wxBitmapDataObject
* bitmapDataObject
= (wxBitmapDataObject
*) data
;
432 wxBitmap
bitmap(bitmapDataObject
->GetBitmap());
433 return wxSetClipboardData(format
, &bitmap
);
436 #if 0 // wxUSE_METAFILE
439 wxMetafileDataObject
* metaFileDataObject
=
440 (wxMetafileDataObject
*) data
;
441 wxMetafile metaFile
= metaFileDataObject
->GetMetafile();
442 return wxSetClipboardData(wxDF_METAFILE
, &metaFile
,
443 metaFileDataObject
->GetWidth(),
444 metaFileDataObject
->GetHeight());
446 #endif // wxUSE_METAFILE
449 // return wxSetClipboardData(data);
452 #else // !wxUSE_DATAOBJ
457 void wxClipboard::Close()
462 bool wxClipboard::IsSupported( const wxDataFormat
&format
)
464 return wxIsClipboardFormatAvailable(format
);
467 bool wxClipboard::GetData( wxDataObject
& data
)
470 wxCHECK_MSG( wxIsClipboardOpened(), FALSE
, wxT("clipboard not open") );
472 wxDataFormat format
= data
.GetPreferredFormat();
473 switch ( format
.GetType() )
478 wxTextDataObject
& textDataObject
= (wxTextDataObject
&)data
;
479 char* s
= (char*)wxGetClipboardData(format
);
483 textDataObject
.SetText(s
);
492 wxBitmapDataObject
& bitmapDataObject
= (wxBitmapDataObject
&)data
;
493 wxBitmap
* bitmap
= (wxBitmap
*)wxGetClipboardData(format
);
497 bitmapDataObject
.SetBitmap(*bitmap
);
502 #if 0 // wxUSE_METAFILE
505 wxMetafileDataObject
& metaFileDataObject
= (wxMetafileDataObject
&)data
;
506 wxMetafile
* metaFile
= (wxMetafile
*)wxGetClipboardData(wxDF_METAFILE
);
510 metaFileDataObject
.SetMetafile(*metaFile
);
515 #endif // wxUSE_METAFILE
517 #else // !wxUSE_DATAOBJ
518 wxFAIL_MSG( wxT("no clipboard implementation") );
523 void wxClipboard::SetClipboardClient(wxClipboardClient *client, long time)
528 clipOwner->BeingReplaced();
535 if (wxOpenClipboard()) {
536 char **formats, *data;
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;
552 got_selection = wxCloseClipboard();
554 got_selection = FALSE;
556 got_selection = FALSE; // Assume another process takes over
558 if (!got_selection) {
559 clipOwner->BeingReplaced();
564 wxClipboardClient *wxClipboard::GetClipboardClient()
569 void wxClipboard::SetClipboardString(char *str, long time)
574 clipOwner->BeingReplaced();
582 if (wxOpenClipboard()) {
583 if (!wxSetClipboardData(wxDF_TEXT, (wxObject *)str))
584 got_selection = FALSE;
586 got_selection = wxCloseClipboard();
588 got_selection = FALSE;
590 got_selection = FALSE; // Assume another process takes over
592 if (!got_selection) {
597 char *wxClipboard::GetClipboardString(long time)
602 str = GetClipboardData("TEXT", &length, time);
612 char *wxClipboard::GetClipboardData(char *format, long *length, long time)
615 if (clipOwner->formats.Member(format))
616 return clipOwner->GetData(format, length);
619 } else if (cbString) {
620 if (!strcmp(format, "TEXT"))
621 return copystring(cbString);
625 if (wxOpenClipboard()) {
626 receivedString = (char *)wxGetClipboardData(FormatStringToID(format),
630 receivedString = NULL;
632 return receivedString;