]> git.saurik.com Git - wxWidgets.git/blame - src/common/dobjcmn.cpp
wxSortedArray::Add must return the index of the newly
[wxWidgets.git] / src / common / dobjcmn.cpp
CommitLineData
3f364be8
VZ
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
55d99c7a 9// Licence: wxWindows licence
3f364be8
VZ
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
1e6feb95
VZ
30#if wxUSE_DATAOBJ
31
3f364be8
VZ
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
45WX_DEFINE_LIST(wxSimpleDataObjectList);
46
0c2b453f
VZ
47// ----------------------------------------------------------------------------
48// globals
49// ----------------------------------------------------------------------------
50
51static wxDataFormat dataFormatInvalid;
31e78e0c 52WXDLLEXPORT const wxDataFormat& wxFormatInvalid = dataFormatInvalid;
0c2b453f 53
3f364be8
VZ
54// ============================================================================
55// implementation
56// ============================================================================
57
58// ----------------------------------------------------------------------------
59// wxDataObjectBase
60// ----------------------------------------------------------------------------
61
62wxDataObjectBase::~wxDataObjectBase()
63{
64}
65
d9317fd4
VZ
66bool 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
3f364be8
VZ
93// ----------------------------------------------------------------------------
94// wxDataObjectComposite
95// ----------------------------------------------------------------------------
96
e6b01b78
VZ
97wxDataObjectComposite::wxDataObjectComposite()
98{
99 m_preferred = 0;
100
101 m_dataObjects.DeleteContents(TRUE);
102}
103
3f364be8
VZ
104wxDataObjectSimple *
105wxDataObjectComposite::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
123void wxDataObjectComposite::Add(wxDataObjectSimple *dataObject, bool preferred)
124{
125 if ( preferred )
126 m_preferred = m_dataObjects.GetCount();
127
128 m_dataObjects.Append( dataObject );
129}
130
131wxDataFormat
132wxDataObjectComposite::GetPreferredFormat(Direction WXUNUSED(dir)) const
133{
134 wxSimpleDataObjectList::Node *node = m_dataObjects.Item( m_preferred );
135
2ee3ee1b 136 wxCHECK_MSG( node, wxFormatInvalid, wxT("no preferred format") );
3f364be8
VZ
137
138 wxDataObjectSimple* dataObj = node->GetData();
139
140 return dataObj->GetFormat();
141}
142
e1b435af 143#if defined(__WXMSW__)
7d584866 144
e1b435af
MB
145size_t wxDataObjectComposite::GetBufferOffset( const wxDataFormat& format )
146{
147 wxDataObjectSimple *dataObj = GetObject(format);
148
f7f50f49 149 wxCHECK_MSG( dataObj, 0,
e1b435af
MB
150 wxT("unsupported format in wxDataObjectComposite"));
151
152 return dataObj->GetBufferOffset( format );
153}
154
7d584866 155
e1b435af
MB
156const void* wxDataObjectComposite::GetSizeFromBuffer( const void* buffer,
157 size_t* size,
158 const wxDataFormat& format )
159{
160 wxDataObjectSimple *dataObj = GetObject(format);
161
f7f50f49 162 wxCHECK_MSG( dataObj, NULL,
e1b435af
MB
163 wxT("unsupported format in wxDataObjectComposite"));
164
165 return dataObj->GetSizeFromBuffer( buffer, size, format );
166}
167
7d584866 168
e1b435af
MB
169void* wxDataObjectComposite::SetSizeInBuffer( void* buffer, size_t size,
170 const wxDataFormat& format )
171{
172 wxDataObjectSimple *dataObj = GetObject(format);
173
f7f50f49 174 wxCHECK_MSG( dataObj, NULL,
e1b435af
MB
175 wxT("unsupported format in wxDataObjectComposite"));
176
177 return dataObj->SetSizeInBuffer( buffer, size, format );
178}
179
180#endif
181
3f364be8
VZ
182size_t wxDataObjectComposite::GetFormatCount(Direction WXUNUSED(dir)) const
183{
184 // TODO what about the Get/Set only formats?
185 return m_dataObjects.GetCount();
186}
187
188void 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
200size_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
210bool 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
221bool 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
237size_t wxTextDataObject::GetDataSize() const
238{
6a59178a
RR
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
e1b435af 244 return GetTextLength() * sizeof(wxChar);
6a59178a 245#endif
3f364be8
VZ
246}
247
248bool wxTextDataObject::GetDataHere(void *buf) const
249{
6a59178a
RR
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
e1b435af 255 wxStrcpy((wxChar *)buf, GetText().c_str());
6a59178a 256#endif
3f364be8
VZ
257
258 return TRUE;
259}
260
261bool wxTextDataObject::SetData(size_t WXUNUSED(len), const void *buf)
262{
6a59178a
RR
263#if defined(__WXGTK20__) && wxUSE_UNICODE
264 // Use UTF8 not UCS4
265 SetText( wxConvUTF8.cMB2WX( (const char*) buf ) );
266#else
e1b435af 267 SetText(wxString((const wxChar *)buf));
6a59178a 268#endif
3f364be8
VZ
269
270 return TRUE;
271}
272
273// ----------------------------------------------------------------------------
274// wxFileDataObjectBase
275// ----------------------------------------------------------------------------
276
9e2896e5
VZ
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
3f364be8
VZ
281wxString 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
293void 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
9e2896e5
VZ
318#endif // 0
319
3f364be8
VZ
320// ----------------------------------------------------------------------------
321// wxCustomDataObject
322// ----------------------------------------------------------------------------
323
775e1c62
RD
324wxCustomDataObject::wxCustomDataObject(const wxDataFormat& format)
325 : wxDataObjectSimple(format)
326{
4e16881a 327 m_data = (void *)NULL;
775e1c62
RD
328}
329
3f364be8
VZ
330wxCustomDataObject::~wxCustomDataObject()
331{
332 Free();
333}
334
335void wxCustomDataObject::TakeData(size_t size, void *data)
336{
337 Free();
338
339 m_size = size;
340 m_data = data;
341}
342
343void *wxCustomDataObject::Alloc(size_t size)
344{
345 return (void *)new char[size];
346}
347
348void wxCustomDataObject::Free()
349{
5bcea60e 350 delete [] (char *)m_data;
3f364be8
VZ
351 m_size = 0;
352 m_data = (void *)NULL;
353}
354
355size_t wxCustomDataObject::GetDataSize() const
356{
357 return GetSize();
358}
359
360bool 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
9e2896e5 371bool wxCustomDataObject::SetData(size_t size, const void *buf)
3f364be8
VZ
372{
373 Free();
374
375 m_data = Alloc(size);
376 if ( !m_data )
377 return FALSE;
378
9e2896e5 379 memcpy(m_data, buf, m_size = size);
3f364be8
VZ
380
381 return TRUE;
382}
383
8ee9d618
VZ
384// ============================================================================
385// some common dnd related code
386// ============================================================================
387
8fb3a512
JS
388#if wxUSE_DRAG_AND_DROP
389
8ee9d618
VZ
390#include "wx/dnd.h"
391
392// ----------------------------------------------------------------------------
393// wxTextDropTarget
394// ----------------------------------------------------------------------------
395
f3ac12aa
VZ
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
8ee9d618 400wxTextDropTarget::wxTextDropTarget()
8ee9d618 401{
f3ac12aa 402 SetDataObject(new wxTextDataObject);
8ee9d618
VZ
403}
404
405wxDragResult 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
418wxFileDropTarget::wxFileDropTarget()
8ee9d618 419{
f3ac12aa 420 SetDataObject(new wxFileDataObject);
8ee9d618
VZ
421}
422
423wxDragResult 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
1e6feb95 432#endif // wxUSE_DRAG_AND_DROP
8fb3a512 433
1e6feb95 434#endif // wxUSE_DATAOBJ