1///////////////////////////////////////////////////////////////////////////////
2// Name:        src/os2/dataobj.cpp
3// Purpose:     implementation of wx[I]DataObject class
4// Author:      David Webster
5// Modified by:
6// Created:     10/21/99
7// RCS-ID:      $Id: dataobj.cpp 40345 2006-07-27 12:57:16Z ABX $
8// Copyright:   (c) 1999 David Webster
9// Licence:     wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#if wxUSE_DATAOBJ
24
25#include "wx/dataobj.h"
26
27#ifndef WX_PRECOMP
28    #include "wx/intl.h"
29    #include "wx/log.h"
30    #include "wx/image.h"
31#endif
32
33#include "wx/mstream.h"
34
35#include "wx/os2/private.h"
36
37// ----------------------------------------------------------------------------
38// functions
39// ----------------------------------------------------------------------------
40
41// ----------------------------------------------------------------------------
42// wxDataFormat
43// ----------------------------------------------------------------------------
44
45wxString wxDataFormat::GetId() const
46{
47    wxChar                          zBuf[256];
48    wxString                        sRet;
49
50    ::WinQueryAtomName( ::WinQuerySystemAtomTable()
51                       ,m_uFormat
52                       ,(PSZ)zBuf
53                       ,256
54                      );
55    sRet = zBuf;
56    return sRet;
57} // end of wxDataFormat::GetId()
58
59void wxDataFormat::SetId (
60  const wxChar*                     zId
61)
62{
63    m_uFormat = ::WinAddAtom( ::WinQuerySystemAtomTable()
64                             ,(PSZ)zId
65                            );
66} // end of wxDataFormat::SetId
67
68class CIDataObject
69{
70public:
71    CIDataObject(wxDataObject* pDataObject);
72    ~CIDataObject();
73
74    //
75    // Operations on the DRAGITEM struct
76    //
77    bool GetData( const wxDataFormat& rFormat
78                 ,char*               pzBuffer
79                 ,ULONG               ulLen
80                );
81    void GetDataHere( const wxDataFormat& rFormat
82                     ,char*               pzBuffer
83                     ,ULONG               ulLen
84                    );
85    void QueryGetData(const wxDataFormat& rFormat);
86    void SetData( const wxDataFormat& rFormat
87                 ,char*               pzBuffer
88                );
89private:
90    wxDataObject*                   m_pDataObject;      // pointer to C++ class we belong to
91    DRAGITEM                        m_vDragItem;
92}; // end of CLASS CIDataObject
93
94bool CIDataObject::GetData ( const wxDataFormat& rFormat,
95                             char* pzBuffer,
96                             ULONG ulLen )
97{
98    QueryGetData(rFormat);
99    if (rFormat.GetType() == wxDF_INVALID)
100        return false;
101
102    ULONG                           ulSize = m_pDataObject->GetDataSize(rFormat);
103
104    if (ulSize == 0)
105    {
106        //
107        // It probably means that the method is just not implemented
108        //
109        return false;
110    }
111    if (rFormat.GetType() == wxDF_PRIVATE)
112    {
113        //
114        // For custom formats, put the size with the data - alloc the
115        // space for it
116        //
117        ulSize += sizeof(ULONG);
118    }
119
120    if (ulSize > ulLen) // not enough room to copy
121        return false;
122
123    //
124    // Copy the data
125    //
126    GetDataHere( rFormat
127                ,pzBuffer
128                ,ulSize
129               );
130    return true;
131} // end of CIDataObject::GetData
132
133void CIDataObject::GetDataHere(
134  const wxDataFormat&               rFormat
135, char*                             pzBuffer
136, ULONG                             WXUNUSED(ulLen)
137)
138{
139    m_pDataObject->GetDataHere( rFormat
140                               ,(void*)pzBuffer
141                              );
142} // end of CIDataObject::GetDataHere
143
144void CIDataObject::QueryGetData (
145  const wxDataFormat&               rFormat
146)
147{
148    m_pDataObject->IsSupportedFormat(rFormat);
149} // end of CIDataObject::QueryGetData
150
151void CIDataObject::SetData (
152  const wxDataFormat&               rFormat
153, char*                             pzBuffer
154)
155{
156    ULONG                           ulSize = 0;
157
158    switch (rFormat.GetType())
159    {
160        case wxDF_TEXT:
161        case wxDF_OEMTEXT:
162        case wxDF_FILENAME:
163        case wxDF_HTML:
164            ulSize = strlen((const char *)pzBuffer);
165            break;
166
167#if wxUSE_UNICODE
168        case wxDF_UNICODETEXT:
169             ulSize = ::wcslen((const wchar_t *)pzBuffer);
170             break;
171#endif
172
173        case wxDF_BITMAP:
174        case wxDF_METAFILE:
175        case wxDF_ENHMETAFILE:
176        case wxDF_TIFF:
177        case wxDF_DIB:
178            ulSize = 0; // pass via a handle
179            break;
180
181
182        case wxDF_SYLK:
183        case wxDF_DIF:
184        case wxDF_PALETTE:
185        case wxDF_PENDATA:
186        case wxDF_RIFF:
187        case wxDF_WAVE:
188        case wxDF_LOCALE:
189            //PUNT
190            break;
191
192        case wxDF_PRIVATE:
193            size_t*                 p = (size_t *)pzBuffer;
194
195            ulSize = *p++;
196            pzBuffer = (char*)p;
197            break;
198    }
199    m_pDataObject->SetData( rFormat
200                           ,ulSize
201                           ,(void*)pzBuffer
202                          );
203} // end of CIDataObject::SetData
204
205//-------------------------------------------------------------------------
206// wxDataObject
207//-------------------------------------------------------------------------
208
209wxDataObject::wxDataObject ()
210{
211    m_pDataObject = new DRAGITEM;
212} // end of wxDataObject::wxDataObject
213
214wxDataObject::~wxDataObject ()
215{
216    delete m_pDataObject;
217} // end of wxDataObject::~wxDataObject
218
219// ----------------------------------------------------------------------------
220// wxFileDataObject
221// ----------------------------------------------------------------------------
222
223bool wxFileDataObject::GetDataHere( void* pBuf ) const
224{
225    wxString                        sFilenames;
226
227    for (size_t i = 0; i < m_filenames.GetCount(); i++)
228    {
229        sFilenames += m_filenames[i];
230        sFilenames += (wxChar)0;
231    }
232
233    memcpy(pBuf, sFilenames.mbc_str(), sFilenames.length() + 1);
234    return true;
235}
236
237size_t wxFileDataObject::GetDataSize() const
238{
239    size_t                          nRes = 0;
240
241    for (size_t i = 0; i < m_filenames.GetCount(); i++)
242    {
243        nRes += m_filenames[i].length();
244        nRes += 1;
245    }
246
247    return nRes + 1;
248}
249
250bool wxFileDataObject::SetData( size_t WXUNUSED(nSize),
251                                const void* pBuf )
252{
253    /* TODO */
254
255    wxString sFile((const wxChar *)pBuf);  /* char, not wxChar */
256
257    AddFile(sFile);
258
259    return true;
260}
261
262void wxFileDataObject::AddFile(
263  const wxString&                   rFilename
264)
265{
266    m_filenames.Add(rFilename);
267}
268
269// ----------------------------------------------------------------------------
270// wxBitmapDataObject
271// ----------------------------------------------------------------------------
272
273wxBitmapDataObject::wxBitmapDataObject()
274{
275    Init();
276}
277
278wxBitmapDataObject::wxBitmapDataObject(
279  const wxBitmap&                   rBitmap
280)
281: wxBitmapDataObjectBase(rBitmap)
282{
283    Init();
284
285    DoConvertToPng();
286}
287
288wxBitmapDataObject::~wxBitmapDataObject()
289{
290    Clear();
291}
292
293void wxBitmapDataObject::SetBitmap( const wxBitmap& rBitmap )
294{
295    ClearAll();
296    wxBitmapDataObjectBase::SetBitmap(rBitmap);
297    DoConvertToPng();
298}
299
300bool wxBitmapDataObject::GetDataHere( void* pBuf ) const
301{
302    if (!m_pngSize)
303    {
304        wxFAIL_MSG(wxT("attempt to copy empty bitmap failed"));
305        return false;
306    }
307    memcpy(pBuf, m_pngData, m_pngSize);
308    return true;
309}
310
311bool wxBitmapDataObject::SetData( size_t nSize, const void* pBuf)
312{
313    Clear();
314    m_pngSize = nSize;
315    m_pngData = malloc(m_pngSize);
316
317    memcpy(m_pngData, pBuf, m_pngSize);
318
319#if wxUSE_STREAMS
320    wxMemoryInputStream             vMstream((char*)m_pngData, m_pngSize);
321    wxImage                         vImage;
322    wxPNGHandler                    vHandler;
323
324    if (!vHandler.LoadFile(&vImage, vMstream))
325    {
326        return false;
327    }
328
329    m_bitmap = wxBitmap(vImage);
330#endif //wxUSE_STREAMS
331
332    return m_bitmap.Ok();
333}
334
335void wxBitmapDataObject::DoConvertToPng()
336{
337    if (!m_bitmap.Ok())
338        return;
339
340#if wxUSE_STREAMS
341    wxImage                         vImage = m_bitmap.ConvertToImage();
342    wxPNGHandler                    vHandler;
343    wxCountingOutputStream          vCount;
344
345    vHandler.SaveFile(&vImage, vCount);
346
347    m_pngSize = vCount.GetSize() + 100; // sometimes the size seems to vary ???
348    m_pngData = malloc(m_pngSize);
349
350    wxMemoryOutputStream            vMstream((char*) m_pngData, m_pngSize);
351
352    vHandler.SaveFile(&vImage, vMstream );
353#endif
354}
355
356#endif // wxUSE_DATAOBJ
357