]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/clipbrd.cpp
Border corrections
[wxWidgets.git] / src / mac / carbon / clipbrd.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/clipbrd.cpp
3 // Purpose: Clipboard functionality
4 // Author: Stefan Csomor;
5 // Generalized clipboard implementation by Matthew Flatt
6 // Modified by:
7 // Created: 1998-01-01
8 // RCS-ID: $Id$
9 // Copyright: (c) Stefan Csomor
10 // Licence: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12
13 #include "wx/wxprec.h"
14
15 #if wxUSE_CLIPBOARD
16
17 #include "wx/clipbrd.h"
18
19 #ifndef WX_PRECOMP
20 #include "wx/intl.h"
21 #include "wx/log.h"
22 #include "wx/app.h"
23 #include "wx/utils.h"
24 #include "wx/frame.h"
25 #include "wx/bitmap.h"
26 #endif
27
28 #include "wx/metafile.h"
29
30 #include "wx/mac/uma.h"
31
32 #define wxUSE_DATAOBJ 1
33
34 #include <string.h>
35
36
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");
41
42 IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
43
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
47
48 class wxMacBinaryCompatHelper : public wxDataObject
49 {
50 public :
51 wxMacBinaryCompatHelper()
52 {
53 m_trueData = NULL;
54 }
55
56 ~wxMacBinaryCompatHelper()
57 {
58 if (m_trueData != NULL)
59 {
60 delete m_trueData;
61 m_trueData = NULL;
62 }
63 }
64
65 virtual wxDataFormat GetPreferredFormat(Direction dir = Get) const
66 {
67 return wxDataFormat();
68 }
69
70 virtual size_t GetFormatCount(Direction dir = Get) const
71 {
72 return 0;
73 }
74
75 virtual void GetAllFormats(wxDataFormat *formats,
76 Direction dir = Get) const
77 {
78 }
79
80 virtual size_t GetDataSize(const wxDataFormat& format) const
81 {
82 return 0;
83 }
84
85 virtual bool GetDataHere(const wxDataFormat& format, void *buf) const
86 {
87 return false;
88 }
89
90 // only relevant from here on
91
92 wxDataObject* m_trueData;
93 wxCFRef<PasteboardRef> m_pasteboard;
94 };
95
96 #define M_CLIPBOARD ((wxMacBinaryCompatHelper*)m_data)
97
98 wxClipboard::wxClipboard()
99 {
100 m_open = false;
101 m_data = new wxMacBinaryCompatHelper() ;
102 PasteboardRef clipboard = 0;
103 OSStatus err = PasteboardCreate( kPasteboardClipboard, &clipboard );
104 if (err != noErr)
105 {
106 wxLogSysError( wxT("Failed to create the clipboard.") );
107 }
108 M_CLIPBOARD->m_pasteboard.reset(clipboard);
109 }
110
111 wxClipboard::~wxClipboard()
112 {
113 M_CLIPBOARD->m_pasteboard.reset((PasteboardRef)0);
114 delete m_data;
115 }
116
117 void wxClipboard::Clear()
118 {
119 if (M_CLIPBOARD->m_trueData != NULL)
120 {
121 delete M_CLIPBOARD->m_trueData;
122 M_CLIPBOARD->m_trueData = NULL;
123 }
124
125 OSStatus err = PasteboardClear( M_CLIPBOARD->m_pasteboard );
126 if (err != noErr)
127 {
128 wxLogSysError( wxT("Failed to empty the clipboard.") );
129 }
130 }
131
132 bool wxClipboard::Flush()
133 {
134 return false;
135 }
136
137 bool wxClipboard::Open()
138 {
139 wxCHECK_MSG( !m_open, false, wxT("clipboard already open") );
140
141 m_open = true;
142
143 return true;
144 }
145
146 bool wxClipboard::IsOpened() const
147 {
148 return m_open;
149 }
150
151 bool wxClipboard::SetData( wxDataObject *data )
152 {
153 if ( IsUsingPrimarySelection() )
154 return false;
155
156 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
157 wxCHECK_MSG( data, false, wxT("data is invalid") );
158
159 Clear();
160
161 // as we can only store one wxDataObject,
162 // this is the same in this implementation
163 return AddData( data );
164 }
165
166 bool wxClipboard::AddData( wxDataObject *data )
167 {
168 if ( IsUsingPrimarySelection() )
169 return false;
170
171 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
172 wxCHECK_MSG( data, false, wxT("data is invalid") );
173
174 // we can only store one wxDataObject
175 Clear();
176
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") );
180
181 M_CLIPBOARD->m_trueData = data;
182
183 data->AddToPasteboard( M_CLIPBOARD->m_pasteboard, 1 );
184
185 return true;
186 }
187
188 void wxClipboard::Close()
189 {
190 wxCHECK_RET( m_open, wxT("clipboard not open") );
191
192 m_open = false;
193
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)
198 {
199 delete M_CLIPBOARD->m_trueData;
200 M_CLIPBOARD->m_trueData = (wxDataObject*) NULL;
201 }
202 }
203
204 bool wxClipboard::IsSupported( const wxDataFormat &dataFormat )
205 {
206 if ( M_CLIPBOARD->m_trueData )
207 return M_CLIPBOARD->m_trueData->IsSupported( dataFormat );
208 return wxDataObject::IsFormatInPasteboard( M_CLIPBOARD->m_pasteboard, dataFormat );
209 }
210
211 bool wxClipboard::GetData( wxDataObject& data )
212 {
213 if ( IsUsingPrimarySelection() )
214 return false;
215
216 wxCHECK_MSG( m_open, false, wxT("clipboard not open") );
217
218 size_t formatcount = data.GetFormatCount() + 1;
219 wxDataFormat *array = new wxDataFormat[ formatcount ];
220 array[0] = data.GetPreferredFormat();
221 data.GetAllFormats( &array[1] );
222
223 bool transferred = false;
224
225 if ( M_CLIPBOARD->m_trueData )
226 {
227 for (size_t i = 0; !transferred && i < formatcount; i++)
228 {
229 wxDataFormat format = array[ i ];
230 if ( M_CLIPBOARD->m_trueData->IsSupported( format ) )
231 {
232 int dataSize = M_CLIPBOARD->m_trueData->GetDataSize( format );
233 transferred = true;
234
235 if (dataSize == 0)
236 {
237 data.SetData( format, 0, 0 );
238 }
239 else
240 {
241 char *d = new char[ dataSize ];
242 M_CLIPBOARD->m_trueData->GetDataHere( format, (void*)d );
243 data.SetData( format, dataSize, d );
244 delete [] d;
245 }
246 }
247 }
248 }
249
250 // get formats from wxDataObjects
251 if ( !transferred )
252 {
253 transferred = data.GetFromPasteboard( M_CLIPBOARD->m_pasteboard ) ;
254 }
255
256 delete [] array;
257
258 return transferred;
259 }
260
261 #endif