]> git.saurik.com Git - wxWidgets.git/blob - src/common/dobjcmn.cpp
filter out garbage Windows sends us via LVN_ODCACHEHINT
[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 #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 wxDataObjectSimple *
98 wxDataObjectComposite::GetObject(const wxDataFormat& format) const
99 {
100 wxSimpleDataObjectList::Node *node = m_dataObjects.GetFirst();
101 while ( node )
102 {
103 wxDataObjectSimple *dataObj = node->GetData();
104
105 if ( dataObj->GetFormat() == format )
106 {
107 return dataObj;
108 }
109
110 node = node->GetNext();
111 }
112
113 return (wxDataObjectSimple *)NULL;
114 }
115
116 void wxDataObjectComposite::Add(wxDataObjectSimple *dataObject, bool preferred)
117 {
118 if ( preferred )
119 m_preferred = m_dataObjects.GetCount();
120
121 m_dataObjects.Append( dataObject );
122 }
123
124 wxDataFormat
125 wxDataObjectComposite::GetPreferredFormat(Direction WXUNUSED(dir)) const
126 {
127 wxSimpleDataObjectList::Node *node = m_dataObjects.Item( m_preferred );
128
129 wxCHECK_MSG( node, wxFormatInvalid, wxT("no preferred format") );
130
131 wxDataObjectSimple* dataObj = node->GetData();
132
133 return dataObj->GetFormat();
134 }
135
136 size_t wxDataObjectComposite::GetFormatCount(Direction WXUNUSED(dir)) const
137 {
138 // TODO what about the Get/Set only formats?
139 return m_dataObjects.GetCount();
140 }
141
142 void wxDataObjectComposite::GetAllFormats(wxDataFormat *formats,
143 Direction WXUNUSED(dir)) const
144 {
145 size_t n = 0;
146 wxSimpleDataObjectList::Node *node;
147 for ( node = m_dataObjects.GetFirst(); node; node = node->GetNext() )
148 {
149 // TODO if ( !outputOnlyToo ) && this one counts ...
150 formats[n++] = node->GetData()->GetFormat();
151 }
152 }
153
154 size_t wxDataObjectComposite::GetDataSize(const wxDataFormat& format) const
155 {
156 wxDataObjectSimple *dataObj = GetObject(format);
157
158 wxCHECK_MSG( dataObj, 0,
159 wxT("unsupported format in wxDataObjectComposite"));
160
161 return dataObj->GetDataSize();
162 }
163
164 bool wxDataObjectComposite::GetDataHere(const wxDataFormat& format,
165 void *buf) const
166 {
167 wxDataObjectSimple *dataObj = GetObject(format);
168
169 wxCHECK_MSG( dataObj, FALSE,
170 wxT("unsupported format in wxDataObjectComposite"));
171
172 return dataObj->GetDataHere(buf);
173 }
174
175 bool wxDataObjectComposite::SetData(const wxDataFormat& format,
176 size_t len,
177 const void *buf)
178 {
179 wxDataObjectSimple *dataObj = GetObject(format);
180
181 wxCHECK_MSG( dataObj, FALSE,
182 wxT("unsupported format in wxDataObjectComposite"));
183
184 return dataObj->SetData(len, buf);
185 }
186
187 // ----------------------------------------------------------------------------
188 // wxTextDataObject
189 // ----------------------------------------------------------------------------
190
191 size_t wxTextDataObject::GetDataSize() const
192 {
193 return GetTextLength();
194 }
195
196 bool wxTextDataObject::GetDataHere(void *buf) const
197 {
198 strcpy((char *)buf, GetText().mb_str());
199
200 return TRUE;
201 }
202
203 bool wxTextDataObject::SetData(size_t WXUNUSED(len), const void *buf)
204 {
205 SetText(wxString((const char *)buf));
206
207 return TRUE;
208 }
209
210 // ----------------------------------------------------------------------------
211 // wxFileDataObjectBase
212 // ----------------------------------------------------------------------------
213
214 // VZ: I don't need this in MSW finally, so if it is needed in wxGTK, it should
215 // be moved to gtk/dataobj.cpp
216 #if 0
217
218 wxString wxFileDataObjectBase::GetFilenames() const
219 {
220 wxString str;
221 size_t count = m_filenames.GetCount();
222 for ( size_t n = 0; n < count; n++ )
223 {
224 str << m_filenames[n] << wxT('\0');
225 }
226
227 return str;
228 }
229
230 void wxFileDataObjectBase::SetFilenames(const wxChar* filenames)
231 {
232 m_filenames.Empty();
233
234 wxString current;
235 for ( const wxChar *pc = filenames; ; pc++ )
236 {
237 if ( *pc )
238 {
239 current += *pc;
240 }
241 else
242 {
243 if ( !current )
244 {
245 // 2 consecutive NULs - this is the end of the string
246 break;
247 }
248
249 m_filenames.Add(current);
250 current.Empty();
251 }
252 }
253 }
254
255 #endif // 0
256
257 // ----------------------------------------------------------------------------
258 // wxCustomDataObject
259 // ----------------------------------------------------------------------------
260
261 wxCustomDataObject::wxCustomDataObject(const wxDataFormat& format)
262 : wxDataObjectSimple(format)
263 {
264 m_data = (void *)NULL;
265 }
266
267 wxCustomDataObject::~wxCustomDataObject()
268 {
269 Free();
270 }
271
272 void wxCustomDataObject::TakeData(size_t size, void *data)
273 {
274 Free();
275
276 m_size = size;
277 m_data = data;
278 }
279
280 void *wxCustomDataObject::Alloc(size_t size)
281 {
282 return (void *)new char[size];
283 }
284
285 void wxCustomDataObject::Free()
286 {
287 delete [] (char *)m_data;
288 m_size = 0;
289 m_data = (void *)NULL;
290 }
291
292 size_t wxCustomDataObject::GetDataSize() const
293 {
294 return GetSize();
295 }
296
297 bool wxCustomDataObject::GetDataHere(void *buf) const
298 {
299 void *data = GetData();
300 if ( !data )
301 return FALSE;
302
303 memcpy(buf, data, GetSize());
304
305 return TRUE;
306 }
307
308 bool wxCustomDataObject::SetData(size_t size, const void *buf)
309 {
310 Free();
311
312 m_data = Alloc(size);
313 if ( !m_data )
314 return FALSE;
315
316 memcpy(m_data, buf, m_size = size);
317
318 return TRUE;
319 }
320
321 // ============================================================================
322 // some common dnd related code
323 // ============================================================================
324
325 #if wxUSE_DRAG_AND_DROP
326
327 #include "wx/dnd.h"
328
329 // ----------------------------------------------------------------------------
330 // wxTextDropTarget
331 // ----------------------------------------------------------------------------
332
333 // NB: we can't use "new" in ctor initializer lists because this provokes an
334 // internal compiler error with VC++ 5.0 (hey, even gcc compiles this!),
335 // so use SetDataObject() instead
336
337 wxTextDropTarget::wxTextDropTarget()
338 {
339 SetDataObject(new wxTextDataObject);
340 }
341
342 wxDragResult wxTextDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult def)
343 {
344 if ( !GetData() )
345 return wxDragNone;
346
347 wxTextDataObject *dobj = (wxTextDataObject *)m_dataObject;
348 return OnDropText(x, y, dobj->GetText()) ? def : wxDragNone;
349 }
350
351 // ----------------------------------------------------------------------------
352 // wxFileDropTarget
353 // ----------------------------------------------------------------------------
354
355 wxFileDropTarget::wxFileDropTarget()
356 {
357 SetDataObject(new wxFileDataObject);
358 }
359
360 wxDragResult wxFileDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult def)
361 {
362 if ( !GetData() )
363 return wxDragNone;
364
365 wxFileDataObject *dobj = (wxFileDataObject *)m_dataObject;
366 return OnDropFiles(x, y, dobj->GetFilenames()) ? def : wxDragNone;
367 }
368
369 #endif // wxUSE_DRAG_AND_DROP
370
371 #endif // wxUSE_DATAOBJ