]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/dataobj.h
added support for item attributes in virtual list control
[wxWidgets.git] / include / wx / dataobj.h
index 95e4296b55b3bb0604a333262c7e1c2328c59946..e7042d2b07310580b918a6c197dfa27e74823991 100644 (file)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
-// Name:        dataobj.h
+// Name:        wx/dataobj.h
 // Purpose:     common data object classes
-// Author:      Robert Roebling, Vadim Zeitlin
+// Author:      Vadim Zeitlin, Robert Roebling
 // Modified by:
 // Created:     26.05.99
 // RCS-ID:      $Id$
 #ifndef _WX_DATAOBJ_H_BASE_
 #define _WX_DATAOBJ_H_BASE_
 
-#if defined(__WXMSW__)
+#ifdef __GNUG__
+    #pragma interface "dataobjbase.h"
+#endif
+
 // ----------------------------------------------------------------------------
-// wxDataFormat identifies the single format of data
+// headers
 // ----------------------------------------------------------------------------
 
-class WXDLLEXPORT wxDataFormat
+#include "wx/defs.h"
+#include "wx/string.h"
+#include "wx/bitmap.h"
+#include "wx/list.h"
+
+// ============================================================================
+/*
+   Generic data transfer related classes. The class hierarchy is as follows:
+
+                                - wxDataObject-
+                               /               \
+                              /                 \
+            wxDataObjectSimple                  wxDataObjectComposite
+           /           |      \
+          /            |       \
+   wxTextDataObject    |     wxBitmapDataObject
+                       |
+               wxCustomDataObject
+
+*/
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxDataFormat class is declared in platform-specific headers: it represents
+// a format for data which may be either one of the standard ones (text,
+// bitmap, ...) or a custom one which is then identified by a unique string.
+// ----------------------------------------------------------------------------
+
+/* the class interface looks like this (pseudo code):
+
+class wxDataFormat
 {
 public:
-    // the clipboard formats under Win32 are UINTs
-    typedef unsigned int NativeFormat;
-
-    wxDataFormat(NativeFormat format = wxDF_INVALID) { m_format = format; }
-    wxDataFormat& operator=(NativeFormat format)
-        { m_format = format; return *this; }
-
-    // defautl copy ctor/assignment operators ok
-
-    // comparison (must have both versions)
-    bool operator==(wxDataFormatId format) const
-        { return m_format == (NativeFormat)format; }
-    bool operator!=(wxDataFormatId format) const
-        { return m_format != (NativeFormat)format; }
-    bool operator==(const wxDataFormat& format) const
-        { return m_format == format.m_format; }
-    bool operator!=(const wxDataFormat& format) const
-        { return m_format != format.m_format; }
-
-    // explicit and implicit conversions to NativeFormat which is one of
-    // standard data types (implicit conversion is useful for preserving the
-    // compatibility with old code)
-    NativeFormat GetFormatId() const { return m_format; }
-    operator NativeFormat() const { return m_format; }
-
-    // this only works with standard ids
-    void SetId(wxDataFormatId format) { m_format = format; }
-
-    // string ids are used for custom types - this SetId() must be used for
-    // application-specific formats
+    typedef <integral type> NativeFormat;
+
+    wxDataFormat(NativeFormat format = wxDF_INVALID);
+    wxDataFormat(const wxChar *format);
+
+    wxDataFormat& operator=(NativeFormat format);
+    wxDataFormat& operator=(const wxDataFormat& format);
+
+    bool operator==(NativeFormat format) const;
+    bool operator!=(NativeFormat format) const;
+
+    void SetType(NativeFormat format);
+    NativeFormat GetType() const;
+
     wxString GetId() const;
     void SetId(const wxChar *format);
+};
 
-private:
-    // returns TRUE if the format is one of those defined in wxDataFormatId
-    bool IsStandard() const { return m_format > 0 && m_format < wxDF_MAX; }
+*/
 
-    NativeFormat m_format;
+#if defined(__WXMSW__)
+    #include "wx/msw/ole/dataform.h"
+#elif defined(__WXMOTIF__)
+    #include "wx/motif/dataform.h"
+#elif defined(__WXGTK__)
+    #include "wx/gtk/dataform.h"
+#elif defined(__WXMAC__)
+    #include "wx/mac/dataform.h"
+#elif defined(__WXPM__)
+    #include "wx/os2/dataform.h"
+#endif
+
+// the value for default argument to some functions (corresponds to
+// wxDF_INVALID)
+extern WXDLLEXPORT const wxDataFormat& wxFormatInvalid;
+
+// ----------------------------------------------------------------------------
+// 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 WXDLLEXPORT wxDataObjectBase
+{
+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)
+    };
+
+    // this class is polymorphic, hence it needs a virtual dtor
+    virtual ~wxDataObjectBase();
+
+    // get the best suited format for rendering our data
+    virtual wxDataFormat GetPreferredFormat(Direction dir = Get) const = 0;
+
+    // get the number of formats we support
+    virtual size_t GetFormatCount(Direction dir = Get) const = 0;
+
+    // return all formats in the provided array (of size GetFormatCount())
+    virtual void GetAllFormats(wxDataFormat *formats,
+                               Direction dir = Get) const = 0;
+
+    // get the (total) size of data for the given format
+    virtual size_t GetDataSize(const wxDataFormat& format) const = 0;
+
+    // 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 = 0;
+
+    // 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& WXUNUSED(format),
+                         size_t WXUNUSED(len), const void * WXUNUSED(buf))
+    {
+        return FALSE;
+    }
+
+    // returns TRUE if this format is supported
+    bool IsSupported(const wxDataFormat& format, Direction dir = Get) const;
 };
 
+// ----------------------------------------------------------------------------
+// include the platform-specific declarations of wxDataObject
+// ----------------------------------------------------------------------------
+
+#if defined(__WXMSW__)
     #include "wx/msw/ole/dataobj.h"
 #elif defined(__WXMOTIF__)
     #include "wx/motif/dataobj.h"
@@ -68,74 +164,295 @@ private:
 #elif defined(__WXQT__)
     #include "wx/qt/dnd.h"
 #elif defined(__WXMAC__)
-    #include "wx/mac/dnd.h"
+    #include "wx/mac/dataobj.h"
+#elif defined(__WXPM__)
+    #include "wx/os2/dataobj.h"
 #elif defined(__WXSTUBS__)
     #include "wx/stubs/dnd.h"
 #endif
 
-// ---------------------------------------------------------------------------
-// wxPrivateDataObject is a specialization of wxDataObject for app specific
-// data (of some given kind, derive directly from wxDataObject if you wish to
-// efficiently support multiple formats)
-// ---------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+// 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 WXDLLEXPORT wxPrivateDataObject : public wxDataObject
+class WXDLLEXPORT wxDataObjectSimple : public wxDataObject
 {
-#ifdef __WXGTK__
-    DECLARE_DYNAMIC_CLASS( wxPrivateDataObject )
-#endif
+public:
+    // ctor takes the format we support, but it can also be set later with
+    // SetFormat()
+    wxDataObjectSimple(const wxDataFormat& format = wxFormatInvalid)
+        : m_format(format)
+        {
+        }
+
+    // get/set the format we support
+    const wxDataFormat& GetFormat() const { return m_format; }
+    void SetFormat(const wxDataFormat& format) { m_format = format; }
+
+    // virtual functions to override in derived class (the base class versions
+    // just return "not implemented")
+    // -----------------------------------------------------------------------
+
+    // get the size of our data
+    virtual size_t GetDataSize() const
+        { return 0; }
+
+    // copy our data to the buffer
+    virtual bool GetDataHere(void *WXUNUSED(buf)) const
+        { return FALSE; }
+
+    // copy data from buffer to our data
+    virtual bool SetData(size_t WXUNUSED(len), const void *WXUNUSED(buf))
+        { return FALSE; }
 
+    // implement base class pure virtuals
+    // ----------------------------------
+    virtual wxDataFormat GetPreferredFormat(wxDataObjectBase::Direction WXUNUSED(dir) = Get) const
+        { return m_format; }
+    virtual size_t GetFormatCount(wxDataObjectBase::Direction WXUNUSED(dir) = Get) const
+        { return 1; }
+    virtual void GetAllFormats(wxDataFormat *formats,
+                               wxDataObjectBase::Direction WXUNUSED(dir) = Get) const
+        { *formats = m_format; }
+    virtual size_t GetDataSize(const wxDataFormat& WXUNUSED(format)) const
+        { return GetDataSize(); }
+    virtual bool GetDataHere(const wxDataFormat& WXUNUSED(format),
+                             void *buf) const
+        { return GetDataHere(buf); }
+    virtual bool SetData(const wxDataFormat& WXUNUSED(format),
+                         size_t len, const void *buf)
+        { return SetData(len, buf); }
+
+private:
+    // the one and only format we support
+    wxDataFormat m_format;
+};
+
+// ----------------------------------------------------------------------------
+// wxDataObjectComposite is the simplest way to implement wxDataObject
+// supporting multiple formats. It contains several wxDataObjectSimple and
+// supports all formats supported by any of them.
+//
+// This class shouldn't be (normally) derived from, but may be used directly.
+// If you need more flexibility than what it provides, you should probably use
+// wxDataObject directly.
+// ----------------------------------------------------------------------------
+
+WX_DECLARE_EXPORTED_LIST(wxDataObjectSimple, wxSimpleDataObjectList);
+
+class WXDLLEXPORT wxDataObjectComposite : public wxDataObject
+{
 public:
-    wxPrivateDataObject();
-    virtual ~wxPrivateDataObject() { Free(); }
+    // ctor
+    wxDataObjectComposite() { m_preferred = 0; }
 
-    // get the format object - it is used to decide whether we support the
-    // given output format or not
-    wxDataFormat& GetFormat() { return m_format; }
+    // add data object (it will be deleted by wxDataObjectComposite, hence it
+    // must be allocated on the heap) whose format will become the preferred
+    // one if preferred == TRUE
+    void Add(wxDataObjectSimple *dataObject, bool preferred = FALSE);
 
-    // set data. will make copy of the data
-    void SetData( const void *data, size_t size );
+    // implement base class pure virtuals
+    // ----------------------------------
+    virtual wxDataFormat GetPreferredFormat(wxDataObjectBase::Direction dir = Get) const;
+    virtual size_t GetFormatCount(wxDataObjectBase::Direction dir = Get) const;
+    virtual void GetAllFormats(wxDataFormat *formats, wxDataObjectBase::Direction dir = Get) const;
+    virtual size_t GetDataSize(const wxDataFormat& format) const;
+    virtual bool GetDataHere(const wxDataFormat& format, void *buf) const;
+    virtual bool SetData(const wxDataFormat& format, size_t len, const void *buf);
 
-    // returns pointer to data
-    void *GetData() const { return m_data; }
+protected:
+    // returns the pointer to the object which supports this format or NULL
+    wxDataObjectSimple *GetObject(const wxDataFormat& format) const;
 
-    // get the size of the data
-    virtual size_t GetSize() const;
+private:
+    // the list of all (simple) data objects whose formats we support
+    wxSimpleDataObjectList m_dataObjects;
 
-    // copy data to the given buffer
-    virtual void WriteData( void *dest ) const;
+    // the index of the preferred one (0 initially, so by default the first
+    // one is the preferred)
+    size_t m_preferred;
+};
 
-    // these functions are provided for wxGTK compatibility, their usage is
-    // deprecated - use GetFormat().SetId() instead
-    void SetId( const wxString& id ) { m_format.SetId(id); }
-    wxString GetId() const { return m_format.GetId(); }
+// ============================================================================
+// Standard implementations of wxDataObjectSimple which can be used directly
+// (i.e. without having to derive from them) for standard data type transfers.
+//
+// Note that although all of them can work with provided data, you can also
+// override their virtual GetXXX() functions to only provide data on demand.
+// ============================================================================
 
-    // implement the base class pure virtuals
-    virtual wxDataFormat GetPreferredFormat() const
-        { return m_format; }
-    virtual bool IsSupportedFormat(wxDataFormat format) const
-        { return m_format == format; }
-    virtual size_t GetDataSize() const
-        { return m_size; }
-    virtual void GetDataHere(void *dest) const
-        { WriteData(dest); }
+// ----------------------------------------------------------------------------
+// wxTextDataObject contains text data
+// ----------------------------------------------------------------------------
 
-    // the function which really copies the data - called by WriteData() above
-    // and uses GetSize() to get the size of the data
-    void WriteData( const void *data, void *dest ) const;
+class WXDLLEXPORT wxTextDataObject : public wxDataObjectSimple
+{
+public:
+    // ctor: you can specify the text here or in SetText(), or override
+    // GetText()
+    wxTextDataObject(const wxString& text = wxEmptyString)
+        : wxDataObjectSimple(wxDF_TEXT), m_text(text)
+        {
+        }
+
+    // virtual functions which you may override if you want to provide text on
+    // demand only - otherwise, the trivial default versions will be used
+    virtual size_t GetTextLength() const { return m_text.Len() + 1; }
+    virtual wxString GetText() const { return m_text; }
+    virtual void SetText(const wxString& text) { m_text = text; }
+
+    // implement base class pure virtuals
+    // ----------------------------------
+    virtual size_t GetDataSize() const;
+    virtual bool GetDataHere(void *buf) const;
+    virtual bool SetData(size_t len, const void *buf);
 
 private:
-    // free the data
-    inline void Free();
+    wxString m_text;
 
-    // the data
-    size_t     m_size;
-    void      *m_data;
+    // virtual function hiding supression
+    size_t GetDataSize(const wxDataFormat& format) const
+        { return(wxDataObjectSimple::GetDataSize(format)); }
+    bool GetDataHere(const wxDataFormat& format, void *pBuf) const
+        { return(wxDataObjectSimple::GetDataHere(format, pBuf)); }
+    bool SetData(const wxDataFormat& format, size_t nLen, const void* pBuf)
+        { return(wxDataObjectSimple::SetData(format, nLen, pBuf)); }
+};
 
-    // the data format
-    wxDataFormat m_format;
+// ----------------------------------------------------------------------------
+// wxBitmapDataObject contains a bitmap
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxBitmapDataObjectBase : public wxDataObjectSimple
+{
+public:
+    // ctor: you can specify the bitmap here or in SetBitmap(), or override
+    // GetBitmap()
+    wxBitmapDataObjectBase(const wxBitmap& bitmap = wxNullBitmap)
+        : wxDataObjectSimple(wxDF_BITMAP), m_bitmap(bitmap)
+        {
+        }
+
+    // virtual functions which you may override if you want to provide data on
+    // demand only - otherwise, the trivial default versions will be used
+    virtual wxBitmap GetBitmap() const { return m_bitmap; }
+    virtual void SetBitmap(const wxBitmap& bitmap) { m_bitmap = bitmap; }
+
+protected:
+    wxBitmap m_bitmap;
+};
+
+// ----------------------------------------------------------------------------
+// wxFileDataObject contains a list of filenames
+//
+// NB: notice that this is a "write only" object, it can only be filled with
+//     data from drag and drop operation.
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxFileDataObjectBase : public wxDataObjectSimple
+{
+public:
+    // ctor: use AddFile() later to fill the array
+    wxFileDataObjectBase() : wxDataObjectSimple(wxDF_FILENAME) { }
+
+    // get a reference to our array
+    const wxArrayString& GetFilenames() const { return m_filenames; }
+
+    // the Get() functions do nothing for us
+    virtual size_t GetDataSize() const { return 0; }
+    virtual bool GetDataHere(void *WXUNUSED(buf)) const { return FALSE; }
+
+protected:
+    wxArrayString m_filenames;
+
+private:
+    // Virtual function hiding supression
+    size_t GetDataSize(const wxDataFormat& format) const
+        { return(wxDataObjectSimple::GetDataSize(format)); }
+    bool GetDataHere(const wxDataFormat& format, void* pBuf) const
+        { return(wxDataObjectSimple::GetDataHere(format, pBuf)); }
 };
 
+// ----------------------------------------------------------------------------
+// wxCustomDataObject contains arbitrary untyped user data.
+//
+// It is understood that this data can be copied bitwise.
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxCustomDataObject : public wxDataObjectSimple
+{
+public:
+    // if you don't specify the format in the ctor, you can still use
+    // SetFormat() later
+    wxCustomDataObject(const wxDataFormat& format = wxFormatInvalid);
+
+    // the dtor calls Free()
+    virtual ~wxCustomDataObject();
+
+    // you can call SetData() to set m_data: it will make a copy of the data
+    // you pass - or you can use TakeData() which won't copy anything, but
+    // will take ownership of data (i.e. will call Free() on it later)
+    void TakeData(size_t size, void *data);
+
+    // this function is called to allocate "size" bytes of memory from
+    // SetData(). The default version uses operator new[].
+    virtual void *Alloc(size_t size);
+
+    // this function is called when the data is freed, you may override it to
+    // anything you want (or may be nothing at all). The default version calls
+    // operator delete[] on m_data
+    virtual void Free();
 
+    // get data: you may override these functions if you wish to provide data
+    // only when it's requested
+    virtual size_t GetSize() const { return m_size; }
+    virtual void *GetData() const { return m_data; }
+
+    // implement base class pure virtuals
+    // ----------------------------------
+    virtual size_t GetDataSize() const;
+    virtual bool GetDataHere(void *buf) const;
+    virtual bool SetData(size_t size, const void *buf);
+
+private:
+    size_t m_size;
+    void  *m_data;
+
+    // virtual function hiding supression
+    size_t GetDataSize(const wxDataFormat& format) const
+        { return(wxDataObjectSimple::GetDataSize(format)); }
+    bool GetDataHere(const wxDataFormat& format, void* pBuf) const
+        { return(wxDataObjectSimple::GetDataHere(format, pBuf)); }
+    bool SetData(const wxDataFormat& format, size_t nLen, const void* pBuf)
+        { return(wxDataObjectSimple::SetData(format, nLen, pBuf)); }
+};
+
+// ----------------------------------------------------------------------------
+// include platform-specific declarations of wxXXXBase classes
+// ----------------------------------------------------------------------------
+
+#if defined(__WXMSW__)
+    #include "wx/msw/ole/dataobj2.h"
+#elif defined(__WXMOTIF__)
+    // #include "wx/motif/dataobj2.h" -- not yet
+#elif defined(__WXGTK__)
+    #include "wx/gtk/dataobj2.h"
+#elif defined(__WXMAC__)
+    #include "wx/mac/dataobj2.h"
+#elif defined(__WXPM__)
+    #include "wx/os2/dataobj2.h"
 #endif
-    // _WX_DATAOBJ_H_BASE_
+
+#endif // _WX_DATAOBJ_H_BASE_