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