1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/common/dobjcmn.cpp 
   3 // Purpose:     implementation of data object methods common to all platforms 
   4 // Author:      Vadim Zeitlin, Robert Roebling 
   8 // Copyright:   (c) wxWidgets Team 
   9 // Licence:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  21 #include "wx/dataobj.h" 
  27 // ---------------------------------------------------------------------------- 
  29 // ---------------------------------------------------------------------------- 
  31 #include "wx/listimpl.cpp" 
  33 WX_DEFINE_LIST(wxSimpleDataObjectList
) 
  35 // ---------------------------------------------------------------------------- 
  37 // ---------------------------------------------------------------------------- 
  39 static wxDataFormat dataFormatInvalid
; 
  40 WXDLLEXPORT 
const wxDataFormat
& wxFormatInvalid 
= dataFormatInvalid
; 
  42 // ============================================================================ 
  44 // ============================================================================ 
  46 // ---------------------------------------------------------------------------- 
  48 // ---------------------------------------------------------------------------- 
  50 wxDataObjectBase::~wxDataObjectBase() 
  54 bool wxDataObjectBase::IsSupported(const wxDataFormat
& format
, 
  57     size_t nFormatCount 
= GetFormatCount( dir 
); 
  58     if ( nFormatCount 
== 1 ) 
  60         return format 
== GetPreferredFormat( dir 
); 
  64         wxDataFormat 
*formats 
= new wxDataFormat
[nFormatCount
]; 
  65         GetAllFormats( formats
, dir 
); 
  68         for ( n 
= 0; n 
< nFormatCount
; n
++ ) 
  70             if ( formats
[n
] == format 
) 
  77         return n 
< nFormatCount
; 
  81 // ---------------------------------------------------------------------------- 
  82 // wxDataObjectComposite 
  83 // ---------------------------------------------------------------------------- 
  85 wxDataObjectComposite::wxDataObjectComposite() 
  88     m_receivedFormat 
= wxFormatInvalid
; 
  91 wxDataObjectComposite::~wxDataObjectComposite() 
  93     WX_CLEAR_LIST( wxSimpleDataObjectList
, m_dataObjects 
); 
  97 wxDataObjectComposite::GetObject(const wxDataFormat
& format
) const 
  99     wxSimpleDataObjectList::compatibility_iterator node 
= m_dataObjects
.GetFirst(); 
 102         wxDataObjectSimple 
*dataObj 
= node
->GetData(); 
 104         if ( dataObj
->GetFormat() == format 
) 
 109         node 
= node
->GetNext(); 
 112     return (wxDataObjectSimple 
*)NULL
; 
 115 void wxDataObjectComposite::Add(wxDataObjectSimple 
*dataObject
, bool preferred
) 
 118         m_preferred 
= m_dataObjects
.GetCount(); 
 120     m_dataObjects
.Append( dataObject 
); 
 123 wxDataFormat 
wxDataObjectComposite::GetReceivedFormat() const 
 125     return m_receivedFormat
; 
 129 wxDataObjectComposite::GetPreferredFormat(Direction 
WXUNUSED(dir
)) const 
 131     wxSimpleDataObjectList::compatibility_iterator node 
= m_dataObjects
.Item( m_preferred 
); 
 133     wxCHECK_MSG( node
, wxFormatInvalid
, wxT("no preferred format") ); 
 135     wxDataObjectSimple
* dataObj 
= node
->GetData(); 
 137     return dataObj
->GetFormat(); 
 140 #if defined(__WXMSW__) 
 142 size_t wxDataObjectComposite::GetBufferOffset( const wxDataFormat
& format 
) 
 144     wxDataObjectSimple 
*dataObj 
= GetObject(format
); 
 146     wxCHECK_MSG( dataObj
, 0, 
 147                  wxT("unsupported format in wxDataObjectComposite")); 
 149     return dataObj
->GetBufferOffset( format 
); 
 153 const void* wxDataObjectComposite::GetSizeFromBuffer( const void* buffer
, 
 155                                                       const wxDataFormat
& format 
) 
 157     wxDataObjectSimple 
*dataObj 
= GetObject(format
); 
 159     wxCHECK_MSG( dataObj
, NULL
, 
 160                  wxT("unsupported format in wxDataObjectComposite")); 
 162     return dataObj
->GetSizeFromBuffer( buffer
, size
, format 
); 
 166 void* wxDataObjectComposite::SetSizeInBuffer( void* buffer
, size_t size
, 
 167                                               const wxDataFormat
& format 
) 
 169     wxDataObjectSimple 
*dataObj 
= GetObject( format 
); 
 171     wxCHECK_MSG( dataObj
, NULL
, 
 172                  wxT("unsupported format in wxDataObjectComposite")); 
 174     return dataObj
->SetSizeInBuffer( buffer
, size
, format 
); 
 179 size_t wxDataObjectComposite::GetFormatCount(Direction 
WXUNUSED(dir
)) const 
 181     // TODO what about the Get/Set only formats? 
 182     return m_dataObjects
.GetCount(); 
 185 void wxDataObjectComposite::GetAllFormats(wxDataFormat 
*formats
, 
 186                                           Direction 
WXUNUSED(dir
)) const 
 189     wxSimpleDataObjectList::compatibility_iterator node
; 
 190     for ( node 
= m_dataObjects
.GetFirst(); node
; node 
= node
->GetNext() ) 
 192         // TODO if ( !outputOnlyToo ) && this one counts ... 
 193         formats
[n
++] = node
->GetData()->GetFormat(); 
 197 size_t wxDataObjectComposite::GetDataSize(const wxDataFormat
& format
) const 
 199     wxDataObjectSimple 
*dataObj 
= GetObject(format
); 
 201     wxCHECK_MSG( dataObj
, 0, 
 202                  wxT("unsupported format in wxDataObjectComposite")); 
 204     return dataObj
->GetDataSize(); 
 207 bool wxDataObjectComposite::GetDataHere(const wxDataFormat
& format
, 
 210     wxDataObjectSimple 
*dataObj 
= GetObject( format 
); 
 212     wxCHECK_MSG( dataObj
, false, 
 213                  wxT("unsupported format in wxDataObjectComposite")); 
 215     return dataObj
->GetDataHere( buf 
); 
 218 bool wxDataObjectComposite::SetData(const wxDataFormat
& format
, 
 222     wxDataObjectSimple 
*dataObj 
= GetObject( format 
); 
 224     wxCHECK_MSG( dataObj
, false, 
 225                  wxT("unsupported format in wxDataObjectComposite")); 
 227     m_receivedFormat 
= format
; 
 228     return dataObj
->SetData( len
, buf 
); 
 231 // ---------------------------------------------------------------------------- 
 233 // ---------------------------------------------------------------------------- 
 235 #if defined(__WXGTK20__) && wxUSE_UNICODE 
 237 static inline wxMBConv
& GetConv(const wxDataFormat
& format
) 
 239     // use UTF8 for wxDF_UNICODETEXT and UCS4 for wxDF_TEXT 
 240     return format 
== wxDF_UNICODETEXT 
? wxConvUTF8 
: wxConvLibc
; 
 243 size_t wxTextDataObject::GetDataSize(const wxDataFormat
& format
) const 
 245     wxCharBuffer buffer 
= GetConv(format
).cWX2MB( GetText().c_str() ); 
 247     return buffer 
? strlen( buffer 
) : 0; 
 250 bool wxTextDataObject::GetDataHere(const wxDataFormat
& format
, void *buf
) const 
 255     wxCharBuffer buffer 
= GetConv(format
).cWX2MB( GetText().c_str() ); 
 259     memcpy( (char*) buf
, buffer
, GetDataSize(format
) ); 
 260     // strcpy( (char*) buf, buffer ); 
 265 bool wxTextDataObject::SetData(const wxDataFormat
& format
, 
 266                                size_t WXUNUSED(len
), const void *buf
) 
 271     wxWCharBuffer buffer 
= GetConv(format
).cMB2WX( (const char*)buf 
); 
 278 #elif wxUSE_UNICODE && defined(__WXMAC__) 
 280 static wxMBConvUTF16 sUTF16Converter
; 
 282 static inline wxMBConv
& GetConv(const wxDataFormat
& format
) 
 285         format 
== wxDF_UNICODETEXT
 
 286         ? (wxMBConv
&) sUTF16Converter
 
 287         : (wxMBConv
&) wxConvLocal
; 
 290 size_t wxTextDataObject::GetDataSize(const wxDataFormat
& format
) const 
 292     size_t len 
= GetConv(format
).WC2MB( NULL
, GetText().c_str(), 0 ); 
 293     len 
+= (format 
== wxDF_UNICODETEXT 
? 2 : 1); 
 298 bool wxTextDataObject::GetDataHere(const wxDataFormat
& format
, void *buf
) const 
 303     wxCharBuffer buffer 
= GetConv(format
).cWX2MB( GetText().c_str() ); 
 305     size_t len 
= GetConv(format
).WC2MB( NULL
, GetText().c_str(), 0 ); 
 306     len 
+= (format 
== wxDF_UNICODETEXT 
? 2 : 1); 
 308     // trailing (uni)char 0 
 309     memcpy( (char*)buf
, (const char*)buffer
, len 
); 
 314 bool wxTextDataObject::SetData(const wxDataFormat
& format
, 
 315                                size_t WXUNUSED(len
), const void *buf
) 
 320     wxWCharBuffer buffer 
= GetConv(format
).cMB2WX( (const char*)buf 
); 
 329 size_t wxTextDataObject::GetDataSize() const 
 331     return GetTextLength() * sizeof(wxChar
); 
 334 bool wxTextDataObject::GetDataHere(void *buf
) const 
 336     wxStrcpy( (wxChar
*)buf
, GetText().c_str() ); 
 341 bool wxTextDataObject::SetData(size_t WXUNUSED(len
), const void *buf
) 
 343     SetText( wxString((const wxChar
*)buf
) ); 
 350 // ---------------------------------------------------------------------------- 
 351 // wxFileDataObjectBase 
 352 // ---------------------------------------------------------------------------- 
 354 // VZ: I don't need this in MSW finally, so if it is needed in wxGTK, it should 
 355 //     be moved to gtk/dataobj.cpp 
 358 wxString 
wxFileDataObjectBase::GetFilenames() const 
 361     size_t count 
= m_filenames
.GetCount(); 
 362     for ( size_t n 
= 0; n 
< count
; n
++ ) 
 364         str 
<< m_filenames
[n
] << wxT('\0'); 
 370 void wxFileDataObjectBase::SetFilenames(const wxChar
* filenames
) 
 375     for ( const wxChar 
*pc 
= filenames
; ; pc
++ ) 
 385                 // 2 consecutive NULs - this is the end of the string 
 389             m_filenames
.Add(current
); 
 397 // ---------------------------------------------------------------------------- 
 398 // wxCustomDataObject 
 399 // ---------------------------------------------------------------------------- 
 401 wxCustomDataObject::wxCustomDataObject(const wxDataFormat
& format
) 
 402     : wxDataObjectSimple(format
) 
 408 wxCustomDataObject::~wxCustomDataObject() 
 413 void wxCustomDataObject::TakeData(size_t size
, void *data
) 
 421 void *wxCustomDataObject::Alloc(size_t size
) 
 423     return (void *)new char[size
]; 
 426 void wxCustomDataObject::Free() 
 428     delete [] (char*)m_data
; 
 430     m_data 
= (void*)NULL
; 
 433 size_t wxCustomDataObject::GetDataSize() const 
 438 bool wxCustomDataObject::GetDataHere(void *buf
) const 
 443     void *data 
= GetData(); 
 447     memcpy( buf
, data
, GetSize() ); 
 452 bool wxCustomDataObject::SetData(size_t size
, const void *buf
) 
 456     m_data 
= Alloc(size
); 
 457     if ( m_data 
== NULL 
) 
 461     memcpy( m_data
, buf
, m_size 
); 
 466 // ============================================================================ 
 467 // some common dnd related code 
 468 // ============================================================================ 
 470 #if wxUSE_DRAG_AND_DROP 
 474 // ---------------------------------------------------------------------------- 
 476 // ---------------------------------------------------------------------------- 
 478 // NB: we can't use "new" in ctor initializer lists because this provokes an 
 479 //     internal compiler error with VC++ 5.0 (hey, even gcc compiles this!), 
 480 //     so use SetDataObject() instead 
 482 wxTextDropTarget::wxTextDropTarget() 
 484     SetDataObject(new wxTextDataObject
); 
 487 wxDragResult 
wxTextDropTarget::OnData(wxCoord x
, wxCoord y
, wxDragResult def
) 
 492     wxTextDataObject 
*dobj 
= (wxTextDataObject 
*)m_dataObject
; 
 493     return OnDropText( x
, y
, dobj
->GetText() ) ? def 
: wxDragNone
; 
 496 // ---------------------------------------------------------------------------- 
 498 // ---------------------------------------------------------------------------- 
 500 wxFileDropTarget::wxFileDropTarget() 
 502     SetDataObject(new wxFileDataObject
); 
 505 wxDragResult 
wxFileDropTarget::OnData(wxCoord x
, wxCoord y
, wxDragResult def
) 
 510     wxFileDataObject 
*dobj 
= (wxFileDataObject 
*)m_dataObject
; 
 511     return OnDropFiles( x
, y
, dobj
->GetFilenames() ) ? def 
: wxDragNone
; 
 514 #endif // wxUSE_DRAG_AND_DROP 
 516 #endif // wxUSE_DATAOBJ