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