DnD with Unicode fixes
[wxWidgets.git] / src / gtk1 / dataobj.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: dataobj.cpp
3 // Purpose: wxDataObject class
4 // Author: Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
9
10 #ifdef __GNUG__
11 #pragma implementation "dataobj.h"
12 #endif
13
14 #include "wx/dataobj.h"
15 #include "wx/app.h"
16 #include "wx/debug.h"
17
18 #include "gdk/gdk.h"
19
20
21 //-------------------------------------------------------------------------
22 // global data
23 //-------------------------------------------------------------------------
24
25 GdkAtom g_textAtom = 0;
26
27 //-------------------------------------------------------------------------
28 // wxDataFormat
29 //-------------------------------------------------------------------------
30
31 IMPLEMENT_CLASS(wxDataFormat, wxObject)
32
33 wxDataFormat::wxDataFormat()
34 {
35 if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
36 m_type = wxDF_INVALID;
37 m_hasAtom = FALSE;
38 m_atom = (GdkAtom) 0;
39 }
40
41 wxDataFormat::wxDataFormat( wxDataType type )
42 {
43 if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
44 SetType( type );
45 }
46
47 wxDataFormat::wxDataFormat( const wxChar *id )
48 {
49 if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
50 SetId( id );
51 }
52
53 wxDataFormat::wxDataFormat( const wxString &id )
54 {
55 if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
56 SetId( id );
57 }
58
59 wxDataFormat::wxDataFormat( wxDataFormat &format )
60 {
61 if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
62 m_type = format.GetType();
63 m_id = format.GetId();
64 m_hasAtom = TRUE;
65 m_atom = format.GetAtom();
66 }
67
68 wxDataFormat::wxDataFormat( const GdkAtom atom )
69 {
70 if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
71 m_hasAtom = TRUE;
72
73 m_atom = atom;
74
75 if (m_atom == g_textAtom)
76 {
77 m_type = wxDF_TEXT;
78 } else
79 if (m_atom == GDK_TARGET_BITMAP)
80 {
81 m_type = wxDF_BITMAP;
82 } else
83 {
84 m_type = wxDF_PRIVATE;
85 m_id = gdk_atom_name( m_atom );
86
87 if (m_id == _T("file:ALL"))
88 {
89 m_type = wxDF_FILENAME;
90 }
91 }
92 }
93
94 void wxDataFormat::SetType( wxDataType type )
95 {
96 m_type = type;
97
98 if (m_type == wxDF_TEXT)
99 {
100 m_id = _T("STRING");
101 }
102 else
103 if (m_type == wxDF_BITMAP)
104 {
105 m_id = _T("BITMAP");
106 }
107 else
108 if (m_type == wxDF_FILENAME)
109 {
110 m_id = _T("file:ALL");
111 }
112 else
113 {
114 wxFAIL_MSG( _T("invalid dataformat") );
115 }
116
117 m_hasAtom = FALSE;
118 }
119
120 wxDataType wxDataFormat::GetType() const
121 {
122 return m_type;
123 }
124
125 wxString wxDataFormat::GetId() const
126 {
127 return m_id;
128 }
129
130 void wxDataFormat::SetId( const wxChar *id )
131 {
132 m_type = wxDF_PRIVATE;
133 m_id = id;
134 m_hasAtom = FALSE;
135 }
136
137 GdkAtom wxDataFormat::GetAtom()
138 {
139 if (!m_hasAtom)
140 {
141 m_hasAtom = TRUE;
142
143 if (m_type == wxDF_TEXT)
144 {
145 m_atom = g_textAtom;
146 }
147 else
148 if (m_type == wxDF_BITMAP)
149 {
150 m_atom = GDK_TARGET_BITMAP;
151 }
152 else
153 if (m_type == wxDF_PRIVATE)
154 {
155 m_atom = gdk_atom_intern( MBSTRINGCAST m_id.mbc_str(), FALSE );
156 }
157 else
158 if (m_type == wxDF_FILENAME)
159 {
160 m_atom = gdk_atom_intern( "file:ALL", FALSE );
161 }
162 else
163 {
164 m_hasAtom = FALSE;
165 m_atom = (GdkAtom) 0;
166 }
167 }
168
169 return m_atom;
170 }
171
172 //-------------------------------------------------------------------------
173 // wxDataBroker
174 //-------------------------------------------------------------------------
175
176 IMPLEMENT_CLASS(wxDataBroker,wxObject)
177
178 wxDataBroker::wxDataBroker()
179 {
180 m_dataObjects.DeleteContents(TRUE);
181 m_preferred = 0;
182 }
183
184 void wxDataBroker::Add( wxDataObject *dataObject, bool preferred )
185 {
186 if (preferred) m_preferred = m_dataObjects.GetCount();
187 m_dataObjects.Append( dataObject );
188 }
189
190 size_t wxDataBroker::GetFormatCount() const
191 {
192 return m_dataObjects.GetCount();
193 }
194
195 wxDataFormat &wxDataBroker::GetPreferredFormat() const
196 {
197 wxNode *node = m_dataObjects.Nth( m_preferred );
198
199 wxASSERT( node );
200
201 wxDataObject* data_obj = (wxDataObject*)node->Data();
202
203 return data_obj->GetFormat();
204 }
205
206 wxDataFormat &wxDataBroker::GetNthFormat( size_t nth ) const
207 {
208 wxNode *node = m_dataObjects.Nth( nth );
209
210 wxASSERT( node );
211
212 wxDataObject* data_obj = (wxDataObject*)node->Data();
213
214 return data_obj->GetFormat();
215 }
216
217 bool wxDataBroker::IsSupportedFormat( wxDataFormat &format ) const
218 {
219 wxNode *node = m_dataObjects.First();
220 while (node)
221 {
222 wxDataObject *dobj = (wxDataObject*)node->Data();
223
224 if (dobj->GetFormat().GetAtom() == format.GetAtom())
225 {
226 return TRUE;
227 }
228
229 node = node->Next();
230 }
231
232 return FALSE;
233 }
234
235 size_t wxDataBroker::GetSize( wxDataFormat& format ) const
236 {
237 wxNode *node = m_dataObjects.First();
238 while (node)
239 {
240 wxDataObject *dobj = (wxDataObject*)node->Data();
241
242 if (dobj->GetFormat().GetAtom() == format.GetAtom())
243 {
244 return dobj->GetSize();
245 }
246
247 node = node->Next();
248 }
249
250 return 0;
251 }
252
253 void wxDataBroker::WriteData( wxDataFormat& format, void *dest ) const
254 {
255 wxNode *node = m_dataObjects.First();
256 while (node)
257 {
258 wxDataObject *dobj = (wxDataObject*)node->Data();
259
260 if (dobj->GetFormat().GetAtom() == format.GetAtom())
261 {
262 dobj->WriteData( dest );
263 }
264
265 node = node->Next();
266 }
267 }
268
269 //-------------------------------------------------------------------------
270 // wxDataObject
271 //-------------------------------------------------------------------------
272
273 IMPLEMENT_ABSTRACT_CLASS( wxDataObject, wxObject )
274
275 wxDataObject::wxDataObject()
276 {
277 }
278
279 wxDataObject::~wxDataObject()
280 {
281 }
282
283 wxDataFormat &wxDataObject::GetFormat()
284 {
285 return m_format;
286 }
287
288 wxDataType wxDataObject::GetFormatType() const
289 {
290 return m_format.GetType();
291 }
292
293 wxString wxDataObject::GetFormatId() const
294 {
295 return m_format.GetId();
296 }
297
298 GdkAtom wxDataObject::GetFormatAtom() const
299 {
300 GdkAtom ret = ((wxDataObject*) this)->m_format.GetAtom();
301 return ret;
302 }
303
304 // ----------------------------------------------------------------------------
305 // wxTextDataObject
306 // ----------------------------------------------------------------------------
307
308 IMPLEMENT_DYNAMIC_CLASS( wxTextDataObject, wxDataObject )
309
310 wxTextDataObject::wxTextDataObject()
311 {
312 m_format.SetType( wxDF_TEXT );
313 }
314
315 wxTextDataObject::wxTextDataObject( const wxString& data )
316 {
317 m_format.SetType( wxDF_TEXT );
318
319 m_data = data;
320 }
321
322 void wxTextDataObject::SetText( const wxString& data )
323 {
324 m_data = data;
325 }
326
327 wxString wxTextDataObject::GetText() const
328 {
329 return m_data;
330 }
331
332 void wxTextDataObject::WriteData( void *dest ) const
333 {
334 WriteString( m_data, dest );
335 }
336
337 size_t wxTextDataObject::GetSize() const
338 {
339 return m_data.Len() + 1;
340 }
341
342 void wxTextDataObject::WriteString( const wxString &str, void *dest ) const
343 {
344 memcpy( dest, m_data.mbc_str(), GetSize() );
345 }
346
347 // ----------------------------------------------------------------------------
348 // wxFileDataObject
349 // ----------------------------------------------------------------------------
350
351 IMPLEMENT_DYNAMIC_CLASS( wxFileDataObject, wxDataObject )
352
353 wxFileDataObject::wxFileDataObject()
354 {
355 m_format.SetType( wxDF_FILENAME );
356 }
357
358 void wxFileDataObject::AddFile( const wxString &file )
359 {
360 m_files += file;
361 m_files += (wxChar)0;
362 }
363
364 wxString wxFileDataObject::GetFiles() const
365 {
366 return m_files;
367 }
368
369 void wxFileDataObject::WriteData( void *dest ) const
370 {
371 memcpy( dest, m_files.mbc_str(), GetSize() );
372 }
373
374 size_t wxFileDataObject::GetSize() const
375 {
376 return m_files.Len() + 1;
377 }
378
379 // ----------------------------------------------------------------------------
380 // wxBitmapDataObject
381 // ----------------------------------------------------------------------------
382
383 IMPLEMENT_DYNAMIC_CLASS( wxBitmapDataObject, wxDataObject )
384
385 wxBitmapDataObject::wxBitmapDataObject()
386 {
387 m_format.SetType( wxDF_BITMAP );
388 }
389
390 wxBitmapDataObject::wxBitmapDataObject( const wxBitmap& bitmap )
391 {
392 m_format.SetType( wxDF_BITMAP );
393
394 m_bitmap = bitmap;
395 }
396
397 void wxBitmapDataObject::SetBitmap( const wxBitmap &bitmap )
398 {
399 m_bitmap = bitmap;
400 }
401
402 wxBitmap wxBitmapDataObject::GetBitmap() const
403 {
404 return m_bitmap;
405 }
406
407 void wxBitmapDataObject::WriteData( void *dest ) const
408 {
409 WriteBitmap( m_bitmap, dest );
410 }
411
412 size_t wxBitmapDataObject::GetSize() const
413 {
414 return 0;
415 }
416
417 void wxBitmapDataObject::WriteBitmap( const wxBitmap &bitmap, void *dest ) const
418 {
419 memcpy( dest, m_bitmap.GetPixmap(), GetSize() );
420 }
421
422 // ----------------------------------------------------------------------------
423 // wxPrivateDataObject
424 // ----------------------------------------------------------------------------
425
426 IMPLEMENT_DYNAMIC_CLASS( wxPrivateDataObject, wxDataObject )
427
428 wxPrivateDataObject::wxPrivateDataObject()
429 {
430 m_id = _T("application/");
431 m_id += wxTheApp->GetAppName();
432
433 m_format.SetId( m_id );
434
435 m_size = 0;
436 m_data = (char*) NULL;
437 }
438
439 wxPrivateDataObject::~wxPrivateDataObject()
440 {
441 if (m_data) delete[] m_data;
442 }
443
444 void wxPrivateDataObject::SetId( const wxString& id )
445 {
446 m_id = id;
447 m_format.SetId( m_id );
448 }
449
450 wxString wxPrivateDataObject::GetId() const
451 {
452 return m_id;
453 }
454
455 void wxPrivateDataObject::SetData( const char *data, size_t size )
456 {
457 m_size = size;
458
459 if (m_data) delete[] m_data;
460
461 m_data = new char[size];
462
463 memcpy( m_data, data, size );
464 }
465
466 char* wxPrivateDataObject::GetData() const
467 {
468 return m_data;
469 }
470
471 void wxPrivateDataObject::WriteData( void *dest ) const
472 {
473 WriteData( m_data, dest );
474 }
475
476 size_t wxPrivateDataObject::GetSize() const
477 {
478 return m_size;
479 }
480
481 void wxPrivateDataObject::WriteData( const char *data, void *dest ) const
482 {
483 memcpy( dest, data, GetSize() );
484 }
485