1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: 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 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #include "wx/wxprec.h"
33 #include "wx/dataobj.h"
35 // ----------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------
39 #include "wx/listimpl.cpp"
41 WX_DEFINE_LIST(wxSimpleDataObjectList
)
43 // ----------------------------------------------------------------------------
45 // ----------------------------------------------------------------------------
47 static wxDataFormat dataFormatInvalid
;
48 WXDLLEXPORT
const wxDataFormat
& wxFormatInvalid
= dataFormatInvalid
;
50 // ============================================================================
52 // ============================================================================
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 wxDataObjectBase::~wxDataObjectBase()
62 bool wxDataObjectBase::IsSupported(const wxDataFormat
& format
,
65 size_t nFormatCount
= GetFormatCount(dir
);
66 if ( nFormatCount
== 1 )
68 return format
== GetPreferredFormat(dir
);
72 wxDataFormat
*formats
= new wxDataFormat
[nFormatCount
];
73 GetAllFormats(formats
, dir
);
76 for ( n
= 0; n
< nFormatCount
; n
++ )
78 if ( formats
[n
] == format
)
85 return n
< nFormatCount
;
89 // ----------------------------------------------------------------------------
90 // wxDataObjectComposite
91 // ----------------------------------------------------------------------------
93 wxDataObjectComposite::wxDataObjectComposite()
98 wxDataObjectComposite::~wxDataObjectComposite()
100 WX_CLEAR_LIST(wxSimpleDataObjectList
, m_dataObjects
);
104 wxDataObjectComposite::GetObject(const wxDataFormat
& format
) const
106 wxSimpleDataObjectList::compatibility_iterator node
= m_dataObjects
.GetFirst();
109 wxDataObjectSimple
*dataObj
= node
->GetData();
111 if ( dataObj
->GetFormat() == format
)
116 node
= node
->GetNext();
119 return (wxDataObjectSimple
*)NULL
;
122 void wxDataObjectComposite::Add(wxDataObjectSimple
*dataObject
, bool preferred
)
125 m_preferred
= m_dataObjects
.GetCount();
127 m_dataObjects
.Append( dataObject
);
131 wxDataObjectComposite::GetPreferredFormat(Direction
WXUNUSED(dir
)) const
133 wxSimpleDataObjectList::compatibility_iterator node
= m_dataObjects
.Item( m_preferred
);
135 wxCHECK_MSG( node
, wxFormatInvalid
, wxT("no preferred format") );
137 wxDataObjectSimple
* dataObj
= node
->GetData();
139 return dataObj
->GetFormat();
142 #if defined(__WXMSW__)
144 size_t wxDataObjectComposite::GetBufferOffset( const wxDataFormat
& format
)
146 wxDataObjectSimple
*dataObj
= GetObject(format
);
148 wxCHECK_MSG( dataObj
, 0,
149 wxT("unsupported format in wxDataObjectComposite"));
151 return dataObj
->GetBufferOffset( format
);
155 const void* wxDataObjectComposite::GetSizeFromBuffer( const void* buffer
,
157 const wxDataFormat
& format
)
159 wxDataObjectSimple
*dataObj
= GetObject(format
);
161 wxCHECK_MSG( dataObj
, NULL
,
162 wxT("unsupported format in wxDataObjectComposite"));
164 return dataObj
->GetSizeFromBuffer( buffer
, size
, format
);
168 void* wxDataObjectComposite::SetSizeInBuffer( void* buffer
, size_t size
,
169 const wxDataFormat
& format
)
171 wxDataObjectSimple
*dataObj
= GetObject(format
);
173 wxCHECK_MSG( dataObj
, NULL
,
174 wxT("unsupported format in wxDataObjectComposite"));
176 return dataObj
->SetSizeInBuffer( buffer
, size
, format
);
181 size_t wxDataObjectComposite::GetFormatCount(Direction
WXUNUSED(dir
)) const
183 // TODO what about the Get/Set only formats?
184 return m_dataObjects
.GetCount();
187 void wxDataObjectComposite::GetAllFormats(wxDataFormat
*formats
,
188 Direction
WXUNUSED(dir
)) const
191 wxSimpleDataObjectList::compatibility_iterator node
;
192 for ( node
= m_dataObjects
.GetFirst(); node
; node
= node
->GetNext() )
194 // TODO if ( !outputOnlyToo ) && this one counts ...
195 formats
[n
++] = node
->GetData()->GetFormat();
199 size_t wxDataObjectComposite::GetDataSize(const wxDataFormat
& format
) const
201 wxDataObjectSimple
*dataObj
= GetObject(format
);
203 wxCHECK_MSG( dataObj
, 0,
204 wxT("unsupported format in wxDataObjectComposite"));
206 return dataObj
->GetDataSize();
209 bool wxDataObjectComposite::GetDataHere(const wxDataFormat
& format
,
212 wxDataObjectSimple
*dataObj
= GetObject(format
);
214 wxCHECK_MSG( dataObj
, false,
215 wxT("unsupported format in wxDataObjectComposite"));
217 return dataObj
->GetDataHere(buf
);
220 bool wxDataObjectComposite::SetData(const wxDataFormat
& format
,
224 wxDataObjectSimple
*dataObj
= GetObject(format
);
226 wxCHECK_MSG( dataObj
, false,
227 wxT("unsupported format in wxDataObjectComposite"));
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() );
247 return buffer
? strlen(buffer
) + 1 : 0;
250 bool wxTextDataObject::GetDataHere(const wxDataFormat
& format
, void *buf
) const
252 wxCharBuffer buffer
= GetConv(format
).cWX2MB( GetText().c_str() );
256 strcpy( (char*) buf
, buffer
);
261 bool wxTextDataObject::SetData(const wxDataFormat
& format
,
262 size_t WXUNUSED(len
), const void *buf
)
264 wxWCharBuffer buffer
= GetConv(format
).cMB2WX((const char *)buf
);
273 #elif wxUSE_UNICODE && defined(__WXMAC__)
275 static wxMBConvUTF16 sUTF16Converter
;
277 static inline wxMBConv
& GetConv(const wxDataFormat
& format
)
279 return format
== wxDF_UNICODETEXT
? (wxMBConv
&) sUTF16Converter
280 : (wxMBConv
&) wxConvLocal
;
283 size_t wxTextDataObject::GetDataSize(const wxDataFormat
& format
) const
285 size_t len
= GetConv(format
).WC2MB( NULL
, GetText().c_str() , 0 )
286 + ( format
== wxDF_UNICODETEXT
? 2 : 1 ) ;
290 bool wxTextDataObject::GetDataHere(const wxDataFormat
& format
, void *buf
) const
292 wxCharBuffer buffer
= GetConv(format
).cWX2MB( GetText().c_str() );
296 size_t len
= GetConv(format
).WC2MB( NULL
, GetText().c_str() , 0 )
297 + ( format
== wxDF_UNICODETEXT
? 2 : 1 ) ;
299 memcpy( (char*) buf
, (const char*) buffer
, len
); // trailing (uni)char 0
304 bool wxTextDataObject::SetData(const wxDataFormat
& format
,
305 size_t WXUNUSED(len
), const void *buf
)
307 wxWCharBuffer buffer
= GetConv(format
).cMB2WX((const char *)buf
);
318 size_t wxTextDataObject::GetDataSize() const
320 return GetTextLength() * sizeof(wxChar
);
323 bool wxTextDataObject::GetDataHere(void *buf
) const
325 wxStrcpy((wxChar
*)buf
, GetText().c_str());
330 bool wxTextDataObject::SetData(size_t WXUNUSED(len
), const void *buf
)
332 SetText(wxString((const wxChar
*)buf
));
339 // ----------------------------------------------------------------------------
340 // wxFileDataObjectBase
341 // ----------------------------------------------------------------------------
343 // VZ: I don't need this in MSW finally, so if it is needed in wxGTK, it should
344 // be moved to gtk/dataobj.cpp
347 wxString
wxFileDataObjectBase::GetFilenames() const
350 size_t count
= m_filenames
.GetCount();
351 for ( size_t n
= 0; n
< count
; n
++ )
353 str
<< m_filenames
[n
] << wxT('\0');
359 void wxFileDataObjectBase::SetFilenames(const wxChar
* filenames
)
364 for ( const wxChar
*pc
= filenames
; ; pc
++ )
374 // 2 consecutive NULs - this is the end of the string
378 m_filenames
.Add(current
);
386 // ----------------------------------------------------------------------------
387 // wxCustomDataObject
388 // ----------------------------------------------------------------------------
390 wxCustomDataObject::wxCustomDataObject(const wxDataFormat
& format
)
391 : wxDataObjectSimple(format
)
393 m_data
= (void *)NULL
;
396 wxCustomDataObject::~wxCustomDataObject()
401 void wxCustomDataObject::TakeData(size_t size
, void *data
)
409 void *wxCustomDataObject::Alloc(size_t size
)
411 return (void *)new char[size
];
414 void wxCustomDataObject::Free()
416 delete [] (char *)m_data
;
418 m_data
= (void *)NULL
;
421 size_t wxCustomDataObject::GetDataSize() const
426 bool wxCustomDataObject::GetDataHere(void *buf
) const
428 void *data
= GetData();
432 memcpy(buf
, data
, GetSize());
437 bool wxCustomDataObject::SetData(size_t size
, const void *buf
)
441 m_data
= Alloc(size
);
445 memcpy(m_data
, buf
, m_size
= size
);
450 // ============================================================================
451 // some common dnd related code
452 // ============================================================================
454 #if wxUSE_DRAG_AND_DROP
458 // ----------------------------------------------------------------------------
460 // ----------------------------------------------------------------------------
462 // NB: we can't use "new" in ctor initializer lists because this provokes an
463 // internal compiler error with VC++ 5.0 (hey, even gcc compiles this!),
464 // so use SetDataObject() instead
466 wxTextDropTarget::wxTextDropTarget()
468 SetDataObject(new wxTextDataObject
);
471 wxDragResult
wxTextDropTarget::OnData(wxCoord x
, wxCoord y
, wxDragResult def
)
476 wxTextDataObject
*dobj
= (wxTextDataObject
*)m_dataObject
;
477 return OnDropText(x
, y
, dobj
->GetText()) ? def
: wxDragNone
;
480 // ----------------------------------------------------------------------------
482 // ----------------------------------------------------------------------------
484 wxFileDropTarget::wxFileDropTarget()
486 SetDataObject(new wxFileDataObject
);
489 wxDragResult
wxFileDropTarget::OnData(wxCoord x
, wxCoord y
, wxDragResult def
)
494 wxFileDataObject
*dobj
= (wxFileDataObject
*)m_dataObject
;
495 return OnDropFiles(x
, y
, dobj
->GetFilenames()) ? def
: wxDragNone
;
498 #endif // wxUSE_DRAG_AND_DROP
500 #endif // wxUSE_DATAOBJ