]> git.saurik.com Git - wxWidgets.git/blob - src/common/dobjcmn.cpp
more contrib tweaks
[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 licence
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 #if wxUSE_DATAOBJ
31
32 #ifndef WX_PRECOMP
33 #include "wx/app.h"
34 #include "wx/debug.h"
35 #endif // WX_PRECOMP
36
37 #include "wx/dataobj.h"
38
39 // ----------------------------------------------------------------------------
40 // lists
41 // ----------------------------------------------------------------------------
42
43 #include "wx/listimpl.cpp"
44
45 WX_DEFINE_LIST(wxSimpleDataObjectList);
46
47 // ----------------------------------------------------------------------------
48 // globals
49 // ----------------------------------------------------------------------------
50
51 static wxDataFormat dataFormatInvalid;
52 WXDLLEXPORT const wxDataFormat& wxFormatInvalid = dataFormatInvalid;
53
54 // ============================================================================
55 // implementation
56 // ============================================================================
57
58 // ----------------------------------------------------------------------------
59 // wxDataObjectBase
60 // ----------------------------------------------------------------------------
61
62 wxDataObjectBase::~wxDataObjectBase()
63 {
64 }
65
66 bool wxDataObjectBase::IsSupported(const wxDataFormat& format,
67 Direction dir) const
68 {
69 size_t nFormatCount = GetFormatCount(dir);
70 if ( nFormatCount == 1 )
71 {
72 return format == GetPreferredFormat(dir);
73 }
74 else
75 {
76 wxDataFormat *formats = new wxDataFormat[nFormatCount];
77 GetAllFormats(formats, dir);
78
79 size_t n;
80 for ( n = 0; n < nFormatCount; n++ )
81 {
82 if ( formats[n] == format )
83 break;
84 }
85
86 delete [] formats;
87
88 // found?
89 return n < nFormatCount;
90 }
91 }
92
93 // ----------------------------------------------------------------------------
94 // wxDataObjectComposite
95 // ----------------------------------------------------------------------------
96
97 wxDataObjectComposite::wxDataObjectComposite()
98 {
99 m_preferred = 0;
100
101 m_dataObjects.DeleteContents(TRUE);
102 }
103
104 wxDataObjectSimple *
105 wxDataObjectComposite::GetObject(const wxDataFormat& format) const
106 {
107 wxSimpleDataObjectList::Node *node = m_dataObjects.GetFirst();
108 while ( node )
109 {
110 wxDataObjectSimple *dataObj = node->GetData();
111
112 if ( dataObj->GetFormat() == format )
113 {
114 return dataObj;
115 }
116
117 node = node->GetNext();
118 }
119
120 return (wxDataObjectSimple *)NULL;
121 }
122
123 void wxDataObjectComposite::Add(wxDataObjectSimple *dataObject, bool preferred)
124 {
125 if ( preferred )
126 m_preferred = m_dataObjects.GetCount();
127
128 m_dataObjects.Append( dataObject );
129 }
130
131 wxDataFormat
132 wxDataObjectComposite::GetPreferredFormat(Direction WXUNUSED(dir)) const
133 {
134 wxSimpleDataObjectList::Node *node = m_dataObjects.Item( m_preferred );
135
136 wxCHECK_MSG( node, wxFormatInvalid, wxT("no preferred format") );
137
138 wxDataObjectSimple* dataObj = node->GetData();
139
140 return dataObj->GetFormat();
141 }
142
143 #if defined(__WXMSW__)
144
145 size_t wxDataObjectComposite::GetBufferOffset( const wxDataFormat& format )
146 {
147 wxDataObjectSimple *dataObj = GetObject(format);
148
149 wxCHECK_MSG( dataObj, 0,
150 wxT("unsupported format in wxDataObjectComposite"));
151
152 return dataObj->GetBufferOffset( format );
153 }
154
155
156 const void* wxDataObjectComposite::GetSizeFromBuffer( const void* buffer,
157 size_t* size,
158 const wxDataFormat& format )
159 {
160 wxDataObjectSimple *dataObj = GetObject(format);
161
162 wxCHECK_MSG( dataObj, NULL,
163 wxT("unsupported format in wxDataObjectComposite"));
164
165 return dataObj->GetSizeFromBuffer( buffer, size, format );
166 }
167
168
169 void* wxDataObjectComposite::SetSizeInBuffer( void* buffer, size_t size,
170 const wxDataFormat& format )
171 {
172 wxDataObjectSimple *dataObj = GetObject(format);
173
174 wxCHECK_MSG( dataObj, NULL,
175 wxT("unsupported format in wxDataObjectComposite"));
176
177 return dataObj->SetSizeInBuffer( buffer, size, format );
178 }
179
180 #endif
181
182 size_t wxDataObjectComposite::GetFormatCount(Direction WXUNUSED(dir)) const
183 {
184 // TODO what about the Get/Set only formats?
185 return m_dataObjects.GetCount();
186 }
187
188 void wxDataObjectComposite::GetAllFormats(wxDataFormat *formats,
189 Direction WXUNUSED(dir)) const
190 {
191 size_t n = 0;
192 wxSimpleDataObjectList::Node *node;
193 for ( node = m_dataObjects.GetFirst(); node; node = node->GetNext() )
194 {
195 // TODO if ( !outputOnlyToo ) && this one counts ...
196 formats[n++] = node->GetData()->GetFormat();
197 }
198 }
199
200 size_t wxDataObjectComposite::GetDataSize(const wxDataFormat& format) const
201 {
202 wxDataObjectSimple *dataObj = GetObject(format);
203
204 wxCHECK_MSG( dataObj, 0,
205 wxT("unsupported format in wxDataObjectComposite"));
206
207 return dataObj->GetDataSize();
208 }
209
210 bool wxDataObjectComposite::GetDataHere(const wxDataFormat& format,
211 void *buf) const
212 {
213 wxDataObjectSimple *dataObj = GetObject(format);
214
215 wxCHECK_MSG( dataObj, FALSE,
216 wxT("unsupported format in wxDataObjectComposite"));
217
218 return dataObj->GetDataHere(buf);
219 }
220
221 bool wxDataObjectComposite::SetData(const wxDataFormat& format,
222 size_t len,
223 const void *buf)
224 {
225 wxDataObjectSimple *dataObj = GetObject(format);
226
227 wxCHECK_MSG( dataObj, FALSE,
228 wxT("unsupported format in wxDataObjectComposite"));
229
230 return dataObj->SetData(len, buf);
231 }
232
233 // ----------------------------------------------------------------------------
234 // wxTextDataObject
235 // ----------------------------------------------------------------------------
236
237 size_t wxTextDataObject::GetDataSize() const
238 {
239 #if defined(__WXGTK20__) && wxUSE_UNICODE
240 // Use UTF8 not UCS4
241 wxCharBuffer buffer = wxConvUTF8.cWX2MB( GetText().c_str() );
242 return strlen( (const char*) buffer ) + 1;
243 #else
244 return GetTextLength() * sizeof(wxChar);
245 #endif
246 }
247
248 bool wxTextDataObject::GetDataHere(void *buf) const
249 {
250 #if defined(__WXGTK20__) && wxUSE_UNICODE
251 // Use UTF8 not UCS4
252 wxCharBuffer buffer = wxConvUTF8.cWX2MB( GetText().c_str() );
253 strcpy( (char*) buf, (const char*) buffer );
254 #else
255 wxStrcpy((wxChar *)buf, GetText().c_str());
256 #endif
257
258 return TRUE;
259 }
260
261 bool wxTextDataObject::SetData(size_t WXUNUSED(len), const void *buf)
262 {
263 #if defined(__WXGTK20__) && wxUSE_UNICODE
264 // Use UTF8 not UCS4
265 SetText( wxConvUTF8.cMB2WX( (const char*) buf ) );
266 #else
267 SetText(wxString((const wxChar *)buf));
268 #endif
269
270 return TRUE;
271 }
272
273 // ----------------------------------------------------------------------------
274 // wxFileDataObjectBase
275 // ----------------------------------------------------------------------------
276
277 // VZ: I don't need this in MSW finally, so if it is needed in wxGTK, it should
278 // be moved to gtk/dataobj.cpp
279 #if 0
280
281 wxString wxFileDataObjectBase::GetFilenames() const
282 {
283 wxString str;
284 size_t count = m_filenames.GetCount();
285 for ( size_t n = 0; n < count; n++ )
286 {
287 str << m_filenames[n] << wxT('\0');
288 }
289
290 return str;
291 }
292
293 void wxFileDataObjectBase::SetFilenames(const wxChar* filenames)
294 {
295 m_filenames.Empty();
296
297 wxString current;
298 for ( const wxChar *pc = filenames; ; pc++ )
299 {
300 if ( *pc )
301 {
302 current += *pc;
303 }
304 else
305 {
306 if ( !current )
307 {
308 // 2 consecutive NULs - this is the end of the string
309 break;
310 }
311
312 m_filenames.Add(current);
313 current.Empty();
314 }
315 }
316 }
317
318 #endif // 0
319
320 // ----------------------------------------------------------------------------
321 // wxCustomDataObject
322 // ----------------------------------------------------------------------------
323
324 wxCustomDataObject::wxCustomDataObject(const wxDataFormat& format)
325 : wxDataObjectSimple(format)
326 {
327 m_data = (void *)NULL;
328 }
329
330 wxCustomDataObject::~wxCustomDataObject()
331 {
332 Free();
333 }
334
335 void wxCustomDataObject::TakeData(size_t size, void *data)
336 {
337 Free();
338
339 m_size = size;
340 m_data = data;
341 }
342
343 void *wxCustomDataObject::Alloc(size_t size)
344 {
345 return (void *)new char[size];
346 }
347
348 void wxCustomDataObject::Free()
349 {
350 delete [] (char *)m_data;
351 m_size = 0;
352 m_data = (void *)NULL;
353 }
354
355 size_t wxCustomDataObject::GetDataSize() const
356 {
357 return GetSize();
358 }
359
360 bool wxCustomDataObject::GetDataHere(void *buf) const
361 {
362 void *data = GetData();
363 if ( !data )
364 return FALSE;
365
366 memcpy(buf, data, GetSize());
367
368 return TRUE;
369 }
370
371 bool wxCustomDataObject::SetData(size_t size, const void *buf)
372 {
373 Free();
374
375 m_data = Alloc(size);
376 if ( !m_data )
377 return FALSE;
378
379 memcpy(m_data, buf, m_size = size);
380
381 return TRUE;
382 }
383
384 // ============================================================================
385 // some common dnd related code
386 // ============================================================================
387
388 #if wxUSE_DRAG_AND_DROP
389
390 #include "wx/dnd.h"
391
392 // ----------------------------------------------------------------------------
393 // wxTextDropTarget
394 // ----------------------------------------------------------------------------
395
396 // NB: we can't use "new" in ctor initializer lists because this provokes an
397 // internal compiler error with VC++ 5.0 (hey, even gcc compiles this!),
398 // so use SetDataObject() instead
399
400 wxTextDropTarget::wxTextDropTarget()
401 {
402 SetDataObject(new wxTextDataObject);
403 }
404
405 wxDragResult wxTextDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult def)
406 {
407 if ( !GetData() )
408 return wxDragNone;
409
410 wxTextDataObject *dobj = (wxTextDataObject *)m_dataObject;
411 return OnDropText(x, y, dobj->GetText()) ? def : wxDragNone;
412 }
413
414 // ----------------------------------------------------------------------------
415 // wxFileDropTarget
416 // ----------------------------------------------------------------------------
417
418 wxFileDropTarget::wxFileDropTarget()
419 {
420 SetDataObject(new wxFileDataObject);
421 }
422
423 wxDragResult wxFileDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult def)
424 {
425 if ( !GetData() )
426 return wxDragNone;
427
428 wxFileDataObject *dobj = (wxFileDataObject *)m_dataObject;
429 return OnDropFiles(x, y, dobj->GetFilenames()) ? def : wxDragNone;
430 }
431
432 #endif // wxUSE_DRAG_AND_DROP
433
434 #endif // wxUSE_DATAOBJ