]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/x11/dataobj.cpp
hide tree root on wxMSW in wxHtmlHelpController
[wxWidgets.git] / src / x11 / dataobj.cpp
... / ...
CommitLineData
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__
11 #pragma implementation "dataobj.h"
12#endif
13
14#include "wx/defs.h"
15
16#include "wx/dataobj.h"
17#include "wx/mstream.h"
18#include "wx/app.h"
19#include "wx/image.h"
20
21#include "wx/utils.h"
22#include "wx/x11/private.h"
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#if wxUSE_NANOX
101 return wxEmptyString;
102#else
103 char *t = XGetAtomName ((Display*) wxGetDisplay(), m_format);
104 wxString ret( t ); // this will convert from ascii to Unicode
105 if (t)
106 XFree( t );
107 return ret;
108#endif
109}
110
111void wxDataFormat::SetId( NativeFormat format )
112{
113 PrepareFormats();
114 m_format = format;
115
116 if (m_format == g_textAtom)
117 m_type = wxDF_TEXT;
118 else
119 if (m_format == g_pngAtom)
120 m_type = wxDF_BITMAP;
121 else
122 if (m_format == g_fileAtom)
123 m_type = wxDF_FILENAME;
124 else
125 m_type = wxDF_PRIVATE;
126}
127
128void wxDataFormat::SetId( const wxChar *id )
129{
130#if !wxUSE_NANOX
131 PrepareFormats();
132 m_type = wxDF_PRIVATE;
133 wxString tmp( id );
134 m_format = XInternAtom( (Display*) wxGetDisplay(), wxMBSTRINGCAST tmp.mbc_str(), FALSE ); // what is the string cast for?
135#endif
136}
137
138void wxDataFormat::PrepareFormats()
139{
140#if !wxUSE_NANOX
141 if (!g_textAtom)
142 g_textAtom = XInternAtom( (Display*) wxGetDisplay(), "STRING", FALSE );
143 if (!g_pngAtom)
144 g_pngAtom = XInternAtom( (Display*) wxGetDisplay(), "image/png", FALSE );
145 if (!g_fileAtom)
146 g_fileAtom = XInternAtom( (Display*) wxGetDisplay(), "text/uri-list", FALSE );
147#endif
148}
149
150//-------------------------------------------------------------------------
151// wxDataObject
152//-------------------------------------------------------------------------
153
154wxDataObject::wxDataObject()
155{
156}
157
158bool wxDataObject::IsSupportedFormat(const wxDataFormat& format, Direction dir) const
159{
160 size_t nFormatCount = GetFormatCount(dir);
161 if ( nFormatCount == 1 )
162 {
163 return format == GetPreferredFormat();
164 }
165 else
166 {
167 wxDataFormat *formats = new wxDataFormat[nFormatCount];
168 GetAllFormats(formats,dir);
169
170 size_t n;
171 for ( n = 0; n < nFormatCount; n++ )
172 {
173 if ( formats[n] == format )
174 break;
175 }
176
177 delete [] formats;
178
179 // found?
180 return n < nFormatCount;
181 }
182}
183
184// ----------------------------------------------------------------------------
185// wxFileDataObject
186// ----------------------------------------------------------------------------
187
188bool wxFileDataObject::GetDataHere(void *buf) const
189{
190 wxString filenames;
191
192 for (size_t i = 0; i < m_filenames.GetCount(); i++)
193 {
194 filenames += m_filenames[i];
195 filenames += (wxChar) 0;
196 }
197
198 memcpy( buf, filenames.mbc_str(), filenames.Len() + 1 );
199
200 return TRUE;
201}
202
203size_t wxFileDataObject::GetDataSize() const
204{
205 size_t res = 0;
206
207 for (size_t i = 0; i < m_filenames.GetCount(); i++)
208 {
209 res += m_filenames[i].Len();
210 res += 1;
211 }
212
213 return res + 1;
214}
215
216bool wxFileDataObject::SetData(size_t WXUNUSED(size), const void *buf)
217{
218 // VZ: old format
219#if 0
220 // filenames are stores as a string with #0 as deliminators
221 const char *filenames = (const char*) buf;
222 size_t pos = 0;
223 for(;;)
224 {
225 if (filenames[0] == 0)
226 break;
227 if (pos >= size)
228 break;
229 wxString file( filenames ); // this returns the first file
230 AddFile( file );
231 pos += file.Len()+1;
232 filenames += file.Len()+1;
233 }
234#else // 1
235 m_filenames.Empty();
236
237 // the text/uri-list format is a sequence of URIs (filenames prefixed by
238 // "file:" as far as I see) delimited by "\r\n" of total length size
239 // (I wonder what happens if the file has '\n' in its filename??)
240 wxString filename;
241 for ( const char *p = (const char *)buf; ; p++ )
242 {
243 // some broken programs (testdnd GTK+ sample!) omit the trailing
244 // "\r\n", so check for '\0' explicitly here instead of doing it in
245 // the loop statement to account for it
246 if ( (*p == '\r' && *(p+1) == '\n') || !*p )
247 {
248 size_t lenPrefix = 5; // strlen("file:")
249 if ( filename.Left(lenPrefix).MakeLower() == _T("file:") )
250 {
251 // sometimes the syntax is "file:filename", sometimes it's
252 // URL-like: "file://filename" - deal with both
253 if ( filename[lenPrefix] == _T('/') &&
254 filename[lenPrefix + 1] == _T('/') )
255 {
256 // skip the slashes
257 lenPrefix += 2;
258 }
259
260 AddFile(filename.c_str() + lenPrefix);
261 filename.Empty();
262 }
263 else
264 {
265 wxLogDebug(_T("Unsupported URI '%s' in wxFileDataObject"),
266 filename.c_str());
267 }
268
269 if ( !*p )
270 break;
271
272 // skip '\r'
273 p++;
274 }
275 else
276 {
277 filename += *p;
278 }
279 }
280#endif // 0/1
281
282 return TRUE;
283}
284
285void wxFileDataObject::AddFile( const wxString &filename )
286{
287 m_filenames.Add( filename );
288}
289
290// ----------------------------------------------------------------------------
291// wxBitmapDataObject
292// ----------------------------------------------------------------------------
293
294wxBitmapDataObject::wxBitmapDataObject()
295{
296 Init();
297}
298
299wxBitmapDataObject::wxBitmapDataObject( const wxBitmap& bitmap )
300 : wxBitmapDataObjectBase(bitmap)
301{
302 Init();
303
304 DoConvertToPng();
305}
306
307wxBitmapDataObject::~wxBitmapDataObject()
308{
309 Clear();
310}
311
312void wxBitmapDataObject::SetBitmap( const wxBitmap &bitmap )
313{
314 ClearAll();
315
316 wxBitmapDataObjectBase::SetBitmap(bitmap);
317
318 DoConvertToPng();
319}
320
321bool wxBitmapDataObject::GetDataHere(void *buf) const
322{
323 if ( !m_pngSize )
324 {
325 wxFAIL_MSG( wxT("attempt to copy empty bitmap failed") );
326
327 return FALSE;
328 }
329
330 memcpy(buf, m_pngData, m_pngSize);
331
332 return TRUE;
333}
334
335bool wxBitmapDataObject::SetData(size_t size, const void *buf)
336{
337 Clear();
338
339#if wxUSE_LIBPNG
340 m_pngSize = size;
341 m_pngData = malloc(m_pngSize);
342
343 memcpy( m_pngData, buf, m_pngSize );
344
345 wxMemoryInputStream mstream( (char*) m_pngData, m_pngSize );
346 wxImage image;
347 wxPNGHandler handler;
348 if ( !handler.LoadFile( &image, mstream ) )
349 {
350 return FALSE;
351 }
352
353 m_bitmap = image.ConvertToBitmap();
354
355 return m_bitmap.Ok();
356#else
357 return FALSE;
358#endif
359}
360
361void wxBitmapDataObject::DoConvertToPng()
362{
363#if wxUSE_LIBPNG
364 if (!m_bitmap.Ok())
365 return;
366
367 wxImage image( m_bitmap );
368 wxPNGHandler handler;
369
370 wxCountingOutputStream count;
371 handler.SaveFile( &image, count );
372
373 m_pngSize = count.GetSize() + 100; // sometimes the size seems to vary ???
374 m_pngData = malloc(m_pngSize);
375
376 wxMemoryOutputStream mstream( (char*) m_pngData, m_pngSize );
377 handler.SaveFile( &image, mstream );
378#endif
379}
380