]> git.saurik.com Git - wxWidgets.git/blob - src/common/dobjcmn.cpp
controls can now be put in the toolbars (MSW only so far, preliminary version)
[wxWidgets.git] / src / common / dobjcmn.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: common/dobjcmn.cpp
3 // Purpose: implementation of data object methods common to all platforms
4 // Author: Vadim Zeitlin, Robert Roebling
5 // Modified by:
6 // Created: 19.10.99
7 // RCS-ID: $Id$
8 // Copyright: (c) wxWindows Team
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "dataobjbase.h"
22 #endif
23
24 #include "wx/wxprec.h"
25
26 #ifdef __BORLANDC__
27 #pragma hdrstop
28 #endif
29
30 #ifndef WX_PRECOMP
31 #include "wx/app.h"
32 #include "wx/debug.h"
33 #endif // WX_PRECOMP
34
35 #include "wx/dataobj.h"
36
37 // ----------------------------------------------------------------------------
38 // lists
39 // ----------------------------------------------------------------------------
40
41 #include "wx/listimpl.cpp"
42
43 WX_DEFINE_LIST(wxSimpleDataObjectList);
44
45 // ----------------------------------------------------------------------------
46 // globals
47 // ----------------------------------------------------------------------------
48
49 static wxDataFormat dataFormatInvalid;
50 const wxDataFormat& wxFormatInvalid = dataFormatInvalid;
51
52 // ============================================================================
53 // implementation
54 // ============================================================================
55
56 // ----------------------------------------------------------------------------
57 // wxDataObjectBase
58 // ----------------------------------------------------------------------------
59
60 wxDataObjectBase::~wxDataObjectBase()
61 {
62 }
63
64 // ----------------------------------------------------------------------------
65 // wxDataObjectComposite
66 // ----------------------------------------------------------------------------
67
68 wxDataObjectSimple *
69 wxDataObjectComposite::GetObject(const wxDataFormat& format) const
70 {
71 wxSimpleDataObjectList::Node *node = m_dataObjects.GetFirst();
72 while ( node )
73 {
74 wxDataObjectSimple *dataObj = node->GetData();
75
76 if ( dataObj->GetFormat() == format )
77 {
78 return dataObj;
79 }
80
81 node = node->GetNext();
82 }
83
84 return (wxDataObjectSimple *)NULL;
85 }
86
87 void wxDataObjectComposite::Add(wxDataObjectSimple *dataObject, bool preferred)
88 {
89 if ( preferred )
90 m_preferred = m_dataObjects.GetCount();
91
92 m_dataObjects.Append( dataObject );
93 }
94
95 wxDataFormat
96 wxDataObjectComposite::GetPreferredFormat(Direction WXUNUSED(dir)) const
97 {
98 wxSimpleDataObjectList::Node *node = m_dataObjects.Item( m_preferred );
99
100 wxCHECK_MSG( node, wxFormatInvalid, wxT("no preferred format") );
101
102 wxDataObjectSimple* dataObj = node->GetData();
103
104 return dataObj->GetFormat();
105 }
106
107 size_t wxDataObjectComposite::GetFormatCount(Direction WXUNUSED(dir)) const
108 {
109 // TODO what about the Get/Set only formats?
110 return m_dataObjects.GetCount();
111 }
112
113 void wxDataObjectComposite::GetAllFormats(wxDataFormat *formats,
114 Direction WXUNUSED(dir)) const
115 {
116 size_t n = 0;
117 wxSimpleDataObjectList::Node *node;
118 for ( node = m_dataObjects.GetFirst(); node; node = node->GetNext() )
119 {
120 // TODO if ( !outputOnlyToo ) && this one counts ...
121 formats[n++] = node->GetData()->GetFormat();
122 }
123 }
124
125 size_t wxDataObjectComposite::GetDataSize(const wxDataFormat& format) const
126 {
127 wxDataObjectSimple *dataObj = GetObject(format);
128
129 wxCHECK_MSG( dataObj, 0,
130 wxT("unsupported format in wxDataObjectComposite"));
131
132 return dataObj->GetDataSize();
133 }
134
135 bool wxDataObjectComposite::GetDataHere(const wxDataFormat& format,
136 void *buf) const
137 {
138 wxDataObjectSimple *dataObj = GetObject(format);
139
140 wxCHECK_MSG( dataObj, FALSE,
141 wxT("unsupported format in wxDataObjectComposite"));
142
143 return dataObj->GetDataHere(buf);
144 }
145
146 bool wxDataObjectComposite::SetData(const wxDataFormat& format,
147 size_t len,
148 const void *buf)
149 {
150 wxDataObjectSimple *dataObj = GetObject(format);
151
152 wxCHECK_MSG( dataObj, FALSE,
153 wxT("unsupported format in wxDataObjectComposite"));
154
155 return dataObj->SetData(len, buf);
156 }
157
158 // ----------------------------------------------------------------------------
159 // wxTextDataObject
160 // ----------------------------------------------------------------------------
161
162 size_t wxTextDataObject::GetDataSize() const
163 {
164 return GetTextLength();
165 }
166
167 bool wxTextDataObject::GetDataHere(void *buf) const
168 {
169 strcpy((char *)buf, GetText().mb_str());
170
171 return TRUE;
172 }
173
174 bool wxTextDataObject::SetData(size_t WXUNUSED(len), const void *buf)
175 {
176 SetText(wxString((const char *)buf));
177
178 return TRUE;
179 }
180
181 // ----------------------------------------------------------------------------
182 // wxFileDataObjectBase
183 // ----------------------------------------------------------------------------
184
185 // VZ: I don't need this in MSW finally, so if it is needed in wxGTK, it should
186 // be moved to gtk/dataobj.cpp
187 #if 0
188
189 wxString wxFileDataObjectBase::GetFilenames() const
190 {
191 wxString str;
192 size_t count = m_filenames.GetCount();
193 for ( size_t n = 0; n < count; n++ )
194 {
195 str << m_filenames[n] << wxT('\0');
196 }
197
198 return str;
199 }
200
201 void wxFileDataObjectBase::SetFilenames(const wxChar* filenames)
202 {
203 m_filenames.Empty();
204
205 wxString current;
206 for ( const wxChar *pc = filenames; ; pc++ )
207 {
208 if ( *pc )
209 {
210 current += *pc;
211 }
212 else
213 {
214 if ( !current )
215 {
216 // 2 consecutive NULs - this is the end of the string
217 break;
218 }
219
220 m_filenames.Add(current);
221 current.Empty();
222 }
223 }
224 }
225
226 #endif // 0
227
228 // ----------------------------------------------------------------------------
229 // wxCustomDataObject
230 // ----------------------------------------------------------------------------
231
232 wxCustomDataObject::wxCustomDataObject(const wxDataFormat& format)
233 : wxDataObjectSimple(format)
234 {
235 m_data = (void *)NULL;
236 }
237
238 wxCustomDataObject::~wxCustomDataObject()
239 {
240 Free();
241 }
242
243 void wxCustomDataObject::TakeData(size_t size, void *data)
244 {
245 Free();
246
247 m_size = size;
248 m_data = data;
249 }
250
251 void *wxCustomDataObject::Alloc(size_t size)
252 {
253 return (void *)new char[size];
254 }
255
256 void wxCustomDataObject::Free()
257 {
258 delete [] m_data;
259 m_size = 0;
260 m_data = (void *)NULL;
261 }
262
263 size_t wxCustomDataObject::GetDataSize() const
264 {
265 return GetSize();
266 }
267
268 bool wxCustomDataObject::GetDataHere(void *buf) const
269 {
270 void *data = GetData();
271 if ( !data )
272 return FALSE;
273
274 memcpy(buf, data, GetSize());
275
276 return TRUE;
277 }
278
279 bool wxCustomDataObject::SetData(size_t size, const void *buf)
280 {
281 Free();
282
283 m_data = Alloc(size);
284 if ( !m_data )
285 return FALSE;
286
287 memcpy(m_data, buf, m_size = size);
288
289 return TRUE;
290 }
291
292 // ============================================================================
293 // some common dnd related code
294 // ============================================================================
295
296 #if wxUSE_DRAG_AND_DROP
297
298 #include "wx/dnd.h"
299
300 // ----------------------------------------------------------------------------
301 // wxTextDropTarget
302 // ----------------------------------------------------------------------------
303
304 // NB: we can't use "new" in ctor initializer lists because this provokes an
305 // internal compiler error with VC++ 5.0 (hey, even gcc compiles this!),
306 // so use SetDataObject() instead
307
308 wxTextDropTarget::wxTextDropTarget()
309 {
310 SetDataObject(new wxTextDataObject);
311 }
312
313 wxDragResult wxTextDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult def)
314 {
315 if ( !GetData() )
316 return wxDragNone;
317
318 wxTextDataObject *dobj = (wxTextDataObject *)m_dataObject;
319 return OnDropText(x, y, dobj->GetText()) ? def : wxDragNone;
320 }
321
322 // ----------------------------------------------------------------------------
323 // wxFileDropTarget
324 // ----------------------------------------------------------------------------
325
326 wxFileDropTarget::wxFileDropTarget()
327 {
328 SetDataObject(new wxFileDataObject);
329 }
330
331 wxDragResult wxFileDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult def)
332 {
333 if ( !GetData() )
334 return wxDragNone;
335
336 wxFileDataObject *dobj = (wxFileDataObject *)m_dataObject;
337 return OnDropFiles(x, y, dobj->GetFilenames()) ? def : wxDragNone;
338 }
339
340 #endif
341