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) wxWindows Team
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
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()
101 m_dataObjects
.DeleteContents(TRUE
);
105 wxDataObjectComposite::GetObject(const wxDataFormat
& format
) const
107 wxSimpleDataObjectList::Node
*node
= m_dataObjects
.GetFirst();
110 wxDataObjectSimple
*dataObj
= node
->GetData();
112 if ( dataObj
->GetFormat() == format
)
117 node
= node
->GetNext();
120 return (wxDataObjectSimple
*)NULL
;
123 void wxDataObjectComposite::Add(wxDataObjectSimple
*dataObject
, bool preferred
)
126 m_preferred
= m_dataObjects
.GetCount();
128 m_dataObjects
.Append( dataObject
);
132 wxDataObjectComposite::GetPreferredFormat(Direction
WXUNUSED(dir
)) const
134 wxSimpleDataObjectList::Node
*node
= m_dataObjects
.Item( m_preferred
);
136 wxCHECK_MSG( node
, wxFormatInvalid
, wxT("no preferred format") );
138 wxDataObjectSimple
* dataObj
= node
->GetData();
140 return dataObj
->GetFormat();
143 #if defined(__WXMSW__)
145 size_t wxDataObjectComposite::GetBufferOffset( const wxDataFormat
& format
)
147 wxDataObjectSimple
*dataObj
= GetObject(format
);
149 wxCHECK_MSG( dataObj
, FALSE
,
150 wxT("unsupported format in wxDataObjectComposite"));
152 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
, FALSE
,
162 wxT("unsupported format in wxDataObjectComposite"));
164 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
, FALSE
,
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::Node
*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 return dataObj
->SetData(len
, buf
);
231 // ----------------------------------------------------------------------------
233 // ----------------------------------------------------------------------------
235 size_t wxTextDataObject::GetDataSize() const
237 return GetTextLength() * sizeof(wxChar
);
240 bool wxTextDataObject::GetDataHere(void *buf
) const
242 wxStrcpy((wxChar
*)buf
, GetText().c_str());
247 bool wxTextDataObject::SetData(size_t WXUNUSED(len
), const void *buf
)
249 SetText(wxString((const wxChar
*)buf
));
254 // ----------------------------------------------------------------------------
255 // wxFileDataObjectBase
256 // ----------------------------------------------------------------------------
258 // VZ: I don't need this in MSW finally, so if it is needed in wxGTK, it should
259 // be moved to gtk/dataobj.cpp
262 wxString
wxFileDataObjectBase::GetFilenames() const
265 size_t count
= m_filenames
.GetCount();
266 for ( size_t n
= 0; n
< count
; n
++ )
268 str
<< m_filenames
[n
] << wxT('\0');
274 void wxFileDataObjectBase::SetFilenames(const wxChar
* filenames
)
279 for ( const wxChar
*pc
= filenames
; ; pc
++ )
289 // 2 consecutive NULs - this is the end of the string
293 m_filenames
.Add(current
);
301 // ----------------------------------------------------------------------------
302 // wxCustomDataObject
303 // ----------------------------------------------------------------------------
305 wxCustomDataObject::wxCustomDataObject(const wxDataFormat
& format
)
306 : wxDataObjectSimple(format
)
308 m_data
= (void *)NULL
;
311 wxCustomDataObject::~wxCustomDataObject()
316 void wxCustomDataObject::TakeData(size_t size
, void *data
)
324 void *wxCustomDataObject::Alloc(size_t size
)
326 return (void *)new char[size
];
329 void wxCustomDataObject::Free()
331 delete [] (char *)m_data
;
333 m_data
= (void *)NULL
;
336 size_t wxCustomDataObject::GetDataSize() const
341 bool wxCustomDataObject::GetDataHere(void *buf
) const
343 void *data
= GetData();
347 memcpy(buf
, data
, GetSize());
352 bool wxCustomDataObject::SetData(size_t size
, const void *buf
)
356 m_data
= Alloc(size
);
360 memcpy(m_data
, buf
, m_size
= size
);
365 // ============================================================================
366 // some common dnd related code
367 // ============================================================================
369 #if wxUSE_DRAG_AND_DROP
373 // ----------------------------------------------------------------------------
375 // ----------------------------------------------------------------------------
377 // NB: we can't use "new" in ctor initializer lists because this provokes an
378 // internal compiler error with VC++ 5.0 (hey, even gcc compiles this!),
379 // so use SetDataObject() instead
381 wxTextDropTarget::wxTextDropTarget()
383 SetDataObject(new wxTextDataObject
);
386 wxDragResult
wxTextDropTarget::OnData(wxCoord x
, wxCoord y
, wxDragResult def
)
391 wxTextDataObject
*dobj
= (wxTextDataObject
*)m_dataObject
;
392 return OnDropText(x
, y
, dobj
->GetText()) ? def
: wxDragNone
;
395 // ----------------------------------------------------------------------------
397 // ----------------------------------------------------------------------------
399 wxFileDropTarget::wxFileDropTarget()
401 SetDataObject(new wxFileDataObject
);
404 wxDragResult
wxFileDropTarget::OnData(wxCoord x
, wxCoord y
, wxDragResult def
)
409 wxFileDataObject
*dobj
= (wxFileDataObject
*)m_dataObject
;
410 return OnDropFiles(x
, y
, dobj
->GetFilenames()) ? def
: wxDragNone
;
413 #endif // wxUSE_DRAG_AND_DROP
415 #endif // wxUSE_DATAOBJ