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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "dataobjbase.h"
24 #include "wx/wxprec.h"
37 #include "wx/dataobj.h"
39 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
43 #include "wx/listimpl.cpp"
45 WX_DEFINE_LIST(wxSimpleDataObjectList
);
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 static wxDataFormat dataFormatInvalid
;
52 WXDLLEXPORT
const wxDataFormat
& wxFormatInvalid
= dataFormatInvalid
;
54 // ============================================================================
56 // ============================================================================
58 // ----------------------------------------------------------------------------
60 // ----------------------------------------------------------------------------
62 wxDataObjectBase::~wxDataObjectBase()
66 bool wxDataObjectBase::IsSupported(const wxDataFormat
& format
,
69 size_t nFormatCount
= GetFormatCount(dir
);
70 if ( nFormatCount
== 1 )
72 return format
== GetPreferredFormat(dir
);
76 wxDataFormat
*formats
= new wxDataFormat
[nFormatCount
];
77 GetAllFormats(formats
, dir
);
80 for ( n
= 0; n
< nFormatCount
; n
++ )
82 if ( formats
[n
] == format
)
89 return n
< nFormatCount
;
93 // ----------------------------------------------------------------------------
94 // wxDataObjectComposite
95 // ----------------------------------------------------------------------------
97 wxDataObjectComposite::wxDataObjectComposite()
102 wxDataObjectComposite::~wxDataObjectComposite()
104 WX_CLEAR_LIST(wxSimpleDataObjectList
, m_dataObjects
);
108 wxDataObjectComposite::GetObject(const wxDataFormat
& format
) const
110 wxSimpleDataObjectList::compatibility_iterator node
= m_dataObjects
.GetFirst();
113 wxDataObjectSimple
*dataObj
= node
->GetData();
115 if ( dataObj
->GetFormat() == format
)
120 node
= node
->GetNext();
123 return (wxDataObjectSimple
*)NULL
;
126 void wxDataObjectComposite::Add(wxDataObjectSimple
*dataObject
, bool preferred
)
129 m_preferred
= m_dataObjects
.GetCount();
131 m_dataObjects
.Append( dataObject
);
135 wxDataObjectComposite::GetPreferredFormat(Direction
WXUNUSED(dir
)) const
137 wxSimpleDataObjectList::compatibility_iterator node
= m_dataObjects
.Item( m_preferred
);
139 wxCHECK_MSG( node
, wxFormatInvalid
, wxT("no preferred format") );
141 wxDataObjectSimple
* dataObj
= node
->GetData();
143 return dataObj
->GetFormat();
146 #if defined(__WXMSW__)
148 size_t wxDataObjectComposite::GetBufferOffset( const wxDataFormat
& format
)
150 wxDataObjectSimple
*dataObj
= GetObject(format
);
152 wxCHECK_MSG( dataObj
, 0,
153 wxT("unsupported format in wxDataObjectComposite"));
155 return dataObj
->GetBufferOffset( format
);
159 const void* wxDataObjectComposite::GetSizeFromBuffer( const void* buffer
,
161 const wxDataFormat
& format
)
163 wxDataObjectSimple
*dataObj
= GetObject(format
);
165 wxCHECK_MSG( dataObj
, NULL
,
166 wxT("unsupported format in wxDataObjectComposite"));
168 return dataObj
->GetSizeFromBuffer( buffer
, size
, format
);
172 void* wxDataObjectComposite::SetSizeInBuffer( void* buffer
, size_t size
,
173 const wxDataFormat
& format
)
175 wxDataObjectSimple
*dataObj
= GetObject(format
);
177 wxCHECK_MSG( dataObj
, NULL
,
178 wxT("unsupported format in wxDataObjectComposite"));
180 return dataObj
->SetSizeInBuffer( buffer
, size
, format
);
185 size_t wxDataObjectComposite::GetFormatCount(Direction
WXUNUSED(dir
)) const
187 // TODO what about the Get/Set only formats?
188 return m_dataObjects
.GetCount();
191 void wxDataObjectComposite::GetAllFormats(wxDataFormat
*formats
,
192 Direction
WXUNUSED(dir
)) const
195 wxSimpleDataObjectList::compatibility_iterator node
;
196 for ( node
= m_dataObjects
.GetFirst(); node
; node
= node
->GetNext() )
198 // TODO if ( !outputOnlyToo ) && this one counts ...
199 formats
[n
++] = node
->GetData()->GetFormat();
203 size_t wxDataObjectComposite::GetDataSize(const wxDataFormat
& format
) const
205 wxDataObjectSimple
*dataObj
= GetObject(format
);
207 wxCHECK_MSG( dataObj
, 0,
208 wxT("unsupported format in wxDataObjectComposite"));
210 return dataObj
->GetDataSize();
213 bool wxDataObjectComposite::GetDataHere(const wxDataFormat
& format
,
216 wxDataObjectSimple
*dataObj
= GetObject(format
);
218 wxCHECK_MSG( dataObj
, false,
219 wxT("unsupported format in wxDataObjectComposite"));
221 return dataObj
->GetDataHere(buf
);
224 bool wxDataObjectComposite::SetData(const wxDataFormat
& format
,
228 wxDataObjectSimple
*dataObj
= GetObject(format
);
230 wxCHECK_MSG( dataObj
, false,
231 wxT("unsupported format in wxDataObjectComposite"));
233 return dataObj
->SetData(len
, buf
);
236 // ----------------------------------------------------------------------------
238 // ----------------------------------------------------------------------------
240 #if defined(__WXGTK20__) && wxUSE_UNICODE
242 static inline wxMBConv
& GetConv(const wxDataFormat
& format
)
244 // use UTF8 for wxDF_UNICODETEXT and UCS4 for wxDF_TEXT
245 return format
== wxDF_UNICODETEXT
? wxConvUTF8
: wxConvLibc
;
248 size_t wxTextDataObject::GetDataSize(const wxDataFormat
& format
) const
250 wxCharBuffer buffer
= GetConv(format
).cWX2MB( GetText().c_str() );
251 return buffer
? strlen(buffer
) + 1 : 0;
254 bool wxTextDataObject::GetDataHere(const wxDataFormat
& format
, void *buf
) const
256 wxCharBuffer buffer
= GetConv(format
).cWX2MB( GetText().c_str() );
260 strcpy( (char*) buf
, buffer
);
265 bool wxTextDataObject::SetData(const wxDataFormat
& format
,
266 size_t WXUNUSED(len
), const void *buf
)
268 wxWCharBuffer buffer
= GetConv(format
).cMB2WX((const char *)buf
);
277 #elif wxUSE_UNICODE && defined(__WXMAC__)
279 size_t wxTextDataObject::GetDataSize(const wxDataFormat
& format
) const
281 if (format
== wxDF_UNICODETEXT
)
283 // host native is UTF16
284 wxMBConvUTF16 converter
;
285 return converter
.WC2MB( NULL
, GetText().c_str() , 0 ) + 2; // add space for trailing unichar 0
289 wxCharBuffer buffer
= wxConvLibc
.cWX2MB( GetText().c_str() );
290 // in some cases "buffer" is null (e.g. Mac OS X)
291 return buffer
? strlen( (const char*) buffer
) + 1 : 0;
295 bool wxTextDataObject::GetDataHere(const wxDataFormat
& format
, void *buf
) const
297 if (format
== wxDF_UNICODETEXT
)
299 // host native is UTF16
300 wxMBConvUTF16 converter
;
301 size_t len
= converter
.WC2MB( NULL
, GetText().c_str() , 0 ) ;
302 wxCharBuffer buffer
= converter
.cWX2MB( GetText().c_str() );
303 memcpy( (char*) buf
, (const char*) buffer
, len
+ 2); // trailing unichar 0
307 wxCharBuffer buffer
= wxConvLibc
.cWX2MB( GetText().c_str() );
308 // in some cases "buffer" is null (e.g. Mac OS X)
310 strcpy( (char*) buf
, (const char*) buffer
);
316 bool wxTextDataObject::SetData(const wxDataFormat
& format
,
317 size_t WXUNUSED(len
), const void *buf
)
319 if (format
== wxDF_UNICODETEXT
)
321 // host native is UTF16
322 wxMBConvUTF16 converter
;
323 SetText( converter
.cMB2WX( (const char*) buf
) );
326 SetText( wxConvLibc
.cMB2WX( (const char*) buf
) );
333 size_t wxTextDataObject::GetDataSize() const
335 return GetTextLength() * sizeof(wxChar
);
338 bool wxTextDataObject::GetDataHere(void *buf
) const
340 wxStrcpy((wxChar
*)buf
, GetText().c_str());
345 bool wxTextDataObject::SetData(size_t WXUNUSED(len
), const void *buf
)
347 SetText(wxString((const wxChar
*)buf
));
354 // ----------------------------------------------------------------------------
355 // wxFileDataObjectBase
356 // ----------------------------------------------------------------------------
358 // VZ: I don't need this in MSW finally, so if it is needed in wxGTK, it should
359 // be moved to gtk/dataobj.cpp
362 wxString
wxFileDataObjectBase::GetFilenames() const
365 size_t count
= m_filenames
.GetCount();
366 for ( size_t n
= 0; n
< count
; n
++ )
368 str
<< m_filenames
[n
] << wxT('\0');
374 void wxFileDataObjectBase::SetFilenames(const wxChar
* filenames
)
379 for ( const wxChar
*pc
= filenames
; ; pc
++ )
389 // 2 consecutive NULs - this is the end of the string
393 m_filenames
.Add(current
);
401 // ----------------------------------------------------------------------------
402 // wxCustomDataObject
403 // ----------------------------------------------------------------------------
405 wxCustomDataObject::wxCustomDataObject(const wxDataFormat
& format
)
406 : wxDataObjectSimple(format
)
408 m_data
= (void *)NULL
;
411 wxCustomDataObject::~wxCustomDataObject()
416 void wxCustomDataObject::TakeData(size_t size
, void *data
)
424 void *wxCustomDataObject::Alloc(size_t size
)
426 return (void *)new char[size
];
429 void wxCustomDataObject::Free()
431 delete [] (char *)m_data
;
433 m_data
= (void *)NULL
;
436 size_t wxCustomDataObject::GetDataSize() const
441 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
);
460 memcpy(m_data
, buf
, m_size
= size
);
465 // ============================================================================
466 // some common dnd related code
467 // ============================================================================
469 #if wxUSE_DRAG_AND_DROP
473 // ----------------------------------------------------------------------------
475 // ----------------------------------------------------------------------------
477 // NB: we can't use "new" in ctor initializer lists because this provokes an
478 // internal compiler error with VC++ 5.0 (hey, even gcc compiles this!),
479 // so use SetDataObject() instead
481 wxTextDropTarget::wxTextDropTarget()
483 SetDataObject(new wxTextDataObject
);
486 wxDragResult
wxTextDropTarget::OnData(wxCoord x
, wxCoord y
, wxDragResult def
)
491 wxTextDataObject
*dobj
= (wxTextDataObject
*)m_dataObject
;
492 return OnDropText(x
, y
, dobj
->GetText()) ? def
: wxDragNone
;
495 // ----------------------------------------------------------------------------
497 // ----------------------------------------------------------------------------
499 wxFileDropTarget::wxFileDropTarget()
501 SetDataObject(new wxFileDataObject
);
504 wxDragResult
wxFileDropTarget::OnData(wxCoord x
, wxCoord y
, wxDragResult def
)
509 wxFileDataObject
*dobj
= (wxFileDataObject
*)m_dataObject
;
510 return OnDropFiles(x
, y
, dobj
->GetFilenames()) ? def
: wxDragNone
;
513 #endif // wxUSE_DRAG_AND_DROP
515 #endif // wxUSE_DATAOBJ