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