]> git.saurik.com Git - wxWidgets.git/blame - src/common/dobjcmn.cpp
Added chapter on collection and container classes to contents
[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
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
43WX_DEFINE_LIST(wxSimpleDataObjectList);
44
0c2b453f
VZ
45// ----------------------------------------------------------------------------
46// globals
47// ----------------------------------------------------------------------------
48
49static wxDataFormat dataFormatInvalid;
31e78e0c 50WXDLLEXPORT const wxDataFormat& wxFormatInvalid = dataFormatInvalid;
0c2b453f 51
3f364be8
VZ
52// ============================================================================
53// implementation
54// ============================================================================
55
56// ----------------------------------------------------------------------------
57// wxDataObjectBase
58// ----------------------------------------------------------------------------
59
60wxDataObjectBase::~wxDataObjectBase()
61{
62}
63
d9317fd4
VZ
64bool 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
3f364be8
VZ
91// ----------------------------------------------------------------------------
92// wxDataObjectComposite
93// ----------------------------------------------------------------------------
94
95wxDataObjectSimple *
96wxDataObjectComposite::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
114void wxDataObjectComposite::Add(wxDataObjectSimple *dataObject, bool preferred)
115{
116 if ( preferred )
117 m_preferred = m_dataObjects.GetCount();
118
119 m_dataObjects.Append( dataObject );
120}
121
122wxDataFormat
123wxDataObjectComposite::GetPreferredFormat(Direction WXUNUSED(dir)) const
124{
125 wxSimpleDataObjectList::Node *node = m_dataObjects.Item( m_preferred );
126
2ee3ee1b 127 wxCHECK_MSG( node, wxFormatInvalid, wxT("no preferred format") );
3f364be8
VZ
128
129 wxDataObjectSimple* dataObj = node->GetData();
130
131 return dataObj->GetFormat();
132}
133
134size_t wxDataObjectComposite::GetFormatCount(Direction WXUNUSED(dir)) const
135{
136 // TODO what about the Get/Set only formats?
137 return m_dataObjects.GetCount();
138}
139
140void 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
152size_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
162bool 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
173bool 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
189size_t wxTextDataObject::GetDataSize() const
190{
191 return GetTextLength();
192}
193
194bool wxTextDataObject::GetDataHere(void *buf) const
195{
196 strcpy((char *)buf, GetText().mb_str());
197
198 return TRUE;
199}
200
201bool 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
9e2896e5
VZ
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
3f364be8
VZ
216wxString 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
228void 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
9e2896e5
VZ
253#endif // 0
254
3f364be8
VZ
255// ----------------------------------------------------------------------------
256// wxCustomDataObject
257// ----------------------------------------------------------------------------
258
775e1c62
RD
259wxCustomDataObject::wxCustomDataObject(const wxDataFormat& format)
260 : wxDataObjectSimple(format)
261{
4e16881a 262 m_data = (void *)NULL;
775e1c62
RD
263}
264
3f364be8
VZ
265wxCustomDataObject::~wxCustomDataObject()
266{
267 Free();
268}
269
270void wxCustomDataObject::TakeData(size_t size, void *data)
271{
272 Free();
273
274 m_size = size;
275 m_data = data;
276}
277
278void *wxCustomDataObject::Alloc(size_t size)
279{
280 return (void *)new char[size];
281}
282
283void wxCustomDataObject::Free()
284{
5bcea60e 285 delete [] (char *)m_data;
3f364be8
VZ
286 m_size = 0;
287 m_data = (void *)NULL;
288}
289
290size_t wxCustomDataObject::GetDataSize() const
291{
292 return GetSize();
293}
294
295bool 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
9e2896e5 306bool wxCustomDataObject::SetData(size_t size, const void *buf)
3f364be8
VZ
307{
308 Free();
309
310 m_data = Alloc(size);
311 if ( !m_data )
312 return FALSE;
313
9e2896e5 314 memcpy(m_data, buf, m_size = size);
3f364be8
VZ
315
316 return TRUE;
317}
318
8ee9d618
VZ
319// ============================================================================
320// some common dnd related code
321// ============================================================================
322
8fb3a512
JS
323#if wxUSE_DRAG_AND_DROP
324
8ee9d618
VZ
325#include "wx/dnd.h"
326
327// ----------------------------------------------------------------------------
328// wxTextDropTarget
329// ----------------------------------------------------------------------------
330
f3ac12aa
VZ
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
8ee9d618 335wxTextDropTarget::wxTextDropTarget()
8ee9d618 336{
f3ac12aa 337 SetDataObject(new wxTextDataObject);
8ee9d618
VZ
338}
339
340wxDragResult 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
353wxFileDropTarget::wxFileDropTarget()
8ee9d618 354{
f3ac12aa 355 SetDataObject(new wxFileDataObject);
8ee9d618
VZ
356}
357
358wxDragResult 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
8fb3a512
JS
367#endif
368