warning in wxCustomDataObject::Free fix (I hope)
[wxWidgets.git] / src / common / dobjcmn.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: common/dobjcmn.cpp
3 // Purpose: implementation of data object methods common to all platforms
4 // Author: Vadim Zeitlin, Robert Roebling
5 // Modified by:
6 // Created: 19.10.99
7 // RCS-ID: $Id$
8 // Copyright: (c) wxWindows Team
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "dataobjbase.h"
22 #endif
23
24 #include "wx/wxprec.h"
25
26 #ifdef __BORLANDC__
27 #pragma hdrstop
28 #endif
29
30 #ifndef WX_PRECOMP
31 #include "wx/app.h"
32 #include "wx/debug.h"
33 #endif // WX_PRECOMP
34
35 #include "wx/dataobj.h"
36
37 // ----------------------------------------------------------------------------
38 // lists
39 // ----------------------------------------------------------------------------
40
41 #include "wx/listimpl.cpp"
42
43 WX_DEFINE_LIST(wxSimpleDataObjectList);
44
45 // ----------------------------------------------------------------------------
46 // globals
47 // ----------------------------------------------------------------------------
48
49 static wxDataFormat dataFormatInvalid;
50 WXDLLEXPORT const wxDataFormat& wxFormatInvalid = dataFormatInvalid;
51
52 // ============================================================================
53 // implementation
54 // ============================================================================
55
56 // ----------------------------------------------------------------------------
57 // wxDataObjectBase
58 // ----------------------------------------------------------------------------
59
60 wxDataObjectBase::~wxDataObjectBase()
61 {
62 }
63
64 bool wxDataObjectBase::IsSupported(const wxDataFormat& format,
65 Direction dir) const
66 {
67 size_t nFormatCount = GetFormatCount(dir);
68 if ( nFormatCount == 1 )
69 {
70 return format == GetPreferredFormat(dir);
71 }
72 else
73 {
74 wxDataFormat *formats = new wxDataFormat[nFormatCount];
75 GetAllFormats(formats, dir);
76
77 size_t n;
78 for ( n = 0; n < nFormatCount; n++ )
79 {
80 if ( formats[n] == format )
81 break;
82 }
83
84 delete [] formats;
85
86 // found?
87 return n < nFormatCount;
88 }
89 }
90
91 // ----------------------------------------------------------------------------
92 // wxDataObjectComposite
93 // ----------------------------------------------------------------------------
94
95 wxDataObjectSimple *
96 wxDataObjectComposite::GetObject(const wxDataFormat& format) const
97 {
98 wxSimpleDataObjectList::Node *node = m_dataObjects.GetFirst();
99 while ( node )
100 {
101 wxDataObjectSimple *dataObj = node->GetData();
102
103 if ( dataObj->GetFormat() == format )
104 {
105 return dataObj;
106 }
107
108 node = node->GetNext();
109 }
110
111 return (wxDataObjectSimple *)NULL;
112 }
113
114 void wxDataObjectComposite::Add(wxDataObjectSimple *dataObject, bool preferred)
115 {
116 if ( preferred )
117 m_preferred = m_dataObjects.GetCount();
118
119 m_dataObjects.Append( dataObject );
120 }
121
122 wxDataFormat
123 wxDataObjectComposite::GetPreferredFormat(Direction WXUNUSED(dir)) const
124 {
125 wxSimpleDataObjectList::Node *node = m_dataObjects.Item( m_preferred );
126
127 wxCHECK_MSG( node, wxFormatInvalid, wxT("no preferred format") );
128
129 wxDataObjectSimple* dataObj = node->GetData();
130
131 return dataObj->GetFormat();
132 }
133
134 size_t wxDataObjectComposite::GetFormatCount(Direction WXUNUSED(dir)) const
135 {
136 // TODO what about the Get/Set only formats?
137 return m_dataObjects.GetCount();
138 }
139
140 void wxDataObjectComposite::GetAllFormats(wxDataFormat *formats,
141 Direction WXUNUSED(dir)) const
142 {
143 size_t n = 0;
144 wxSimpleDataObjectList::Node *node;
145 for ( node = m_dataObjects.GetFirst(); node; node = node->GetNext() )
146 {
147 // TODO if ( !outputOnlyToo ) && this one counts ...
148 formats[n++] = node->GetData()->GetFormat();
149 }
150 }
151
152 size_t wxDataObjectComposite::GetDataSize(const wxDataFormat& format) const
153 {
154 wxDataObjectSimple *dataObj = GetObject(format);
155
156 wxCHECK_MSG( dataObj, 0,
157 wxT("unsupported format in wxDataObjectComposite"));
158
159 return dataObj->GetDataSize();
160 }
161
162 bool wxDataObjectComposite::GetDataHere(const wxDataFormat& format,
163 void *buf) const
164 {
165 wxDataObjectSimple *dataObj = GetObject(format);
166
167 wxCHECK_MSG( dataObj, FALSE,
168 wxT("unsupported format in wxDataObjectComposite"));
169
170 return dataObj->GetDataHere(buf);
171 }
172
173 bool wxDataObjectComposite::SetData(const wxDataFormat& format,
174 size_t len,
175 const void *buf)
176 {
177 wxDataObjectSimple *dataObj = GetObject(format);
178
179 wxCHECK_MSG( dataObj, FALSE,
180 wxT("unsupported format in wxDataObjectComposite"));
181
182 return dataObj->SetData(len, buf);
183 }
184
185 // ----------------------------------------------------------------------------
186 // wxTextDataObject
187 // ----------------------------------------------------------------------------
188
189 size_t wxTextDataObject::GetDataSize() const
190 {
191 return GetTextLength();
192 }
193
194 bool wxTextDataObject::GetDataHere(void *buf) const
195 {
196 strcpy((char *)buf, GetText().mb_str());
197
198 return TRUE;
199 }
200
201 bool wxTextDataObject::SetData(size_t WXUNUSED(len), const void *buf)
202 {
203 SetText(wxString((const char *)buf));
204
205 return TRUE;
206 }
207
208 // ----------------------------------------------------------------------------
209 // wxFileDataObjectBase
210 // ----------------------------------------------------------------------------
211
212 // VZ: I don't need this in MSW finally, so if it is needed in wxGTK, it should
213 // be moved to gtk/dataobj.cpp
214 #if 0
215
216 wxString wxFileDataObjectBase::GetFilenames() const
217 {
218 wxString str;
219 size_t count = m_filenames.GetCount();
220 for ( size_t n = 0; n < count; n++ )
221 {
222 str << m_filenames[n] << wxT('\0');
223 }
224
225 return str;
226 }
227
228 void wxFileDataObjectBase::SetFilenames(const wxChar* filenames)
229 {
230 m_filenames.Empty();
231
232 wxString current;
233 for ( const wxChar *pc = filenames; ; pc++ )
234 {
235 if ( *pc )
236 {
237 current += *pc;
238 }
239 else
240 {
241 if ( !current )
242 {
243 // 2 consecutive NULs - this is the end of the string
244 break;
245 }
246
247 m_filenames.Add(current);
248 current.Empty();
249 }
250 }
251 }
252
253 #endif // 0
254
255 // ----------------------------------------------------------------------------
256 // wxCustomDataObject
257 // ----------------------------------------------------------------------------
258
259 wxCustomDataObject::wxCustomDataObject(const wxDataFormat& format)
260 : wxDataObjectSimple(format)
261 {
262 m_data = (void *)NULL;
263 }
264
265 wxCustomDataObject::~wxCustomDataObject()
266 {
267 Free();
268 }
269
270 void wxCustomDataObject::TakeData(size_t size, void *data)
271 {
272 Free();
273
274 m_size = size;
275 m_data = data;
276 }
277
278 void *wxCustomDataObject::Alloc(size_t size)
279 {
280 return (void *)new char[size];
281 }
282
283 void wxCustomDataObject::Free()
284 {
285 delete [] (char *)m_data;
286 m_size = 0;
287 m_data = (void *)NULL;
288 }
289
290 size_t wxCustomDataObject::GetDataSize() const
291 {
292 return GetSize();
293 }
294
295 bool wxCustomDataObject::GetDataHere(void *buf) const
296 {
297 void *data = GetData();
298 if ( !data )
299 return FALSE;
300
301 memcpy(buf, data, GetSize());
302
303 return TRUE;
304 }
305
306 bool wxCustomDataObject::SetData(size_t size, const void *buf)
307 {
308 Free();
309
310 m_data = Alloc(size);
311 if ( !m_data )
312 return FALSE;
313
314 memcpy(m_data, buf, m_size = size);
315
316 return TRUE;
317 }
318
319 // ============================================================================
320 // some common dnd related code
321 // ============================================================================
322
323 #if wxUSE_DRAG_AND_DROP
324
325 #include "wx/dnd.h"
326
327 // ----------------------------------------------------------------------------
328 // wxTextDropTarget
329 // ----------------------------------------------------------------------------
330
331 // NB: we can't use "new" in ctor initializer lists because this provokes an
332 // internal compiler error with VC++ 5.0 (hey, even gcc compiles this!),
333 // so use SetDataObject() instead
334
335 wxTextDropTarget::wxTextDropTarget()
336 {
337 SetDataObject(new wxTextDataObject);
338 }
339
340 wxDragResult wxTextDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult def)
341 {
342 if ( !GetData() )
343 return wxDragNone;
344
345 wxTextDataObject *dobj = (wxTextDataObject *)m_dataObject;
346 return OnDropText(x, y, dobj->GetText()) ? def : wxDragNone;
347 }
348
349 // ----------------------------------------------------------------------------
350 // wxFileDropTarget
351 // ----------------------------------------------------------------------------
352
353 wxFileDropTarget::wxFileDropTarget()
354 {
355 SetDataObject(new wxFileDataObject);
356 }
357
358 wxDragResult wxFileDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult def)
359 {
360 if ( !GetData() )
361 return wxDragNone;
362
363 wxFileDataObject *dobj = (wxFileDataObject *)m_dataObject;
364 return OnDropFiles(x, y, dobj->GetFilenames()) ? def : wxDragNone;
365 }
366
367 #endif
368