]>
Commit | Line | Data |
---|---|---|
d14a1e28 RD |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: _dataobj.i | |
3 | // Purpose: SWIG definitions for the Data Object classes | |
4 | // | |
5 | // Author: Robin Dunn | |
6 | // | |
7 | // Created: 31-October-1999 | |
8 | // RCS-ID: $Id$ | |
9 | // Copyright: (c) 2003 by Total Control Software | |
10 | // Licence: wxWindows license | |
11 | ///////////////////////////////////////////////////////////////////////////// | |
12 | ||
13 | // Not a %module | |
14 | ||
15 | ||
16 | //--------------------------------------------------------------------------- | |
17 | ||
18 | %{ | |
19 | #include <wx/dataobj.h> | |
20 | %} | |
21 | ||
22 | //--------------------------------------------------------------------------- | |
23 | %newgroup | |
24 | ||
25 | ||
26 | enum wxDataFormatId | |
27 | { | |
28 | wxDF_INVALID, | |
29 | wxDF_TEXT, | |
30 | wxDF_BITMAP, | |
31 | wxDF_METAFILE, | |
32 | wxDF_SYLK, | |
33 | wxDF_DIF, | |
34 | wxDF_TIFF, | |
35 | wxDF_OEMTEXT, | |
36 | wxDF_DIB, | |
37 | wxDF_PALETTE, | |
38 | wxDF_PENDATA, | |
39 | wxDF_RIFF, | |
40 | wxDF_WAVE, | |
41 | wxDF_UNICODETEXT, | |
42 | wxDF_ENHMETAFILE, | |
43 | wxDF_FILENAME, | |
44 | wxDF_LOCALE, | |
45 | wxDF_PRIVATE, | |
46 | wxDF_HTML, | |
47 | wxDF_MAX, | |
48 | }; | |
49 | ||
50 | ||
51 | class wxDataFormat { | |
52 | public: | |
53 | wxDataFormat( wxDataFormatId type ); | |
54 | %name(CustomDataFormat) wxDataFormat(const wxString& format); | |
55 | ||
56 | ~wxDataFormat(); | |
57 | ||
58 | %nokwargs operator==; | |
59 | %nokwargs operator!=; | |
60 | bool operator==(wxDataFormatId format) const; | |
61 | bool operator!=(wxDataFormatId format) const; | |
62 | bool operator==(const wxDataFormat& format) const; | |
63 | bool operator!=(const wxDataFormat& format) const; | |
64 | ||
65 | void SetType(wxDataFormatId format); | |
66 | wxDataFormatId GetType() const; | |
67 | ||
68 | wxString GetId() const; | |
69 | void SetId(const wxString& format); | |
70 | }; | |
71 | ||
72 | ||
73 | %immutable; | |
74 | const wxDataFormat wxFormatInvalid; | |
75 | %mutable; | |
76 | ||
77 | ||
78 | //--------------------------------------------------------------------------- | |
79 | ||
80 | ||
81 | // wxDataObject represents a piece of data which knows which formats it | |
82 | // supports and knows how to render itself in each of them - GetDataHere(), | |
83 | // and how to restore data from the buffer (SetData()). | |
84 | // | |
85 | // Although this class may be used directly (i.e. custom classes may be | |
86 | // derived from it), in many cases it might be simpler to use either | |
87 | // wxDataObjectSimple or wxDataObjectComposite classes. | |
88 | // | |
89 | // A data object may be "read only", i.e. support only GetData() functions or | |
90 | // "read-write", i.e. support both GetData() and SetData() (in principle, it | |
91 | // might be "write only" too, but this is rare). Moreover, it doesn't have to | |
92 | // support the same formats in Get() and Set() directions: for example, a data | |
93 | // object containing JPEG image might accept BMPs in GetData() because JPEG | |
94 | // image may be easily transformed into BMP but not in SetData(). Accordingly, | |
95 | // all methods dealing with formats take an additional "direction" argument | |
96 | // which is either SET or GET and which tells the function if the format needs | |
97 | // to be supported by SetData() or GetDataHere(). | |
98 | class wxDataObject { | |
99 | public: | |
100 | enum Direction { | |
101 | Get = 0x01, // format is supported by GetDataHere() | |
102 | Set = 0x02, // format is supported by SetData() | |
103 | Both = 0x03 // format is supported by both (unused currently) | |
104 | }; | |
105 | ||
106 | // wxDataObject(); // *** It's an ABC. | |
107 | ~wxDataObject(); | |
108 | ||
109 | // get the best suited format for rendering our data | |
110 | virtual wxDataFormat GetPreferredFormat(Direction dir = Get) const; | |
111 | ||
112 | // get the number of formats we support | |
113 | virtual size_t GetFormatCount(Direction dir = Get) const; | |
114 | ||
dd9f7fea | 115 | // returns True if this format is supported |
d14a1e28 RD |
116 | bool IsSupported(const wxDataFormat& format, Direction dir = Get) const; |
117 | ||
118 | // get the (total) size of data for the given format | |
119 | virtual size_t GetDataSize(const wxDataFormat& format) const; | |
120 | ||
121 | ||
122 | //------------------------------------------------------------------- | |
123 | // TODO: Fix these three methods to do the right Pythonic things... | |
124 | //------------------------------------------------------------------- | |
125 | ||
126 | // return all formats in the provided array (of size GetFormatCount()) | |
127 | virtual void GetAllFormats(wxDataFormat *formats, | |
128 | Direction dir = Get) const; | |
129 | ||
130 | // copy raw data (in the specified format) to the provided buffer, return | |
dd9f7fea | 131 | // True if data copied successfully, False otherwise |
d14a1e28 RD |
132 | virtual bool GetDataHere(const wxDataFormat& format, void *buf) const; |
133 | ||
134 | // get data from the buffer of specified length (in the given format), | |
dd9f7fea | 135 | // return True if the data was read successfully, False otherwise |
d14a1e28 RD |
136 | virtual bool SetData(const wxDataFormat& format, |
137 | size_t len, const void * buf); | |
138 | }; | |
139 | ||
140 | ||
141 | //--------------------------------------------------------------------------- | |
142 | ||
143 | ||
144 | ||
145 | // wxDataObjectSimple is a wxDataObject which only supports one format (in | |
dd9f7fea | 146 | // both Get and Set directions, but you may return False from GetDataHere() or |
d14a1e28 RD |
147 | // SetData() if one of them is not supported). This is the simplest possible |
148 | // wxDataObject implementation. | |
149 | // | |
150 | // This is still an "abstract base class" (although it doesn't have any pure | |
151 | // virtual functions), to use it you should derive from it and implement | |
152 | // GetDataSize(), GetDataHere() and SetData() functions because the base class | |
153 | // versions don't do anything - they just return "not implemented". | |
154 | // | |
155 | // This class should be used when you provide data in only one format (no | |
156 | // conversion to/from other formats), either a standard or a custom one. | |
157 | // Otherwise, you should use wxDataObjectComposite or wxDataObject directly. | |
158 | class wxDataObjectSimple : public wxDataObject { | |
159 | public: | |
160 | wxDataObjectSimple(const wxDataFormat& format = wxFormatInvalid); | |
161 | ||
162 | // get/set the format we support | |
163 | const wxDataFormat& GetFormat(); | |
164 | void SetFormat(const wxDataFormat& format); | |
165 | ||
166 | }; | |
167 | ||
168 | ||
169 | %{ // Create a new class for wxPython to use | |
170 | class wxPyDataObjectSimple : public wxDataObjectSimple { | |
171 | public: | |
172 | wxPyDataObjectSimple(const wxDataFormat& format = wxFormatInvalid) | |
173 | : wxDataObjectSimple(format) {} | |
174 | ||
175 | DEC_PYCALLBACK_SIZET__const(GetDataSize); | |
176 | bool GetDataHere(void *buf) const; | |
177 | bool SetData(size_t len, const void *buf) const; | |
178 | PYPRIVATE; | |
179 | }; | |
180 | ||
181 | IMP_PYCALLBACK_SIZET__const(wxPyDataObjectSimple, wxDataObjectSimple, GetDataSize); | |
182 | ||
183 | bool wxPyDataObjectSimple::GetDataHere(void *buf) const { | |
184 | // We need to get the data for this object and write it to buf. I think | |
185 | // the best way to do this for wxPython is to have the Python method | |
186 | // return either a string or None and then act appropriately with the | |
187 | // C++ version. | |
188 | ||
dd9f7fea | 189 | bool rval = False; |
d14a1e28 RD |
190 | wxPyBeginBlockThreads(); |
191 | if (wxPyCBH_findCallback(m_myInst, "GetDataHere")) { | |
192 | PyObject* ro; | |
193 | ro = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("()")); | |
194 | if (ro) { | |
195 | rval = (ro != Py_None && PyString_Check(ro)); | |
196 | if (rval) | |
197 | memcpy(buf, PyString_AsString(ro), PyString_Size(ro)); | |
198 | Py_DECREF(ro); | |
199 | } | |
200 | } | |
201 | wxPyEndBlockThreads(); | |
202 | return rval; | |
203 | } | |
204 | ||
205 | bool wxPyDataObjectSimple::SetData(size_t len, const void *buf) const{ | |
206 | // For this one we simply need to make a string from buf and len | |
207 | // and send it to the Python method. | |
dd9f7fea | 208 | bool rval = False; |
d14a1e28 RD |
209 | wxPyBeginBlockThreads(); |
210 | if (wxPyCBH_findCallback(m_myInst, "SetData")) { | |
211 | PyObject* data = PyString_FromStringAndSize((char*)buf, len); | |
212 | rval = wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", data)); | |
213 | Py_DECREF(data); | |
214 | } | |
215 | wxPyEndBlockThreads(); | |
216 | return rval; | |
217 | } | |
218 | %} | |
219 | ||
220 | ||
221 | ||
222 | // Now define it for SWIG | |
223 | class wxPyDataObjectSimple : public wxDataObjectSimple { | |
224 | public: | |
225 | %addtofunc wxPyDataObjectSimple "self._setCallbackInfo(self, PyDataObjectSimple)" | |
226 | ||
227 | wxPyDataObjectSimple(const wxDataFormat& format = wxFormatInvalid); | |
228 | void _setCallbackInfo(PyObject* self, PyObject* _class); | |
229 | }; | |
230 | ||
231 | ||
232 | //--------------------------------------------------------------------------- | |
233 | ||
234 | ||
235 | // wxDataObjectComposite is the simplest way to implement wxDataObject | |
236 | // supporting multiple formats. It contains several wxDataObjectSimple and | |
237 | // supports all formats supported by any of them. | |
238 | // | |
239 | class wxDataObjectComposite : public wxDataObject { | |
240 | public: | |
241 | wxDataObjectComposite(); | |
242 | ||
243 | %addtofunc Add "args[1].thisown = 0" | |
dd9f7fea | 244 | void Add(wxDataObjectSimple *dataObject, int preferred = False); |
d14a1e28 RD |
245 | }; |
246 | ||
247 | //--------------------------------------------------------------------------- | |
248 | ||
249 | // wxTextDataObject contains text data | |
250 | class wxTextDataObject : public wxDataObjectSimple { | |
251 | public: | |
252 | wxTextDataObject(const wxString& text = wxPyEmptyString); | |
253 | ||
254 | size_t GetTextLength(); | |
255 | wxString GetText(); | |
256 | void SetText(const wxString& text); | |
257 | }; | |
258 | ||
259 | ||
260 | ||
261 | %{ // Create a new class for wxPython to use | |
262 | class wxPyTextDataObject : public wxTextDataObject { | |
263 | public: | |
264 | wxPyTextDataObject(const wxString& text = wxPyEmptyString) | |
265 | : wxTextDataObject(text) {} | |
266 | ||
267 | DEC_PYCALLBACK_SIZET__const(GetTextLength); | |
268 | DEC_PYCALLBACK_STRING__const(GetText); | |
269 | DEC_PYCALLBACK__STRING(SetText); | |
270 | PYPRIVATE; | |
271 | }; | |
272 | ||
273 | IMP_PYCALLBACK_SIZET__const(wxPyTextDataObject, wxTextDataObject, GetTextLength); | |
274 | IMP_PYCALLBACK_STRING__const(wxPyTextDataObject, wxTextDataObject, GetText); | |
275 | IMP_PYCALLBACK__STRING(wxPyTextDataObject, wxTextDataObject, SetText); | |
276 | ||
277 | %} | |
278 | ||
279 | ||
280 | // Now define it for SWIG | |
281 | class wxPyTextDataObject : public wxTextDataObject { | |
282 | public: | |
283 | %addtofunc wxPyTextDataObject "self._setCallbackInfo(self, PyTextDataObject)" | |
284 | ||
285 | wxPyTextDataObject(const wxString& text = wxPyEmptyString); | |
286 | void _setCallbackInfo(PyObject* self, PyObject* _class); | |
287 | }; | |
288 | ||
289 | //--------------------------------------------------------------------------- | |
290 | ||
291 | // wxBitmapDataObject contains a bitmap | |
292 | class wxBitmapDataObject : public wxDataObjectSimple { | |
293 | public: | |
294 | wxBitmapDataObject(const wxBitmap& bitmap = wxNullBitmap); | |
295 | ||
296 | wxBitmap GetBitmap() const; | |
297 | void SetBitmap(const wxBitmap& bitmap); | |
298 | }; | |
299 | ||
300 | ||
301 | ||
302 | %{ // Create a new class for wxPython to use | |
303 | class wxPyBitmapDataObject : public wxBitmapDataObject { | |
304 | public: | |
305 | wxPyBitmapDataObject(const wxBitmap& bitmap = wxNullBitmap) | |
306 | : wxBitmapDataObject(bitmap) {} | |
307 | ||
308 | wxBitmap GetBitmap() const; | |
309 | void SetBitmap(const wxBitmap& bitmap); | |
310 | PYPRIVATE; | |
311 | }; | |
312 | ||
313 | wxBitmap wxPyBitmapDataObject::GetBitmap() const { | |
314 | wxBitmap* rval = &wxNullBitmap; | |
315 | wxPyBeginBlockThreads(); | |
316 | if (wxPyCBH_findCallback(m_myInst, "GetBitmap")) { | |
317 | PyObject* ro; | |
318 | wxBitmap* ptr; | |
319 | ro = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("()")); | |
320 | if (ro) { | |
321 | if (wxPyConvertSwigPtr(ro, (void **)&ptr, wxT("wxBitmap"))) | |
322 | rval = ptr; | |
323 | Py_DECREF(ro); | |
324 | } | |
325 | } | |
326 | wxPyEndBlockThreads(); | |
327 | return *rval; | |
328 | } | |
329 | ||
330 | void wxPyBitmapDataObject::SetBitmap(const wxBitmap& bitmap) { | |
331 | wxPyBeginBlockThreads(); | |
332 | if (wxPyCBH_findCallback(m_myInst, "SetBitmap")) { | |
dd9f7fea | 333 | PyObject* bo = wxPyConstructObject((void*)&bitmap, wxT("wxBitmap"), False); |
d14a1e28 RD |
334 | wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", bo)); |
335 | Py_DECREF(bo); | |
336 | } | |
337 | wxPyEndBlockThreads(); | |
338 | } | |
339 | %} | |
340 | ||
341 | ||
342 | ||
343 | // Now define it for SWIG | |
344 | class wxPyBitmapDataObject : public wxBitmapDataObject { | |
345 | public: | |
346 | %addtofunc wxPyBitmapDataObject "self._setCallbackInfo(self, PyBitmapDataObject)" | |
347 | ||
348 | wxPyBitmapDataObject(const wxBitmap& bitmap = wxNullBitmap); | |
349 | void _setCallbackInfo(PyObject* self, PyObject* _class); | |
350 | }; | |
351 | ||
352 | //--------------------------------------------------------------------------- | |
353 | ||
354 | ||
355 | // wxFileDataObject contains a list of filenames | |
356 | class wxFileDataObject : public wxDataObjectSimple | |
357 | { | |
358 | public: | |
359 | wxFileDataObject(); | |
360 | ||
361 | const wxArrayString& GetFilenames(); | |
362 | #ifdef __WXMSW__ | |
363 | void AddFile(const wxString &filename); | |
364 | #endif | |
365 | }; | |
366 | ||
367 | ||
368 | //--------------------------------------------------------------------------- | |
369 | ||
370 | // wxCustomDataObject contains arbitrary untyped user data. | |
371 | // It is understood that this data can be copied bitwise. | |
372 | class wxCustomDataObject : public wxDataObjectSimple { | |
373 | public: | |
374 | wxCustomDataObject(const wxDataFormat& format = wxFormatInvalid); | |
375 | ||
376 | //void TakeData(size_t size, void *data); | |
377 | //bool SetData(size_t size, const void *buf); | |
378 | %extend { | |
379 | void TakeData(PyObject* data) { | |
380 | if (PyString_Check(data)) { | |
381 | // for Python we just call SetData here since we always need it to make a copy. | |
382 | self->SetData(PyString_Size(data), PyString_AsString(data)); | |
383 | } | |
384 | else { | |
385 | // raise a TypeError if not a string | |
386 | PyErr_SetString(PyExc_TypeError, "String expected."); | |
387 | } | |
388 | } | |
389 | bool SetData(PyObject* data) { | |
390 | if (PyString_Check(data)) { | |
391 | return self->SetData(PyString_Size(data), PyString_AsString(data)); | |
392 | } | |
393 | else { | |
394 | // raise a TypeError if not a string | |
395 | PyErr_SetString(PyExc_TypeError, "String expected."); | |
dd9f7fea | 396 | return False; |
d14a1e28 RD |
397 | } |
398 | } | |
399 | } | |
400 | ||
401 | size_t GetSize(); | |
402 | ||
403 | //void *GetData(); | |
404 | %extend { | |
405 | PyObject* GetData() { | |
406 | return PyString_FromStringAndSize((char*)self->GetData(), self->GetSize()); | |
407 | } | |
408 | } | |
409 | }; | |
410 | ||
411 | ||
412 | // TODO: Implement wxPyCustomDataObject allowing GetSize, GetData and SetData | |
413 | // to be overloaded. | |
414 | ||
415 | //--------------------------------------------------------------------------- | |
416 | ||
417 | class wxURLDataObject : public wxDataObjectComposite { | |
418 | public: | |
419 | wxURLDataObject(); | |
420 | ||
421 | wxString GetURL(); | |
422 | void SetURL(const wxString& url); | |
423 | }; | |
424 | ||
425 | //--------------------------------------------------------------------------- | |
426 | ||
427 | #ifndef __WXGTK__ | |
428 | ||
429 | %{ | |
430 | #include <wx/metafile.h> | |
431 | %} | |
432 | ||
433 | class wxMetafileDataObject : public wxDataObjectSimple | |
434 | { | |
435 | public: | |
436 | wxMetafileDataObject(); | |
437 | ||
438 | void SetMetafile(const wxMetafile& metafile); | |
439 | wxMetafile GetMetafile() const; | |
440 | }; | |
441 | ||
442 | ||
443 | #else | |
444 | %{ | |
445 | class wxMetafileDataObject : public wxDataObjectSimple | |
446 | { | |
447 | public: | |
448 | wxMetafileDataObject() { PyErr_SetNone(PyExc_NotImplementedError); } | |
449 | }; | |
450 | %} | |
451 | ||
452 | class wxMetafileDataObject : public wxDataObjectSimple | |
453 | { | |
454 | public: | |
455 | wxMetafileDataObject(); | |
456 | }; | |
457 | ||
458 | #endif | |
459 | ||
460 | //--------------------------------------------------------------------------- | |
461 | //--------------------------------------------------------------------------- | |
462 |