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"
26 #include "wx/dataobj.h"
28 // ----------------------------------------------------------------------------
30 // ----------------------------------------------------------------------------
32 #include "wx/listimpl.cpp"
34 WX_DEFINE_LIST(wxSimpleDataObjectList
)
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 static wxDataFormat dataFormatInvalid
;
41 WXDLLEXPORT
const wxDataFormat
& wxFormatInvalid
= dataFormatInvalid
;
43 // ============================================================================
45 // ============================================================================
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 wxDataObjectBase::~wxDataObjectBase()
55 bool wxDataObjectBase::IsSupported(const wxDataFormat
& format
,
58 size_t nFormatCount
= GetFormatCount( dir
);
59 if ( nFormatCount
== 1 )
61 return format
== GetPreferredFormat( dir
);
65 wxDataFormat
*formats
= new wxDataFormat
[nFormatCount
];
66 GetAllFormats( formats
, dir
);
69 for ( n
= 0; n
< nFormatCount
; n
++ )
71 if ( formats
[n
] == format
)
78 return n
< nFormatCount
;
82 // ----------------------------------------------------------------------------
83 // wxDataObjectComposite
84 // ----------------------------------------------------------------------------
86 wxDataObjectComposite::wxDataObjectComposite()
89 m_receivedFormat
= wxFormatInvalid
;
92 wxDataObjectComposite::~wxDataObjectComposite()
94 WX_CLEAR_LIST( wxSimpleDataObjectList
, m_dataObjects
);
98 wxDataObjectComposite::GetObject(const wxDataFormat
& format
) const
100 wxSimpleDataObjectList::compatibility_iterator node
= m_dataObjects
.GetFirst();
103 wxDataObjectSimple
*dataObj
= node
->GetData();
105 if ( dataObj
->GetFormat() == format
)
110 node
= node
->GetNext();
113 return (wxDataObjectSimple
*)NULL
;
116 void wxDataObjectComposite::Add(wxDataObjectSimple
*dataObject
, bool preferred
)
119 m_preferred
= m_dataObjects
.GetCount();
121 m_dataObjects
.Append( dataObject
);
124 wxDataFormat
wxDataObjectComposite::GetReceivedFormat() const
126 return m_receivedFormat
;
130 wxDataObjectComposite::GetPreferredFormat(Direction
WXUNUSED(dir
)) const
132 wxSimpleDataObjectList::compatibility_iterator node
= m_dataObjects
.Item( m_preferred
);
134 wxCHECK_MSG( node
, wxFormatInvalid
, wxT("no preferred format") );
136 wxDataObjectSimple
* dataObj
= node
->GetData();
138 return dataObj
->GetFormat();
141 #if defined(__WXMSW__)
143 size_t wxDataObjectComposite::GetBufferOffset( const wxDataFormat
& format
)
145 wxDataObjectSimple
*dataObj
= GetObject(format
);
147 wxCHECK_MSG( dataObj
, 0,
148 wxT("unsupported format in wxDataObjectComposite"));
150 return dataObj
->GetBufferOffset( format
);
154 const void* wxDataObjectComposite::GetSizeFromBuffer( const void* buffer
,
156 const wxDataFormat
& format
)
158 wxDataObjectSimple
*dataObj
= GetObject(format
);
160 wxCHECK_MSG( dataObj
, NULL
,
161 wxT("unsupported format in wxDataObjectComposite"));
163 return dataObj
->GetSizeFromBuffer( buffer
, size
, format
);
167 void* wxDataObjectComposite::SetSizeInBuffer( void* buffer
, size_t size
,
168 const wxDataFormat
& format
)
170 wxDataObjectSimple
*dataObj
= GetObject( format
);
172 wxCHECK_MSG( dataObj
, NULL
,
173 wxT("unsupported format in wxDataObjectComposite"));
175 return dataObj
->SetSizeInBuffer( buffer
, size
, format
);
180 size_t wxDataObjectComposite::GetFormatCount(Direction
WXUNUSED(dir
)) const
182 // TODO what about the Get/Set only formats?
183 return m_dataObjects
.GetCount();
186 void wxDataObjectComposite::GetAllFormats(wxDataFormat
*formats
,
187 Direction
WXUNUSED(dir
)) const
190 wxSimpleDataObjectList::compatibility_iterator node
;
191 for ( node
= m_dataObjects
.GetFirst(); node
; node
= node
->GetNext() )
193 // TODO if ( !outputOnlyToo ) && this one counts ...
194 formats
[n
++] = node
->GetData()->GetFormat();
198 size_t wxDataObjectComposite::GetDataSize(const wxDataFormat
& format
) const
200 wxDataObjectSimple
*dataObj
= GetObject(format
);
202 wxCHECK_MSG( dataObj
, 0,
203 wxT("unsupported format in wxDataObjectComposite"));
205 return dataObj
->GetDataSize();
208 bool wxDataObjectComposite::GetDataHere(const wxDataFormat
& format
,
211 wxDataObjectSimple
*dataObj
= GetObject( format
);
213 wxCHECK_MSG( dataObj
, false,
214 wxT("unsupported format in wxDataObjectComposite"));
216 return dataObj
->GetDataHere( buf
);
219 bool wxDataObjectComposite::SetData(const wxDataFormat
& format
,
223 wxDataObjectSimple
*dataObj
= GetObject( format
);
225 wxCHECK_MSG( dataObj
, false,
226 wxT("unsupported format in wxDataObjectComposite"));
228 m_receivedFormat
= format
;
229 return dataObj
->SetData( len
, buf
);
232 // ----------------------------------------------------------------------------
234 // ----------------------------------------------------------------------------
236 #if defined(__WXGTK20__) && wxUSE_UNICODE
238 static inline wxMBConv
& GetConv(const wxDataFormat
& format
)
240 // use UTF8 for wxDF_UNICODETEXT and UCS4 for wxDF_TEXT
241 return format
== wxDF_UNICODETEXT
? wxConvUTF8
: wxConvLibc
;
244 size_t wxTextDataObject::GetDataSize(const wxDataFormat
& format
) const
246 wxCharBuffer buffer
= GetConv(format
).cWX2MB( GetText().c_str() );
248 return buffer
? strlen( buffer
) : 0;
251 bool wxTextDataObject::GetDataHere(const wxDataFormat
& format
, void *buf
) const
256 wxCharBuffer buffer
= GetConv(format
).cWX2MB( GetText().c_str() );
260 memcpy( (char*) buf
, buffer
, GetDataSize(format
) );
261 // strcpy( (char*) buf, buffer );
266 bool wxTextDataObject::SetData(const wxDataFormat
& format
,
267 size_t WXUNUSED(len
), const void *buf
)
272 wxWCharBuffer buffer
= GetConv(format
).cMB2WX( (const char*)buf
);
279 #elif wxUSE_UNICODE && defined(__WXMAC__)
281 static wxMBConvUTF16 sUTF16Converter
;
283 static inline wxMBConv
& GetConv(const wxDataFormat
& format
)
286 format
== wxDF_UNICODETEXT
287 ? (wxMBConv
&) sUTF16Converter
288 : (wxMBConv
&) wxConvLocal
;
291 size_t wxTextDataObject::GetDataSize(const wxDataFormat
& format
) const
293 size_t len
= GetConv(format
).WC2MB( NULL
, GetText().c_str(), 0 );
294 len
+= (format
== wxDF_UNICODETEXT
? 2 : 1);
299 bool wxTextDataObject::GetDataHere(const wxDataFormat
& format
, void *buf
) const
304 wxCharBuffer buffer
= GetConv(format
).cWX2MB( GetText().c_str() );
306 size_t len
= GetConv(format
).WC2MB( NULL
, GetText().c_str(), 0 );
307 len
+= (format
== wxDF_UNICODETEXT
? 2 : 1);
309 // trailing (uni)char 0
310 memcpy( (char*)buf
, (const char*)buffer
, len
);
315 bool wxTextDataObject::SetData(const wxDataFormat
& format
,
316 size_t WXUNUSED(len
), const void *buf
)
321 wxWCharBuffer buffer
= GetConv(format
).cMB2WX( (const char*)buf
);
330 size_t wxTextDataObject::GetDataSize() const
332 return GetTextLength() * sizeof(wxChar
);
335 bool wxTextDataObject::GetDataHere(void *buf
) const
337 wxStrcpy( (wxChar
*)buf
, GetText().c_str() );
342 bool wxTextDataObject::SetData(size_t WXUNUSED(len
), const void *buf
)
344 SetText( wxString((const wxChar
*)buf
) );
351 // ----------------------------------------------------------------------------
352 // wxFileDataObjectBase
353 // ----------------------------------------------------------------------------
355 // VZ: I don't need this in MSW finally, so if it is needed in wxGTK, it should
356 // be moved to gtk/dataobj.cpp
359 wxString
wxFileDataObjectBase::GetFilenames() const
362 size_t count
= m_filenames
.GetCount();
363 for ( size_t n
= 0; n
< count
; n
++ )
365 str
<< m_filenames
[n
] << wxT('\0');
371 void wxFileDataObjectBase::SetFilenames(const wxChar
* filenames
)
376 for ( const wxChar
*pc
= filenames
; ; pc
++ )
386 // 2 consecutive NULs - this is the end of the string
390 m_filenames
.Add(current
);
398 // ----------------------------------------------------------------------------
399 // wxCustomDataObject
400 // ----------------------------------------------------------------------------
402 wxCustomDataObject::wxCustomDataObject(const wxDataFormat
& format
)
403 : wxDataObjectSimple(format
)
409 wxCustomDataObject::~wxCustomDataObject()
414 void wxCustomDataObject::TakeData(size_t size
, void *data
)
422 void *wxCustomDataObject::Alloc(size_t size
)
424 return (void *)new char[size
];
427 void wxCustomDataObject::Free()
429 delete [] (char*)m_data
;
431 m_data
= (void*)NULL
;
434 size_t wxCustomDataObject::GetDataSize() const
439 bool wxCustomDataObject::GetDataHere(void *buf
) const
444 void *data
= GetData();
448 memcpy( buf
, data
, GetSize() );
453 bool wxCustomDataObject::SetData(size_t size
, const void *buf
)
457 m_data
= Alloc(size
);
458 if ( m_data
== NULL
)
462 memcpy( m_data
, buf
, m_size
);
467 // ============================================================================
468 // some common dnd related code
469 // ============================================================================
471 #if wxUSE_DRAG_AND_DROP
475 // ----------------------------------------------------------------------------
477 // ----------------------------------------------------------------------------
479 // NB: we can't use "new" in ctor initializer lists because this provokes an
480 // internal compiler error with VC++ 5.0 (hey, even gcc compiles this!),
481 // so use SetDataObject() instead
483 wxTextDropTarget::wxTextDropTarget()
485 SetDataObject(new wxTextDataObject
);
488 wxDragResult
wxTextDropTarget::OnData(wxCoord x
, wxCoord y
, wxDragResult def
)
493 wxTextDataObject
*dobj
= (wxTextDataObject
*)m_dataObject
;
494 return OnDropText( x
, y
, dobj
->GetText() ) ? def
: wxDragNone
;
497 // ----------------------------------------------------------------------------
499 // ----------------------------------------------------------------------------
501 wxFileDropTarget::wxFileDropTarget()
503 SetDataObject(new wxFileDataObject
);
506 wxDragResult
wxFileDropTarget::OnData(wxCoord x
, wxCoord y
, wxDragResult def
)
511 wxFileDataObject
*dobj
= (wxFileDataObject
*)m_dataObject
;
512 return OnDropFiles( x
, y
, dobj
->GetFilenames() ) ? def
: wxDragNone
;
515 #endif // wxUSE_DRAG_AND_DROP
517 #endif // wxUSE_DATAOBJ