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