]>
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 | ||
0facd0e5 RD |
51 | DocStr(wxDataFormat, |
52 | "A wx.DataFormat is an encapsulation of a platform-specific format | |
53 | handle which is used by the system for the clipboard and drag and | |
54 | drop operations. The applications are usually only interested in, | |
55 | for example, pasting data from the clipboard only if the data is | |
56 | in a format the program understands. A data format is is used to | |
57 | uniquely identify this format. | |
58 | ||
59 | On the system level, a data format is usually just a number | |
60 | (CLIPFORMAT under Windows or Atom under X11, for example)."); | |
61 | ||
62 | // The standard format IDs are | |
63 | ||
64 | // wx.DF_INVALID An invalid format | |
65 | // wx.DF_TEXT Text format | |
66 | // wx.DF_BITMAP A bitmap (wx.Bitmap) | |
67 | // wx.DF_METAFILE A metafile (wx.Metafile, Windows only) | |
68 | // wx.DF_FILENAME A list of filenames | |
69 | // wx.DF_HTML An HTML string. This is only valid on Windows and non-unicode builds | |
70 | ||
71 | // Aside the standard formats, the application may also use | |
72 | // custom formats which are identified by their names (strings) | |
73 | // and not numeric identifiers. Although internally custom format | |
74 | // must be created (or registered) first, you shouldn\'t care | |
75 | // about it because it is done automatically the first time the | |
76 | // wxDataFormat object corresponding to a given format name is | |
77 | // created. | |
78 | ||
79 | // "); | |
80 | ||
d14a1e28 RD |
81 | class wxDataFormat { |
82 | public: | |
0facd0e5 RD |
83 | DocCtorStr( |
84 | wxDataFormat( wxDataFormatId type ), | |
85 | "Constructs a data format object for one of the standard data\n" | |
86 | "formats or an empty data object (use SetType or SetId later in\n" | |
87 | "this case)"); | |
88 | ||
89 | DocCtorStrName( | |
90 | wxDataFormat(const wxString& format), | |
91 | "Constructs a data format object for a custom format identified by its name.", | |
92 | CustomDataFormat); | |
d14a1e28 RD |
93 | |
94 | ~wxDataFormat(); | |
95 | ||
0facd0e5 | 96 | |
d14a1e28 RD |
97 | %nokwargs operator==; |
98 | %nokwargs operator!=; | |
04e27155 RD |
99 | bool operator==(wxDataFormatId format) const; |
100 | bool operator!=(wxDataFormatId format) const; | |
d14a1e28 RD |
101 | bool operator==(const wxDataFormat& format) const; |
102 | bool operator!=(const wxDataFormat& format) const; | |
103 | ||
0facd0e5 RD |
104 | |
105 | DocDeclStr( | |
106 | void , SetType(wxDataFormatId format), | |
107 | "Sets the format to the given value, which should be one of wx.DF_XXX constants."); | |
108 | ||
109 | DocDeclStr( | |
110 | wxDataFormatId , GetType() const, | |
111 | "Returns the platform-specific number identifying the format."); | |
112 | ||
d14a1e28 | 113 | |
0facd0e5 RD |
114 | DocDeclStr( |
115 | wxString , GetId() const, | |
116 | "Returns the name of a custom format (this function will fail for a standard format)."); | |
117 | ||
118 | DocDeclStr( | |
119 | void , SetId(const wxString& format), | |
120 | "Sets the format to be the custom format identified by the given name."); | |
d14a1e28 RD |
121 | }; |
122 | ||
123 | ||
124 | %immutable; | |
125 | const wxDataFormat wxFormatInvalid; | |
126 | %mutable; | |
127 | ||
128 | ||
129 | //--------------------------------------------------------------------------- | |
130 | ||
131 | ||
132 | // wxDataObject represents a piece of data which knows which formats it | |
133 | // supports and knows how to render itself in each of them - GetDataHere(), | |
134 | // and how to restore data from the buffer (SetData()). | |
135 | // | |
136 | // Although this class may be used directly (i.e. custom classes may be | |
137 | // derived from it), in many cases it might be simpler to use either | |
138 | // wxDataObjectSimple or wxDataObjectComposite classes. | |
139 | // | |
140 | // A data object may be "read only", i.e. support only GetData() functions or | |
141 | // "read-write", i.e. support both GetData() and SetData() (in principle, it | |
142 | // might be "write only" too, but this is rare). Moreover, it doesn't have to | |
143 | // support the same formats in Get() and Set() directions: for example, a data | |
144 | // object containing JPEG image might accept BMPs in GetData() because JPEG | |
145 | // image may be easily transformed into BMP but not in SetData(). Accordingly, | |
146 | // all methods dealing with formats take an additional "direction" argument | |
147 | // which is either SET or GET and which tells the function if the format needs | |
148 | // to be supported by SetData() or GetDataHere(). | |
149 | class wxDataObject { | |
150 | public: | |
151 | enum Direction { | |
152 | Get = 0x01, // format is supported by GetDataHere() | |
153 | Set = 0x02, // format is supported by SetData() | |
154 | Both = 0x03 // format is supported by both (unused currently) | |
155 | }; | |
156 | ||
157 | // wxDataObject(); // *** It's an ABC. | |
158 | ~wxDataObject(); | |
159 | ||
160 | // get the best suited format for rendering our data | |
161 | virtual wxDataFormat GetPreferredFormat(Direction dir = Get) const; | |
162 | ||
163 | // get the number of formats we support | |
164 | virtual size_t GetFormatCount(Direction dir = Get) const; | |
165 | ||
dd9f7fea | 166 | // returns True if this format is supported |
d14a1e28 RD |
167 | bool IsSupported(const wxDataFormat& format, Direction dir = Get) const; |
168 | ||
169 | // get the (total) size of data for the given format | |
170 | virtual size_t GetDataSize(const wxDataFormat& format) const; | |
171 | ||
172 | ||
173 | //------------------------------------------------------------------- | |
174 | // TODO: Fix these three methods to do the right Pythonic things... | |
175 | //------------------------------------------------------------------- | |
176 | ||
177 | // return all formats in the provided array (of size GetFormatCount()) | |
178 | virtual void GetAllFormats(wxDataFormat *formats, | |
179 | Direction dir = Get) const; | |
180 | ||
181 | // copy raw data (in the specified format) to the provided buffer, return | |
dd9f7fea | 182 | // True if data copied successfully, False otherwise |
d14a1e28 RD |
183 | virtual bool GetDataHere(const wxDataFormat& format, void *buf) const; |
184 | ||
185 | // get data from the buffer of specified length (in the given format), | |
dd9f7fea | 186 | // return True if the data was read successfully, False otherwise |
d14a1e28 RD |
187 | virtual bool SetData(const wxDataFormat& format, |
188 | size_t len, const void * buf); | |
189 | }; | |
190 | ||
191 | ||
192 | //--------------------------------------------------------------------------- | |
193 | ||
194 | ||
195 | ||
196 | // wxDataObjectSimple is a wxDataObject which only supports one format (in | |
dd9f7fea | 197 | // both Get and Set directions, but you may return False from GetDataHere() or |
d14a1e28 RD |
198 | // SetData() if one of them is not supported). This is the simplest possible |
199 | // wxDataObject implementation. | |
200 | // | |
201 | // This is still an "abstract base class" (although it doesn't have any pure | |
202 | // virtual functions), to use it you should derive from it and implement | |
203 | // GetDataSize(), GetDataHere() and SetData() functions because the base class | |
204 | // versions don't do anything - they just return "not implemented". | |
205 | // | |
206 | // This class should be used when you provide data in only one format (no | |
207 | // conversion to/from other formats), either a standard or a custom one. | |
208 | // Otherwise, you should use wxDataObjectComposite or wxDataObject directly. | |
209 | class wxDataObjectSimple : public wxDataObject { | |
210 | public: | |
211 | wxDataObjectSimple(const wxDataFormat& format = wxFormatInvalid); | |
212 | ||
213 | // get/set the format we support | |
214 | const wxDataFormat& GetFormat(); | |
215 | void SetFormat(const wxDataFormat& format); | |
216 | ||
217 | }; | |
218 | ||
219 | ||
220 | %{ // Create a new class for wxPython to use | |
221 | class wxPyDataObjectSimple : public wxDataObjectSimple { | |
222 | public: | |
223 | wxPyDataObjectSimple(const wxDataFormat& format = wxFormatInvalid) | |
224 | : wxDataObjectSimple(format) {} | |
225 | ||
226 | DEC_PYCALLBACK_SIZET__const(GetDataSize); | |
227 | bool GetDataHere(void *buf) const; | |
228 | bool SetData(size_t len, const void *buf) const; | |
229 | PYPRIVATE; | |
230 | }; | |
231 | ||
232 | IMP_PYCALLBACK_SIZET__const(wxPyDataObjectSimple, wxDataObjectSimple, GetDataSize); | |
233 | ||
234 | bool wxPyDataObjectSimple::GetDataHere(void *buf) const { | |
235 | // We need to get the data for this object and write it to buf. I think | |
236 | // the best way to do this for wxPython is to have the Python method | |
237 | // return either a string or None and then act appropriately with the | |
238 | // C++ version. | |
239 | ||
dd9f7fea | 240 | bool rval = False; |
da32eb53 | 241 | bool blocked = wxPyBeginBlockThreads(); |
d14a1e28 RD |
242 | if (wxPyCBH_findCallback(m_myInst, "GetDataHere")) { |
243 | PyObject* ro; | |
244 | ro = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("()")); | |
245 | if (ro) { | |
246 | rval = (ro != Py_None && PyString_Check(ro)); | |
247 | if (rval) | |
248 | memcpy(buf, PyString_AsString(ro), PyString_Size(ro)); | |
249 | Py_DECREF(ro); | |
250 | } | |
251 | } | |
da32eb53 | 252 | wxPyEndBlockThreads(blocked); |
d14a1e28 RD |
253 | return rval; |
254 | } | |
255 | ||
256 | bool wxPyDataObjectSimple::SetData(size_t len, const void *buf) const{ | |
257 | // For this one we simply need to make a string from buf and len | |
258 | // and send it to the Python method. | |
dd9f7fea | 259 | bool rval = False; |
da32eb53 | 260 | bool blocked = wxPyBeginBlockThreads(); |
d14a1e28 RD |
261 | if (wxPyCBH_findCallback(m_myInst, "SetData")) { |
262 | PyObject* data = PyString_FromStringAndSize((char*)buf, len); | |
263 | rval = wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", data)); | |
264 | Py_DECREF(data); | |
265 | } | |
da32eb53 | 266 | wxPyEndBlockThreads(blocked); |
d14a1e28 RD |
267 | return rval; |
268 | } | |
269 | %} | |
270 | ||
271 | ||
272 | ||
273 | // Now define it for SWIG | |
274 | class wxPyDataObjectSimple : public wxDataObjectSimple { | |
275 | public: | |
2b9048c5 | 276 | %pythonAppend wxPyDataObjectSimple "self._setCallbackInfo(self, PyDataObjectSimple)" |
d14a1e28 RD |
277 | |
278 | wxPyDataObjectSimple(const wxDataFormat& format = wxFormatInvalid); | |
279 | void _setCallbackInfo(PyObject* self, PyObject* _class); | |
280 | }; | |
281 | ||
282 | ||
283 | //--------------------------------------------------------------------------- | |
284 | ||
285 | ||
286 | // wxDataObjectComposite is the simplest way to implement wxDataObject | |
287 | // supporting multiple formats. It contains several wxDataObjectSimple and | |
288 | // supports all formats supported by any of them. | |
289 | // | |
290 | class wxDataObjectComposite : public wxDataObject { | |
291 | public: | |
292 | wxDataObjectComposite(); | |
293 | ||
8668c242 | 294 | %apply SWIGTYPE *DISOWN { wxDataObjectSimple *dataObject }; |
dd9f7fea | 295 | void Add(wxDataObjectSimple *dataObject, int preferred = False); |
8668c242 | 296 | %clear wxDataObjectSimple *dataObject; |
d14a1e28 RD |
297 | }; |
298 | ||
299 | //--------------------------------------------------------------------------- | |
300 | ||
301 | // wxTextDataObject contains text data | |
302 | class wxTextDataObject : public wxDataObjectSimple { | |
303 | public: | |
304 | wxTextDataObject(const wxString& text = wxPyEmptyString); | |
305 | ||
306 | size_t GetTextLength(); | |
307 | wxString GetText(); | |
308 | void SetText(const wxString& text); | |
309 | }; | |
310 | ||
311 | ||
312 | ||
313 | %{ // Create a new class for wxPython to use | |
314 | class wxPyTextDataObject : public wxTextDataObject { | |
315 | public: | |
316 | wxPyTextDataObject(const wxString& text = wxPyEmptyString) | |
317 | : wxTextDataObject(text) {} | |
318 | ||
319 | DEC_PYCALLBACK_SIZET__const(GetTextLength); | |
320 | DEC_PYCALLBACK_STRING__const(GetText); | |
321 | DEC_PYCALLBACK__STRING(SetText); | |
322 | PYPRIVATE; | |
323 | }; | |
324 | ||
325 | IMP_PYCALLBACK_SIZET__const(wxPyTextDataObject, wxTextDataObject, GetTextLength); | |
326 | IMP_PYCALLBACK_STRING__const(wxPyTextDataObject, wxTextDataObject, GetText); | |
327 | IMP_PYCALLBACK__STRING(wxPyTextDataObject, wxTextDataObject, SetText); | |
328 | ||
329 | %} | |
330 | ||
331 | ||
332 | // Now define it for SWIG | |
333 | class wxPyTextDataObject : public wxTextDataObject { | |
334 | public: | |
2b9048c5 | 335 | %pythonAppend wxPyTextDataObject "self._setCallbackInfo(self, PyTextDataObject)" |
d14a1e28 RD |
336 | |
337 | wxPyTextDataObject(const wxString& text = wxPyEmptyString); | |
338 | void _setCallbackInfo(PyObject* self, PyObject* _class); | |
339 | }; | |
340 | ||
341 | //--------------------------------------------------------------------------- | |
342 | ||
343 | // wxBitmapDataObject contains a bitmap | |
344 | class wxBitmapDataObject : public wxDataObjectSimple { | |
345 | public: | |
346 | wxBitmapDataObject(const wxBitmap& bitmap = wxNullBitmap); | |
347 | ||
348 | wxBitmap GetBitmap() const; | |
349 | void SetBitmap(const wxBitmap& bitmap); | |
350 | }; | |
351 | ||
352 | ||
353 | ||
354 | %{ // Create a new class for wxPython to use | |
355 | class wxPyBitmapDataObject : public wxBitmapDataObject { | |
356 | public: | |
357 | wxPyBitmapDataObject(const wxBitmap& bitmap = wxNullBitmap) | |
358 | : wxBitmapDataObject(bitmap) {} | |
359 | ||
360 | wxBitmap GetBitmap() const; | |
361 | void SetBitmap(const wxBitmap& bitmap); | |
362 | PYPRIVATE; | |
363 | }; | |
364 | ||
365 | wxBitmap wxPyBitmapDataObject::GetBitmap() const { | |
366 | wxBitmap* rval = &wxNullBitmap; | |
da32eb53 | 367 | bool blocked = wxPyBeginBlockThreads(); |
d14a1e28 RD |
368 | if (wxPyCBH_findCallback(m_myInst, "GetBitmap")) { |
369 | PyObject* ro; | |
370 | wxBitmap* ptr; | |
371 | ro = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("()")); | |
372 | if (ro) { | |
373 | if (wxPyConvertSwigPtr(ro, (void **)&ptr, wxT("wxBitmap"))) | |
374 | rval = ptr; | |
375 | Py_DECREF(ro); | |
376 | } | |
377 | } | |
da32eb53 | 378 | wxPyEndBlockThreads(blocked); |
d14a1e28 RD |
379 | return *rval; |
380 | } | |
381 | ||
382 | void wxPyBitmapDataObject::SetBitmap(const wxBitmap& bitmap) { | |
da32eb53 | 383 | bool blocked = wxPyBeginBlockThreads(); |
d14a1e28 | 384 | if (wxPyCBH_findCallback(m_myInst, "SetBitmap")) { |
dd9f7fea | 385 | PyObject* bo = wxPyConstructObject((void*)&bitmap, wxT("wxBitmap"), False); |
d14a1e28 RD |
386 | wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", bo)); |
387 | Py_DECREF(bo); | |
388 | } | |
da32eb53 | 389 | wxPyEndBlockThreads(blocked); |
d14a1e28 RD |
390 | } |
391 | %} | |
392 | ||
393 | ||
394 | ||
395 | // Now define it for SWIG | |
396 | class wxPyBitmapDataObject : public wxBitmapDataObject { | |
397 | public: | |
2b9048c5 | 398 | %pythonAppend wxPyBitmapDataObject "self._setCallbackInfo(self, PyBitmapDataObject)" |
d14a1e28 RD |
399 | |
400 | wxPyBitmapDataObject(const wxBitmap& bitmap = wxNullBitmap); | |
401 | void _setCallbackInfo(PyObject* self, PyObject* _class); | |
402 | }; | |
403 | ||
404 | //--------------------------------------------------------------------------- | |
405 | ||
406 | ||
407 | // wxFileDataObject contains a list of filenames | |
408 | class wxFileDataObject : public wxDataObjectSimple | |
409 | { | |
410 | public: | |
411 | wxFileDataObject(); | |
412 | ||
413 | const wxArrayString& GetFilenames(); | |
d14a1e28 | 414 | void AddFile(const wxString &filename); |
d14a1e28 RD |
415 | }; |
416 | ||
417 | ||
418 | //--------------------------------------------------------------------------- | |
419 | ||
420 | // wxCustomDataObject contains arbitrary untyped user data. | |
421 | // It is understood that this data can be copied bitwise. | |
422 | class wxCustomDataObject : public wxDataObjectSimple { | |
423 | public: | |
424 | wxCustomDataObject(const wxDataFormat& format = wxFormatInvalid); | |
425 | ||
426 | //void TakeData(size_t size, void *data); | |
427 | //bool SetData(size_t size, const void *buf); | |
428 | %extend { | |
429 | void TakeData(PyObject* data) { | |
430 | if (PyString_Check(data)) { | |
431 | // for Python we just call SetData here since we always need it to make a copy. | |
432 | self->SetData(PyString_Size(data), PyString_AsString(data)); | |
433 | } | |
434 | else { | |
435 | // raise a TypeError if not a string | |
436 | PyErr_SetString(PyExc_TypeError, "String expected."); | |
437 | } | |
438 | } | |
439 | bool SetData(PyObject* data) { | |
440 | if (PyString_Check(data)) { | |
441 | return self->SetData(PyString_Size(data), PyString_AsString(data)); | |
442 | } | |
443 | else { | |
444 | // raise a TypeError if not a string | |
445 | PyErr_SetString(PyExc_TypeError, "String expected."); | |
dd9f7fea | 446 | return False; |
d14a1e28 RD |
447 | } |
448 | } | |
449 | } | |
450 | ||
451 | size_t GetSize(); | |
452 | ||
453 | //void *GetData(); | |
454 | %extend { | |
455 | PyObject* GetData() { | |
456 | return PyString_FromStringAndSize((char*)self->GetData(), self->GetSize()); | |
457 | } | |
458 | } | |
459 | }; | |
460 | ||
461 | ||
462 | // TODO: Implement wxPyCustomDataObject allowing GetSize, GetData and SetData | |
463 | // to be overloaded. | |
464 | ||
465 | //--------------------------------------------------------------------------- | |
466 | ||
467 | class wxURLDataObject : public wxDataObjectComposite { | |
468 | public: | |
469 | wxURLDataObject(); | |
470 | ||
471 | wxString GetURL(); | |
472 | void SetURL(const wxString& url); | |
473 | }; | |
474 | ||
475 | //--------------------------------------------------------------------------- | |
476 | ||
c1201401 | 477 | #if defined(__WXMSW__) || defined(__WXMAC__) |
d14a1e28 RD |
478 | |
479 | %{ | |
480 | #include <wx/metafile.h> | |
481 | %} | |
482 | ||
483 | class wxMetafileDataObject : public wxDataObjectSimple | |
484 | { | |
485 | public: | |
486 | wxMetafileDataObject(); | |
487 | ||
488 | void SetMetafile(const wxMetafile& metafile); | |
489 | wxMetafile GetMetafile() const; | |
490 | }; | |
491 | ||
492 | ||
493 | #else | |
494 | %{ | |
495 | class wxMetafileDataObject : public wxDataObjectSimple | |
496 | { | |
497 | public: | |
81cfe5e1 | 498 | wxMetafileDataObject() { wxPyRaiseNotImplemented(); } |
d14a1e28 RD |
499 | }; |
500 | %} | |
501 | ||
502 | class wxMetafileDataObject : public wxDataObjectSimple | |
503 | { | |
504 | public: | |
505 | wxMetafileDataObject(); | |
506 | }; | |
507 | ||
508 | #endif | |
509 | ||
510 | //--------------------------------------------------------------------------- | |
511 | //--------------------------------------------------------------------------- | |
512 |