]> git.saurik.com Git - wxWidgets.git/blame - src/x11/dataobj.cpp
Added simplistic wxToolBar to wxUniversal. It
[wxWidgets.git] / src / x11 / dataobj.cpp
CommitLineData
83df96d6
JS
1///////////////////////////////////////////////////////////////////////////////
2// Name: dataobj.cpp
3// Purpose: wxDataObject class
4// Author: Julian Smart
5// Id: $Id$
6// Copyright: (c) 1998 Julian Smart
7// Licence: wxWindows licence
8///////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
9691c806 11 #pragma implementation "dataobj.h"
83df96d6
JS
12#endif
13
14#include "wx/defs.h"
15
83df96d6 16#include "wx/dataobj.h"
9691c806 17#include "wx/mstream.h"
83df96d6 18#include "wx/app.h"
9691c806 19#include "wx/image.h"
83df96d6 20
83df96d6 21#include "wx/utils.h"
7266b672 22#include "wx/x11/private.h"
83df96d6
JS
23
24//-------------------------------------------------------------------------
25// global data
26//-------------------------------------------------------------------------
27
28Atom g_textAtom = 0;
29Atom g_pngAtom = 0;
30Atom g_fileAtom = 0;
31
32//-------------------------------------------------------------------------
33// wxDataFormat
34//-------------------------------------------------------------------------
35
36wxDataFormat::wxDataFormat()
37{
38 // do *not* call PrepareFormats() from here for 2 reasons:
39 //
40 // 1. we will have time to do it later because some other Set function
41 // must be called before we really need them
42 //
43 // 2. doing so prevents us from declaring global wxDataFormats because
44 // calling PrepareFormats (and thus gdk_atom_intern) before GDK is
45 // initialised will result in a crash
46 m_type = wxDF_INVALID;
47 m_format = (Atom) 0;
48}
49
50wxDataFormat::wxDataFormat( wxDataFormatId type )
51{
52 PrepareFormats();
53 SetType( type );
54}
55
56wxDataFormat::wxDataFormat( const wxChar *id )
57{
58 PrepareFormats();
59 SetId( id );
60}
61
62wxDataFormat::wxDataFormat( const wxString &id )
63{
64 PrepareFormats();
65 SetId( id );
66}
67
68wxDataFormat::wxDataFormat( NativeFormat format )
69{
70 PrepareFormats();
71 SetId( format );
72}
73
74void wxDataFormat::SetType( wxDataFormatId type )
75{
76 PrepareFormats();
77 m_type = type;
78
79 if (m_type == wxDF_TEXT)
80 m_format = g_textAtom;
81 else
82 if (m_type == wxDF_BITMAP)
83 m_format = g_pngAtom;
84 else
85 if (m_type == wxDF_FILENAME)
86 m_format = g_fileAtom;
87 else
88 {
89 wxFAIL_MSG( wxT("invalid dataformat") );
90 }
91}
92
93wxDataFormatId wxDataFormat::GetType() const
94{
95 return m_type;
96}
97
98wxString wxDataFormat::GetId() const
99{
100 char *t = XGetAtomName ((Display*) wxGetDisplay(), m_format);
101 wxString ret( t ); // this will convert from ascii to Unicode
102 if (t)
103 XFree( t );
104 return ret;
105}
106
107void wxDataFormat::SetId( NativeFormat format )
108{
109 PrepareFormats();
110 m_format = format;
111
112 if (m_format == g_textAtom)
113 m_type = wxDF_TEXT;
114 else
115 if (m_format == g_pngAtom)
116 m_type = wxDF_BITMAP;
117 else
118 if (m_format == g_fileAtom)
119 m_type = wxDF_FILENAME;
120 else
121 m_type = wxDF_PRIVATE;
122}
123
124void wxDataFormat::SetId( const wxChar *id )
125{
126 PrepareFormats();
127 m_type = wxDF_PRIVATE;
128 wxString tmp( id );
129 m_format = XInternAtom( (Display*) wxGetDisplay(), wxMBSTRINGCAST tmp.mbc_str(), FALSE ); // what is the string cast for?
130}
131
132void wxDataFormat::PrepareFormats()
133{
134 if (!g_textAtom)
135 g_textAtom = XInternAtom( (Display*) wxGetDisplay(), "STRING", FALSE );
136 if (!g_pngAtom)
137 g_pngAtom = XInternAtom( (Display*) wxGetDisplay(), "image/png", FALSE );
138 if (!g_fileAtom)
9691c806 139 g_fileAtom = XInternAtom( (Display*) wxGetDisplay(), "text/uri-list", FALSE );
83df96d6
JS
140}
141
9691c806
RR
142//-------------------------------------------------------------------------
143// wxDataObject
144//-------------------------------------------------------------------------
145
146wxDataObject::wxDataObject()
147{
148}
149
150bool wxDataObject::IsSupportedFormat(const wxDataFormat& format, Direction dir) const
151{
152 size_t nFormatCount = GetFormatCount(dir);
153 if ( nFormatCount == 1 )
154 {
155 return format == GetPreferredFormat();
156 }
157 else
158 {
159 wxDataFormat *formats = new wxDataFormat[nFormatCount];
160 GetAllFormats(formats,dir);
161
162 size_t n;
163 for ( n = 0; n < nFormatCount; n++ )
164 {
165 if ( formats[n] == format )
166 break;
167 }
168
169 delete [] formats;
170
171 // found?
172 return n < nFormatCount;
173 }
174}
83df96d6
JS
175
176// ----------------------------------------------------------------------------
9691c806 177// wxFileDataObject
83df96d6
JS
178// ----------------------------------------------------------------------------
179
9691c806
RR
180bool wxFileDataObject::GetDataHere(void *buf) const
181{
182 wxString filenames;
183
184 for (size_t i = 0; i < m_filenames.GetCount(); i++)
185 {
186 filenames += m_filenames[i];
187 filenames += (wxChar) 0;
188 }
189
190 memcpy( buf, filenames.mbc_str(), filenames.Len() + 1 );
191
192 return TRUE;
193}
83df96d6 194
9691c806 195size_t wxFileDataObject::GetDataSize() const
83df96d6 196{
9691c806
RR
197 size_t res = 0;
198
199 for (size_t i = 0; i < m_filenames.GetCount(); i++)
200 {
201 res += m_filenames[i].Len();
202 res += 1;
203 }
204
205 return res + 1;
83df96d6
JS
206}
207
9691c806 208bool wxFileDataObject::SetData(size_t WXUNUSED(size), const void *buf)
83df96d6 209{
9691c806
RR
210 // VZ: old format
211#if 0
212 // filenames are stores as a string with #0 as deliminators
213 const char *filenames = (const char*) buf;
214 size_t pos = 0;
215 for(;;)
216 {
217 if (filenames[0] == 0)
218 break;
219 if (pos >= size)
220 break;
221 wxString file( filenames ); // this returns the first file
222 AddFile( file );
223 pos += file.Len()+1;
224 filenames += file.Len()+1;
225 }
226#else // 1
227 m_filenames.Empty();
228
229 // the text/uri-list format is a sequence of URIs (filenames prefixed by
230 // "file:" as far as I see) delimited by "\r\n" of total length size
231 // (I wonder what happens if the file has '\n' in its filename??)
232 wxString filename;
233 for ( const char *p = (const char *)buf; ; p++ )
234 {
235 // some broken programs (testdnd GTK+ sample!) omit the trailing
236 // "\r\n", so check for '\0' explicitly here instead of doing it in
237 // the loop statement to account for it
238 if ( (*p == '\r' && *(p+1) == '\n') || !*p )
239 {
240 size_t lenPrefix = 5; // strlen("file:")
241 if ( filename.Left(lenPrefix).MakeLower() == _T("file:") )
242 {
243 // sometimes the syntax is "file:filename", sometimes it's
244 // URL-like: "file://filename" - deal with both
245 if ( filename[lenPrefix] == _T('/') &&
246 filename[lenPrefix + 1] == _T('/') )
247 {
248 // skip the slashes
249 lenPrefix += 2;
250 }
251
252 AddFile(filename.c_str() + lenPrefix);
253 filename.Empty();
254 }
255 else
256 {
257 wxLogDebug(_T("Unsupported URI '%s' in wxFileDataObject"),
258 filename.c_str());
259 }
260
261 if ( !*p )
262 break;
263
264 // skip '\r'
265 p++;
266 }
267 else
268 {
269 filename += *p;
270 }
271 }
272#endif // 0/1
83df96d6 273
9691c806
RR
274 return TRUE;
275}
83df96d6 276
9691c806
RR
277void wxFileDataObject::AddFile( const wxString &filename )
278{
279 m_filenames.Add( filename );
83df96d6
JS
280}
281
9691c806
RR
282// ----------------------------------------------------------------------------
283// wxBitmapDataObject
284// ----------------------------------------------------------------------------
285
286wxBitmapDataObject::wxBitmapDataObject()
83df96d6 287{
9691c806
RR
288 Init();
289}
83df96d6 290
9691c806
RR
291wxBitmapDataObject::wxBitmapDataObject( const wxBitmap& bitmap )
292 : wxBitmapDataObjectBase(bitmap)
293{
294 Init();
83df96d6 295
9691c806 296 DoConvertToPng();
83df96d6
JS
297}
298
9691c806 299wxBitmapDataObject::~wxBitmapDataObject()
83df96d6 300{
9691c806 301 Clear();
83df96d6
JS
302}
303
9691c806 304void wxBitmapDataObject::SetBitmap( const wxBitmap &bitmap )
83df96d6 305{
9691c806
RR
306 ClearAll();
307
308 wxBitmapDataObjectBase::SetBitmap(bitmap);
309
310 DoConvertToPng();
83df96d6
JS
311}
312
9691c806 313bool wxBitmapDataObject::GetDataHere(void *buf) const
83df96d6 314{
9691c806
RR
315 if ( !m_pngSize )
316 {
317 wxFAIL_MSG( wxT("attempt to copy empty bitmap failed") );
318
319 return FALSE;
320 }
321
322 memcpy(buf, m_pngData, m_pngSize);
323
324 return TRUE;
83df96d6
JS
325}
326
9691c806
RR
327bool wxBitmapDataObject::SetData(size_t size, const void *buf)
328{
329 Clear();
330
331#if wxUSE_LIBPNG
332 m_pngSize = size;
333 m_pngData = malloc(m_pngSize);
334
335 memcpy( m_pngData, buf, m_pngSize );
336
337 wxMemoryInputStream mstream( (char*) m_pngData, m_pngSize );
338 wxImage image;
339 wxPNGHandler handler;
340 if ( !handler.LoadFile( &image, mstream ) )
341 {
342 return FALSE;
343 }
344
345 m_bitmap = image.ConvertToBitmap();
346
347 return m_bitmap.Ok();
348#else
349 return FALSE;
350#endif
351}
352
353void wxBitmapDataObject::DoConvertToPng()
354{
355#if wxUSE_LIBPNG
356 if (!m_bitmap.Ok())
357 return;
358
359 wxImage image( m_bitmap );
360 wxPNGHandler handler;
361
362 wxCountingOutputStream count;
363 handler.SaveFile( &image, count );
364
365 m_pngSize = count.GetSize() + 100; // sometimes the size seems to vary ???
366 m_pngData = malloc(m_pngSize);
367
368 wxMemoryOutputStream mstream( (char*) m_pngData, m_pngSize );
369 handler.SaveFile( &image, mstream );
370#endif
371}
83df96d6 372