///////////////////////////////////////////////////////////////////////////// // Name: _dataobj.i // Purpose: SWIG definitions for the Data Object classes // // Author: Robin Dunn // // Created: 31-October-1999 // RCS-ID: $Id$ // Copyright: (c) 2003 by Total Control Software // Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// // Not a %module //--------------------------------------------------------------------------- %{ #include %} //--------------------------------------------------------------------------- %newgroup enum wxDataFormatId { wxDF_INVALID, wxDF_TEXT, wxDF_BITMAP, wxDF_METAFILE, wxDF_SYLK, wxDF_DIF, wxDF_TIFF, wxDF_OEMTEXT, wxDF_DIB, wxDF_PALETTE, wxDF_PENDATA, wxDF_RIFF, wxDF_WAVE, wxDF_UNICODETEXT, wxDF_ENHMETAFILE, wxDF_FILENAME, wxDF_LOCALE, wxDF_PRIVATE, wxDF_HTML, wxDF_MAX, }; class wxDataFormat { public: wxDataFormat( wxDataFormatId type ); %name(CustomDataFormat) wxDataFormat(const wxString& format); ~wxDataFormat(); %nokwargs operator==; %nokwargs operator!=; bool operator==(wxDataFormatId format) const; bool operator!=(wxDataFormatId format) const; bool operator==(const wxDataFormat& format) const; bool operator!=(const wxDataFormat& format) const; void SetType(wxDataFormatId format); wxDataFormatId GetType() const; wxString GetId() const; void SetId(const wxString& format); }; %immutable; const wxDataFormat wxFormatInvalid; %mutable; //--------------------------------------------------------------------------- // wxDataObject represents a piece of data which knows which formats it // supports and knows how to render itself in each of them - GetDataHere(), // and how to restore data from the buffer (SetData()). // // Although this class may be used directly (i.e. custom classes may be // derived from it), in many cases it might be simpler to use either // wxDataObjectSimple or wxDataObjectComposite classes. // // A data object may be "read only", i.e. support only GetData() functions or // "read-write", i.e. support both GetData() and SetData() (in principle, it // might be "write only" too, but this is rare). Moreover, it doesn't have to // support the same formats in Get() and Set() directions: for example, a data // object containing JPEG image might accept BMPs in GetData() because JPEG // image may be easily transformed into BMP but not in SetData(). Accordingly, // all methods dealing with formats take an additional "direction" argument // which is either SET or GET and which tells the function if the format needs // to be supported by SetData() or GetDataHere(). class wxDataObject { public: enum Direction { Get = 0x01, // format is supported by GetDataHere() Set = 0x02, // format is supported by SetData() Both = 0x03 // format is supported by both (unused currently) }; // wxDataObject(); // *** It's an ABC. ~wxDataObject(); // get the best suited format for rendering our data virtual wxDataFormat GetPreferredFormat(Direction dir = Get) const; // get the number of formats we support virtual size_t GetFormatCount(Direction dir = Get) const; // returns True if this format is supported bool IsSupported(const wxDataFormat& format, Direction dir = Get) const; // get the (total) size of data for the given format virtual size_t GetDataSize(const wxDataFormat& format) const; //------------------------------------------------------------------- // TODO: Fix these three methods to do the right Pythonic things... //------------------------------------------------------------------- // return all formats in the provided array (of size GetFormatCount()) virtual void GetAllFormats(wxDataFormat *formats, Direction dir = Get) const; // copy raw data (in the specified format) to the provided buffer, return // True if data copied successfully, False otherwise virtual bool GetDataHere(const wxDataFormat& format, void *buf) const; // get data from the buffer of specified length (in the given format), // return True if the data was read successfully, False otherwise virtual bool SetData(const wxDataFormat& format, size_t len, const void * buf); }; //--------------------------------------------------------------------------- // wxDataObjectSimple is a wxDataObject which only supports one format (in // both Get and Set directions, but you may return False from GetDataHere() or // SetData() if one of them is not supported). This is the simplest possible // wxDataObject implementation. // // This is still an "abstract base class" (although it doesn't have any pure // virtual functions), to use it you should derive from it and implement // GetDataSize(), GetDataHere() and SetData() functions because the base class // versions don't do anything - they just return "not implemented". // // This class should be used when you provide data in only one format (no // conversion to/from other formats), either a standard or a custom one. // Otherwise, you should use wxDataObjectComposite or wxDataObject directly. class wxDataObjectSimple : public wxDataObject { public: wxDataObjectSimple(const wxDataFormat& format = wxFormatInvalid); // get/set the format we support const wxDataFormat& GetFormat(); void SetFormat(const wxDataFormat& format); }; %{ // Create a new class for wxPython to use class wxPyDataObjectSimple : public wxDataObjectSimple { public: wxPyDataObjectSimple(const wxDataFormat& format = wxFormatInvalid) : wxDataObjectSimple(format) {} DEC_PYCALLBACK_SIZET__const(GetDataSize); bool GetDataHere(void *buf) const; bool SetData(size_t len, const void *buf) const; PYPRIVATE; }; IMP_PYCALLBACK_SIZET__const(wxPyDataObjectSimple, wxDataObjectSimple, GetDataSize); bool wxPyDataObjectSimple::GetDataHere(void *buf) const { // We need to get the data for this object and write it to buf. I think // the best way to do this for wxPython is to have the Python method // return either a string or None and then act appropriately with the // C++ version. bool rval = False; wxPyBeginBlockThreads(); if (wxPyCBH_findCallback(m_myInst, "GetDataHere")) { PyObject* ro; ro = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("()")); if (ro) { rval = (ro != Py_None && PyString_Check(ro)); if (rval) memcpy(buf, PyString_AsString(ro), PyString_Size(ro)); Py_DECREF(ro); } } wxPyEndBlockThreads(); return rval; } bool wxPyDataObjectSimple::SetData(size_t len, const void *buf) const{ // For this one we simply need to make a string from buf and len // and send it to the Python method. bool rval = False; wxPyBeginBlockThreads(); if (wxPyCBH_findCallback(m_myInst, "SetData")) { PyObject* data = PyString_FromStringAndSize((char*)buf, len); rval = wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", data)); Py_DECREF(data); } wxPyEndBlockThreads(); return rval; } %} // Now define it for SWIG class wxPyDataObjectSimple : public wxDataObjectSimple { public: %pythonAppend wxPyDataObjectSimple "self._setCallbackInfo(self, PyDataObjectSimple)" wxPyDataObjectSimple(const wxDataFormat& format = wxFormatInvalid); void _setCallbackInfo(PyObject* self, PyObject* _class); }; //--------------------------------------------------------------------------- // wxDataObjectComposite is the simplest way to implement wxDataObject // supporting multiple formats. It contains several wxDataObjectSimple and // supports all formats supported by any of them. // class wxDataObjectComposite : public wxDataObject { public: wxDataObjectComposite(); %apply SWIGTYPE *DISOWN { wxDataObjectSimple *dataObject }; void Add(wxDataObjectSimple *dataObject, int preferred = False); %clear wxDataObjectSimple *dataObject; }; //--------------------------------------------------------------------------- // wxTextDataObject contains text data class wxTextDataObject : public wxDataObjectSimple { public: wxTextDataObject(const wxString& text = wxPyEmptyString); size_t GetTextLength(); wxString GetText(); void SetText(const wxString& text); }; %{ // Create a new class for wxPython to use class wxPyTextDataObject : public wxTextDataObject { public: wxPyTextDataObject(const wxString& text = wxPyEmptyString) : wxTextDataObject(text) {} DEC_PYCALLBACK_SIZET__const(GetTextLength); DEC_PYCALLBACK_STRING__const(GetText); DEC_PYCALLBACK__STRING(SetText); PYPRIVATE; }; IMP_PYCALLBACK_SIZET__const(wxPyTextDataObject, wxTextDataObject, GetTextLength); IMP_PYCALLBACK_STRING__const(wxPyTextDataObject, wxTextDataObject, GetText); IMP_PYCALLBACK__STRING(wxPyTextDataObject, wxTextDataObject, SetText); %} // Now define it for SWIG class wxPyTextDataObject : public wxTextDataObject { public: %pythonAppend wxPyTextDataObject "self._setCallbackInfo(self, PyTextDataObject)" wxPyTextDataObject(const wxString& text = wxPyEmptyString); void _setCallbackInfo(PyObject* self, PyObject* _class); }; //--------------------------------------------------------------------------- // wxBitmapDataObject contains a bitmap class wxBitmapDataObject : public wxDataObjectSimple { public: wxBitmapDataObject(const wxBitmap& bitmap = wxNullBitmap); wxBitmap GetBitmap() const; void SetBitmap(const wxBitmap& bitmap); }; %{ // Create a new class for wxPython to use class wxPyBitmapDataObject : public wxBitmapDataObject { public: wxPyBitmapDataObject(const wxBitmap& bitmap = wxNullBitmap) : wxBitmapDataObject(bitmap) {} wxBitmap GetBitmap() const; void SetBitmap(const wxBitmap& bitmap); PYPRIVATE; }; wxBitmap wxPyBitmapDataObject::GetBitmap() const { wxBitmap* rval = &wxNullBitmap; wxPyBeginBlockThreads(); if (wxPyCBH_findCallback(m_myInst, "GetBitmap")) { PyObject* ro; wxBitmap* ptr; ro = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("()")); if (ro) { if (wxPyConvertSwigPtr(ro, (void **)&ptr, wxT("wxBitmap"))) rval = ptr; Py_DECREF(ro); } } wxPyEndBlockThreads(); return *rval; } void wxPyBitmapDataObject::SetBitmap(const wxBitmap& bitmap) { wxPyBeginBlockThreads(); if (wxPyCBH_findCallback(m_myInst, "SetBitmap")) { PyObject* bo = wxPyConstructObject((void*)&bitmap, wxT("wxBitmap"), False); wxPyCBH_callCallback(m_myInst, Py_BuildValue("(O)", bo)); Py_DECREF(bo); } wxPyEndBlockThreads(); } %} // Now define it for SWIG class wxPyBitmapDataObject : public wxBitmapDataObject { public: %pythonAppend wxPyBitmapDataObject "self._setCallbackInfo(self, PyBitmapDataObject)" wxPyBitmapDataObject(const wxBitmap& bitmap = wxNullBitmap); void _setCallbackInfo(PyObject* self, PyObject* _class); }; //--------------------------------------------------------------------------- // wxFileDataObject contains a list of filenames class wxFileDataObject : public wxDataObjectSimple { public: wxFileDataObject(); const wxArrayString& GetFilenames(); void AddFile(const wxString &filename); }; //--------------------------------------------------------------------------- // wxCustomDataObject contains arbitrary untyped user data. // It is understood that this data can be copied bitwise. class wxCustomDataObject : public wxDataObjectSimple { public: wxCustomDataObject(const wxDataFormat& format = wxFormatInvalid); //void TakeData(size_t size, void *data); //bool SetData(size_t size, const void *buf); %extend { void TakeData(PyObject* data) { if (PyString_Check(data)) { // for Python we just call SetData here since we always need it to make a copy. self->SetData(PyString_Size(data), PyString_AsString(data)); } else { // raise a TypeError if not a string PyErr_SetString(PyExc_TypeError, "String expected."); } } bool SetData(PyObject* data) { if (PyString_Check(data)) { return self->SetData(PyString_Size(data), PyString_AsString(data)); } else { // raise a TypeError if not a string PyErr_SetString(PyExc_TypeError, "String expected."); return False; } } } size_t GetSize(); //void *GetData(); %extend { PyObject* GetData() { return PyString_FromStringAndSize((char*)self->GetData(), self->GetSize()); } } }; // TODO: Implement wxPyCustomDataObject allowing GetSize, GetData and SetData // to be overloaded. //--------------------------------------------------------------------------- class wxURLDataObject : public wxDataObjectComposite { public: wxURLDataObject(); wxString GetURL(); void SetURL(const wxString& url); }; //--------------------------------------------------------------------------- #if defined(__WXMSW__) || defined(__WXMAC__) %{ #include %} class wxMetafileDataObject : public wxDataObjectSimple { public: wxMetafileDataObject(); void SetMetafile(const wxMetafile& metafile); wxMetafile GetMetafile() const; }; #else %{ class wxMetafileDataObject : public wxDataObjectSimple { public: wxMetafileDataObject() { wxPyRaiseNotImplemented(); } }; %} class wxMetafileDataObject : public wxDataObjectSimple { public: wxMetafileDataObject(); }; #endif //--------------------------------------------------------------------------- //---------------------------------------------------------------------------