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