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