]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/dataobj.cpp
don't compare invalid iterators/node pointers
[wxWidgets.git] / src / mac / carbon / dataobj.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/dataobj.cpp
3 // Purpose: implementation of wxDataObject class
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 10/21/99
7 // RCS-ID: $Id$
8 // Copyright: (c) 1999 Stefan Csomor
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #if wxUSE_DATAOBJ
16
17 #ifndef WX_PRECOMP
18 #include "wx/intl.h"
19 #endif
20
21 #include "wx/log.h"
22 #include "wx/dataobj.h"
23 #include "wx/dcmemory.h"
24 #include "wx/mstream.h"
25 #include "wx/image.h"
26 #include "wx/metafile.h"
27 #include "wx/mac/private.h"
28
29 #ifndef __DARWIN__
30 #include <Scrap.h>
31 #endif
32
33
34 // ----------------------------------------------------------------------------
35 // wxDataFormat
36 // ----------------------------------------------------------------------------
37
38 wxDataFormat::wxDataFormat()
39 {
40 m_type = wxDF_INVALID;
41 m_format = 0;
42 }
43
44 wxDataFormat::wxDataFormat( wxDataFormatId vType )
45 {
46 SetType( vType );
47 }
48
49 wxDataFormat::wxDataFormat( const wxChar *zId )
50 {
51 SetId( zId );
52 }
53
54 wxDataFormat::wxDataFormat( const wxString& rId )
55 {
56 SetId( rId );
57 }
58
59 wxDataFormat::wxDataFormat( NativeFormat vFormat )
60 {
61 SetId( vFormat );
62 }
63
64 void wxDataFormat::SetType( wxDataFormatId dataType )
65 {
66 m_type = dataType;
67
68 switch (m_type)
69 {
70 case wxDF_TEXT:
71 m_format = kScrapFlavorTypeText;
72 break;
73
74 case wxDF_UNICODETEXT:
75 m_format = kScrapFlavorTypeUnicode;
76 break;
77
78 case wxDF_BITMAP:
79 case wxDF_METAFILE:
80 m_format = kScrapFlavorTypePicture;
81 break;
82
83 case wxDF_FILENAME:
84 m_format = kDragFlavorTypeHFS;
85 break;
86
87 default:
88 wxFAIL_MSG( wxT("invalid data format") );
89
90 // NB: this translates to '????' ASCII but it can't be used in the code
91 // because '??' will get parsed as a trigraph!
92 m_format = 0x3f3f3f3f;
93 break;
94 }
95 }
96
97 wxString wxDataFormat::GetId() const
98 {
99 wxCHECK_MSG( !IsStandard(), wxEmptyString,
100 wxT("name of predefined format cannot be retrieved") );
101
102 return m_id;
103 }
104
105 void wxDataFormat::SetId( NativeFormat format )
106 {
107 m_format = format;
108
109 switch (m_format)
110 {
111 case kScrapFlavorTypeText:
112 m_type = wxDF_TEXT;
113 break;
114
115 case kScrapFlavorTypeUnicode:
116 m_type = wxDF_UNICODETEXT;
117 break;
118
119 case kScrapFlavorTypePicture:
120 m_type = wxDF_BITMAP;
121 break;
122
123 case kDragFlavorTypeHFS:
124 m_type = wxDF_FILENAME;
125 break;
126
127 default:
128 m_type = wxDF_PRIVATE;
129 char text[5];
130 strncpy( text, (char*)&format, 4 );
131 text[4] = 0;
132 m_id = wxString::FromAscii( text );
133 break;
134 }
135 }
136
137 void wxDataFormat::SetId( const wxChar* zId )
138 {
139 m_type = wxDF_PRIVATE;
140 m_id = zId;
141 m_format = 'WXPR';
142 }
143
144 bool wxDataFormat::operator==(const wxDataFormat& format) const
145 {
146 if (IsStandard() || format.IsStandard())
147 return (format.m_type == m_type);
148 else
149 return (m_id == format.m_id);
150 }
151
152 //-------------------------------------------------------------------------
153 // wxDataObject
154 //-------------------------------------------------------------------------
155
156 wxDataObject::wxDataObject()
157 {
158 }
159
160 bool wxDataObject::IsSupportedFormat( const wxDataFormat& rFormat, Direction vDir ) const
161 {
162 size_t nFormatCount = GetFormatCount( vDir );
163 bool found = false;
164
165 if (nFormatCount == 1)
166 {
167 found = (rFormat == GetPreferredFormat());
168 }
169 else
170 {
171 wxDataFormat* pFormats = new wxDataFormat[nFormatCount];
172 GetAllFormats( pFormats, vDir );
173
174 for (size_t n = 0; n < nFormatCount; n++)
175 {
176 if (pFormats[n] == rFormat)
177 {
178 found = true;
179 break;
180 }
181 }
182
183 delete [] pFormats;
184 }
185
186 return found;
187 }
188
189 // ----------------------------------------------------------------------------
190 // wxTextDataObject
191 // ----------------------------------------------------------------------------
192
193 #if wxUSE_UNICODE
194 void wxTextDataObject::GetAllFormats( wxDataFormat *formats, wxDataObjectBase::Direction dir ) const
195 {
196 *formats++ = wxDataFormat( wxDF_TEXT );
197 *formats = wxDataFormat( wxDF_UNICODETEXT );
198 }
199 #endif
200
201 // ----------------------------------------------------------------------------
202 // wxFileDataObject
203 // ----------------------------------------------------------------------------
204
205 bool wxFileDataObject::GetDataHere( void *pBuf ) const
206 {
207 if (pBuf == NULL)
208 return false;
209
210 wxString sFilenames;
211
212 for (size_t i = 0; i < m_filenames.GetCount(); i++)
213 {
214 sFilenames += m_filenames[i];
215 sFilenames += (wxChar)0;
216 }
217
218 memcpy( pBuf, sFilenames.mbc_str(), sFilenames.Len() + 1 );
219
220 return true;
221 }
222
223 size_t wxFileDataObject::GetDataSize() const
224 {
225 size_t nRes = 0;
226
227 for (size_t i = 0; i < m_filenames.GetCount(); i++)
228 {
229 nRes += m_filenames[i].Len();
230 nRes += 1;
231 }
232
233 return nRes + 1;
234 }
235
236 bool wxFileDataObject::SetData( size_t WXUNUSED(nSize), const void *pBuf )
237 {
238 m_filenames.Empty();
239
240 // only add if this is not an empty string
241 // we can therefore clear the list by just setting an empty string
242 if ((*(const char*)pBuf) != 0)
243 AddFile( wxString::FromAscii( (char*)pBuf) );
244
245 return true;
246 }
247
248 void wxFileDataObject::AddFile( const wxString& rFilename )
249 {
250 m_filenames.Add( rFilename );
251 }
252
253 // ----------------------------------------------------------------------------
254 // wxBitmapDataObject
255 // ----------------------------------------------------------------------------
256
257 wxBitmapDataObject::wxBitmapDataObject()
258 {
259 Init();
260 }
261
262 wxBitmapDataObject::wxBitmapDataObject( const wxBitmap& rBitmap )
263 : wxBitmapDataObjectBase( rBitmap )
264 {
265 Init();
266
267 if (m_bitmap.Ok())
268 {
269 m_pictHandle = m_bitmap.GetBitmapData()->GetPictHandle();
270 m_pictCreated = false;
271 }
272 }
273
274 wxBitmapDataObject::~wxBitmapDataObject()
275 {
276 Clear();
277 }
278
279 void wxBitmapDataObject::SetBitmap( const wxBitmap& rBitmap )
280 {
281 Clear();
282 wxBitmapDataObjectBase::SetBitmap( rBitmap );
283 if (m_bitmap.Ok())
284 {
285 m_pictHandle = m_bitmap.GetBitmapData()->GetPictHandle();
286 m_pictCreated = false;
287 }
288 }
289
290 void wxBitmapDataObject::Init()
291 {
292 m_pictHandle = NULL;
293 m_pictCreated = false;
294 }
295
296 void wxBitmapDataObject::Clear()
297 {
298 if (m_pictHandle != NULL)
299 {
300 if (m_pictCreated)
301 KillPicture( (PicHandle)m_pictHandle );
302 m_pictHandle = NULL;
303 }
304
305 m_pictCreated = false;
306 }
307
308 bool wxBitmapDataObject::GetDataHere( void *pBuf ) const
309 {
310 if (m_pictHandle == NULL)
311 {
312 wxFAIL_MSG( wxT("attempt to copy empty bitmap failed") );
313 return false;
314 }
315
316 if (pBuf == NULL)
317 return false;
318
319 memcpy( pBuf, *(Handle)m_pictHandle, GetHandleSize( (Handle)m_pictHandle ) );
320
321 return true;
322 }
323
324 size_t wxBitmapDataObject::GetDataSize() const
325 {
326 if (m_pictHandle != NULL)
327 return GetHandleSize( (Handle)m_pictHandle );
328 else
329 return 0;
330 }
331
332 bool wxBitmapDataObject::SetData( size_t nSize, const void *pBuf )
333 {
334 Clear();
335
336 if ((pBuf == NULL) || (nSize == 0))
337 return false;
338
339 PicHandle picHandle = (PicHandle)NewHandle( nSize );
340 memcpy( *picHandle, pBuf, nSize );
341 m_pictHandle = picHandle;
342
343 // ownership is transferred to the bitmap
344 m_pictCreated = false;
345 Rect frame;
346 wxMacGetPictureBounds( picHandle, &frame );
347
348 wxMetafile mf;
349 mf.SetHMETAFILE( (WXHMETAFILE)m_pictHandle );
350 wxMemoryDC mdc;
351 m_bitmap.Create( frame.right - frame.left, frame.bottom - frame.top );
352 mdc.SelectObject( m_bitmap );
353 mf.Play( &mdc );
354 mdc.SelectObject( wxNullBitmap );
355
356 return m_bitmap.Ok();
357 }
358
359 #endif