1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/clipbrd.cpp
3 // Purpose: Clipboard functionality
4 // Author: Stefan Csomor;
5 // Generalized clipboard implementation by Matthew Flatt
9 // Copyright: (c) Stefan Csomor
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
13 #include "wx/wxprec.h"
17 #include "wx/clipbrd.h"
25 #include "wx/bitmap.h"
28 #include "wx/metafile.h"
30 #include "wx/mac/uma.h"
32 #define wxUSE_DATAOBJ 1
37 // the trace mask we use with wxLogTrace() - call
38 // wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here
39 // (there will be a *lot* of them!)
40 static const wxChar
*TRACE_CLIPBOARD
= wxT("clipboard");
42 IMPLEMENT_DYNAMIC_CLASS(wxClipboard
, wxObject
)
44 // in order to keep the binary interface the same this class
45 // serves just to have a few additional member variables inside
46 // the clipboard class
48 class wxMacBinaryCompatHelper
: public wxDataObject
51 wxMacBinaryCompatHelper()
56 ~wxMacBinaryCompatHelper()
58 if (m_trueData
!= NULL
)
65 virtual wxDataFormat
GetPreferredFormat(Direction dir
= Get
) const
67 return wxDataFormat();
70 virtual size_t GetFormatCount(Direction dir
= Get
) const
75 virtual void GetAllFormats(wxDataFormat
*formats
,
76 Direction dir
= Get
) const
80 virtual size_t GetDataSize(const wxDataFormat
& format
) const
85 virtual bool GetDataHere(const wxDataFormat
& format
, void *buf
) const
90 // only relevant from here on
92 wxDataObject
* m_trueData
;
93 wxCFRef
<PasteboardRef
> m_pasteboard
;
96 #define M_CLIPBOARD ((wxMacBinaryCompatHelper*)m_data)
98 wxClipboard::wxClipboard()
101 m_data
= new wxMacBinaryCompatHelper() ;
102 PasteboardRef clipboard
= 0;
103 OSStatus err
= PasteboardCreate( kPasteboardClipboard
, &clipboard
);
106 wxLogSysError( wxT("Failed to create the clipboard.") );
108 M_CLIPBOARD
->m_pasteboard
.reset(clipboard
);
111 wxClipboard::~wxClipboard()
113 M_CLIPBOARD
->m_pasteboard
.reset((PasteboardRef
)0);
117 void wxClipboard::Clear()
119 if (M_CLIPBOARD
->m_trueData
!= NULL
)
121 delete M_CLIPBOARD
->m_trueData
;
122 M_CLIPBOARD
->m_trueData
= NULL
;
125 OSStatus err
= PasteboardClear( M_CLIPBOARD
->m_pasteboard
);
128 wxLogSysError( wxT("Failed to empty the clipboard.") );
132 bool wxClipboard::Flush()
137 bool wxClipboard::Open()
139 wxCHECK_MSG( !m_open
, false, wxT("clipboard already open") );
146 bool wxClipboard::IsOpened() const
151 bool wxClipboard::SetData( wxDataObject
*data
)
153 if ( IsUsingPrimarySelection() )
156 wxCHECK_MSG( m_open
, false, wxT("clipboard not open") );
157 wxCHECK_MSG( data
, false, wxT("data is invalid") );
161 // as we can only store one wxDataObject,
162 // this is the same in this implementation
163 return AddData( data
);
166 bool wxClipboard::AddData( wxDataObject
*data
)
168 if ( IsUsingPrimarySelection() )
171 wxCHECK_MSG( m_open
, false, wxT("clipboard not open") );
172 wxCHECK_MSG( data
, false, wxT("data is invalid") );
174 // we can only store one wxDataObject
177 PasteboardSyncFlags syncFlags
= PasteboardSynchronize( M_CLIPBOARD
->m_pasteboard
);
178 wxCHECK_MSG( !(syncFlags
&kPasteboardModified
), false, wxT("clipboard modified after clear") );
179 wxCHECK_MSG( (syncFlags
&kPasteboardClientIsOwner
), false, wxT("client couldn't own clipboard") );
181 M_CLIPBOARD
->m_trueData
= data
;
183 data
->AddToPasteboard( M_CLIPBOARD
->m_pasteboard
, 1 );
188 void wxClipboard::Close()
190 wxCHECK_RET( m_open
, wxT("clipboard not open") );
194 // Get rid of cached object.
195 // If this is not done, copying data from
196 // another application will only work once
197 if (M_CLIPBOARD
->m_trueData
)
199 delete M_CLIPBOARD
->m_trueData
;
200 M_CLIPBOARD
->m_trueData
= (wxDataObject
*) NULL
;
204 bool wxClipboard::IsSupported( const wxDataFormat
&dataFormat
)
206 if ( M_CLIPBOARD
->m_trueData
)
207 return M_CLIPBOARD
->m_trueData
->IsSupported( dataFormat
);
208 return wxDataObject::IsFormatInPasteboard( M_CLIPBOARD
->m_pasteboard
, dataFormat
);
211 bool wxClipboard::GetData( wxDataObject
& data
)
213 if ( IsUsingPrimarySelection() )
216 wxCHECK_MSG( m_open
, false, wxT("clipboard not open") );
218 size_t formatcount
= data
.GetFormatCount() + 1;
219 wxDataFormat
*array
= new wxDataFormat
[ formatcount
];
220 array
[0] = data
.GetPreferredFormat();
221 data
.GetAllFormats( &array
[1] );
223 bool transferred
= false;
225 if ( M_CLIPBOARD
->m_trueData
)
227 for (size_t i
= 0; !transferred
&& i
< formatcount
; i
++)
229 wxDataFormat format
= array
[ i
];
230 if ( M_CLIPBOARD
->m_trueData
->IsSupported( format
) )
232 int dataSize
= M_CLIPBOARD
->m_trueData
->GetDataSize( format
);
237 data
.SetData( format
, 0, 0 );
241 char *d
= new char[ dataSize
];
242 M_CLIPBOARD
->m_trueData
->GetDataHere( format
, (void*)d
);
243 data
.SetData( format
, dataSize
, d
);
250 // get formats from wxDataObjects
253 transferred
= data
.GetFromPasteboard( M_CLIPBOARD
->m_pasteboard
) ;