]> git.saurik.com Git - wxWidgets.git/commitdiff
Added wxCountingStream for measuring the size of streamed data
authorRobert Roebling <robert@roebling.de>
Sun, 22 Aug 1999 14:10:50 +0000 (14:10 +0000)
committerRobert Roebling <robert@roebling.de>
Sun, 22 Aug 1999 14:10:50 +0000 (14:10 +0000)
  Added wxBitmapObject for putting it on the clipboard

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3439 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

12 files changed:
include/wx/gtk/dataobj.h
include/wx/gtk1/dataobj.h
include/wx/stream.h
samples/dnd/Makefile.in
samples/dnd/dnd.cpp
samples/dnd/julian.png [new file with mode: 0644]
src/common/stream.cpp
src/gtk/clipbrd.cpp
src/gtk/dataobj.cpp
src/gtk1/clipbrd.cpp
src/gtk1/dataobj.cpp
utils/wxMMedia2/lib/cdbase.h

index e8d598e3ddc2b4487e59910650d670e147546687..d79e1b63c8fd0ebad371043600e1ecf888915aca 100644 (file)
@@ -37,8 +37,6 @@ class wxFileDataObject;
 
 class wxDataFormat : public wxObject
 {
-    DECLARE_CLASS( wxDataFormat )
-
 public:
     wxDataFormat();
     wxDataFormat( wxDataFormatId type );
@@ -73,6 +71,11 @@ private:
     wxString    m_id;
     bool        m_hasAtom;
     GdkAtom     m_atom;
+    
+    void PrepareFormats();
+
+private:
+    DECLARE_CLASS( wxDataFormat )
 };
 
 //-------------------------------------------------------------------------
@@ -81,44 +84,41 @@ private:
 
 class wxDataBroker : public wxObject
 {
-  DECLARE_CLASS( wxDataBroker )
-
 public:
+    /* constructor */
+    wxDataBroker();
 
-  /* constructor */
-  wxDataBroker();
-
-  /* add data object */
-  void Add( wxDataObject *dataObject, bool preferred = FALSE );
+    /* add data object */
+    void Add( wxDataObject *dataObject, bool preferred = FALSE );
 
 private:
+    /* OLE implementation, the methods don't need to be overridden */
 
-  /* OLE implementation, the methods don't need to be overridden */
-
-  /* get number of supported formats */
-  virtual size_t GetFormatCount() const;
-
-  /* return nth supported format */
-  virtual wxDataFormat &GetNthFormat( size_t nth ) const;
+    /* get number of supported formats */
+    virtual size_t GetFormatCount() const;
 
-  /* return preferrd/best supported format */
-  virtual wxDataFormatId GetPreferredFormat() const;
+    /* return nth supported format */
+    virtual wxDataFormat &GetNthFormat( size_t nth ) const;
 
-  /* search through m_dataObjects, return TRUE if found */
-  virtual bool IsSupportedFormat( wxDataFormat &format ) const;
+    /* return preferrd/best supported format */
+    virtual wxDataFormatId GetPreferredFormat() const;
 
-  /* search through m_dataObjects and call child's GetSize() */
-  virtual size_t GetSize( wxDataFormat& format ) const;
+    /* search through m_dataObjects, return TRUE if found */
+    virtual bool IsSupportedFormat( wxDataFormat &format ) const;
 
-  /* search through m_dataObjects and call child's WriteData(dest) */
-  virtual void WriteData( wxDataFormat& format, void *dest ) const;
+    /* search through m_dataObjects and call child's GetSize() */
+    virtual size_t GetSize( wxDataFormat& format ) const;
 
-  /* implementation */
+    /* search through m_dataObjects and call child's WriteData(dest) */
+    virtual void WriteData( wxDataFormat& format, void *dest ) const;
 
 public:
-
-  wxList    m_dataObjects;
-  size_t    m_preferred;
+    /* implementation */
+    wxList    m_dataObjects;
+    size_t    m_preferred;
+  
+private:
+    DECLARE_CLASS( wxDataBroker )
 };
 
 //----------------------------------------------------------------------------
@@ -127,31 +127,31 @@ public:
 
 class wxDataObject : public wxObject
 {
-  DECLARE_DYNAMIC_CLASS( wxDataObject )
-
 public:
+    /* constructor */
+    wxDataObject();
 
-  /* constructor */
-  wxDataObject();
-
-  /* destructor */
-  ~wxDataObject();
+    /* destructor */
+    ~wxDataObject();
 
-  /* write data to dest */
-  virtual void WriteData( void *dest ) const = 0;
+    /* write data to dest */
+    virtual void WriteData( void *dest ) const = 0;
 
-  /* get size of data */
-  virtual size_t GetSize() const = 0;
+    /* get size of data */
+    virtual size_t GetSize() const = 0;
 
-  /* implementation */
-
-  wxDataFormat &GetFormat();
+public:
+    /* implementation */
+    wxDataFormat m_format;
+    
+    wxDataFormat &GetFormat();
 
-  wxDataFormatId GetFormatType() const;
-  wxString   GetFormatId() const;
-  GdkAtom    GetFormatAtom() const;
+    wxDataFormatId GetFormatType() const;
+    wxString   GetFormatId() const;
+    GdkAtom    GetFormatAtom() const;
 
-  wxDataFormat m_format;
+private:
+    DECLARE_DYNAMIC_CLASS( wxDataObject )
 };
 
 //----------------------------------------------------------------------------
@@ -160,37 +160,37 @@ public:
 
 class wxTextDataObject : public wxDataObject
 {
-  DECLARE_DYNAMIC_CLASS( wxTextDataObject )
-
 public:
+    /* default constructor. call SetText() later or override
+       WriteData() and GetSize() for working on-demand */
+    wxTextDataObject();
 
-  /* default constructor. call SetText() later or override
-     WriteData() and GetSize() for working on-demand */
-  wxTextDataObject();
+    /* constructor */
+    wxTextDataObject( const wxString& data );
 
-  /* constructor */
-  wxTextDataObject( const wxString& data );
+    /* set current text data */
+    void SetText( const wxString& data );
 
-  /* set current text data */
-  void SetText( const wxString& data );
+    /* get current text data */
+    wxString GetText() const;
 
-  /* get current text data */
-  wxString GetText() const;
+    /* by default calls WriteString() with string set by constructor or
+       by SetText(). can be overridden for working on-demand */
+    virtual void WriteData( void *dest ) const;
 
-  /* by default calls WriteString() with string set by constructor or
-     by SetText(). can be overridden for working on-demand */
-  virtual void WriteData( void *dest ) const;
+    /* by default, returns length of string as set by constructor or
+       by SetText(). can be overridden for working on-demand */
+    virtual size_t GetSize() const;
 
-  /* by default, returns length of string as set by constructor or
-     by SetText(). can be overridden for working on-demand */
-  virtual size_t GetSize() const;
+    /* write string to dest */
+    void WriteString( const wxString &str, void *dest ) const;
 
-  /* write string to dest */
-  void WriteString( const wxString &str, void *dest ) const;
-
-  /* implementation */
+public:
+    /* implementation */
+    wxString  m_data;
 
-  wxString  m_data;
+private:
+    DECLARE_DYNAMIC_CLASS( wxTextDataObject )
 };
 
 //----------------------------------------------------------------------------
@@ -199,29 +199,29 @@ public:
 
 class wxFileDataObject : public wxDataObject
 {
-  DECLARE_DYNAMIC_CLASS( wxFileDataObject )
-
 public:
+    /* default constructor */
+    wxFileDataObject();
 
-  /* default constructor */
-  wxFileDataObject();
-
-  /* add file name to list */
-  void AddFile( const wxString &file );
+    /* add file name to list */
+    void AddFile( const wxString &file );
 
-  /* get all filename as one string. each file name is 0 terminated,
-     the list is double zero terminated */
-  wxString GetFiles() const;
+    /* get all filename as one string. each file name is 0 terminated,
+       the list is double zero terminated */
+    wxString GetFiles() const;
 
-  /* write list of filenames */
-  virtual void WriteData( void *dest ) const;
+    /* write list of filenames */
+    virtual void WriteData( void *dest ) const;
 
-  /* return length of list of filenames */
-  virtual size_t GetSize() const;
+    /* return length of list of filenames */
+    virtual size_t GetSize() const;
 
-  /* implementation */
-
-  wxString  m_files;
+public:
+    /* implementation */
+    wxString  m_files;
+  
+private:
+    DECLARE_DYNAMIC_CLASS( wxFileDataObject )
 };
 
 //----------------------------------------------------------------------------
@@ -230,27 +230,32 @@ public:
 
 class wxBitmapDataObject : public wxDataObject
 {
-  DECLARE_DYNAMIC_CLASS( wxBitmapDataObject )
-
 public:
-
-  /* see wxTextDataObject for explanation */
-
-  wxBitmapDataObject();
-  wxBitmapDataObject( const wxBitmap& bitmap );
-
-  void SetBitmap( const wxBitmap &bitmap );
-  wxBitmap GetBitmap() const;
-
-  virtual void WriteData( void *dest ) const;
-  virtual size_t GetSize() const;
-
-  void WriteBitmap( const wxBitmap &bitmap, void *dest ) const;
-
-  // implementation
-
-  wxBitmap  m_bitmap;
-
+    /* see wxTextDataObject for explanation */
+    wxBitmapDataObject();
+    wxBitmapDataObject( const wxBitmap& bitmap );
+    ~wxBitmapDataObject();
+
+    void SetBitmap( const wxBitmap &bitmap );
+    wxBitmap GetBitmap() const;
+
+    virtual void WriteData( void *dest ) const;
+    virtual size_t GetSize() const;
+    void *GetData() const { return (void*)m_pngData; }
+
+    void WriteBitmap( const wxBitmap &bitmap, void *dest ) const;
+    
+    void SetPngData( const char *pngData, size_t pngSize );
+
+private: 
+    wxBitmap    m_bitmap;
+    size_t      m_pngSize;
+    char       *m_pngData;
+  
+    void DoConvertToPng();
+private: 
+    DECLARE_DYNAMIC_CLASS( wxBitmapDataObject );
 };
 
 #endif
index e8d598e3ddc2b4487e59910650d670e147546687..d79e1b63c8fd0ebad371043600e1ecf888915aca 100644 (file)
@@ -37,8 +37,6 @@ class wxFileDataObject;
 
 class wxDataFormat : public wxObject
 {
-    DECLARE_CLASS( wxDataFormat )
-
 public:
     wxDataFormat();
     wxDataFormat( wxDataFormatId type );
@@ -73,6 +71,11 @@ private:
     wxString    m_id;
     bool        m_hasAtom;
     GdkAtom     m_atom;
+    
+    void PrepareFormats();
+
+private:
+    DECLARE_CLASS( wxDataFormat )
 };
 
 //-------------------------------------------------------------------------
@@ -81,44 +84,41 @@ private:
 
 class wxDataBroker : public wxObject
 {
-  DECLARE_CLASS( wxDataBroker )
-
 public:
+    /* constructor */
+    wxDataBroker();
 
-  /* constructor */
-  wxDataBroker();
-
-  /* add data object */
-  void Add( wxDataObject *dataObject, bool preferred = FALSE );
+    /* add data object */
+    void Add( wxDataObject *dataObject, bool preferred = FALSE );
 
 private:
+    /* OLE implementation, the methods don't need to be overridden */
 
-  /* OLE implementation, the methods don't need to be overridden */
-
-  /* get number of supported formats */
-  virtual size_t GetFormatCount() const;
-
-  /* return nth supported format */
-  virtual wxDataFormat &GetNthFormat( size_t nth ) const;
+    /* get number of supported formats */
+    virtual size_t GetFormatCount() const;
 
-  /* return preferrd/best supported format */
-  virtual wxDataFormatId GetPreferredFormat() const;
+    /* return nth supported format */
+    virtual wxDataFormat &GetNthFormat( size_t nth ) const;
 
-  /* search through m_dataObjects, return TRUE if found */
-  virtual bool IsSupportedFormat( wxDataFormat &format ) const;
+    /* return preferrd/best supported format */
+    virtual wxDataFormatId GetPreferredFormat() const;
 
-  /* search through m_dataObjects and call child's GetSize() */
-  virtual size_t GetSize( wxDataFormat& format ) const;
+    /* search through m_dataObjects, return TRUE if found */
+    virtual bool IsSupportedFormat( wxDataFormat &format ) const;
 
-  /* search through m_dataObjects and call child's WriteData(dest) */
-  virtual void WriteData( wxDataFormat& format, void *dest ) const;
+    /* search through m_dataObjects and call child's GetSize() */
+    virtual size_t GetSize( wxDataFormat& format ) const;
 
-  /* implementation */
+    /* search through m_dataObjects and call child's WriteData(dest) */
+    virtual void WriteData( wxDataFormat& format, void *dest ) const;
 
 public:
-
-  wxList    m_dataObjects;
-  size_t    m_preferred;
+    /* implementation */
+    wxList    m_dataObjects;
+    size_t    m_preferred;
+  
+private:
+    DECLARE_CLASS( wxDataBroker )
 };
 
 //----------------------------------------------------------------------------
@@ -127,31 +127,31 @@ public:
 
 class wxDataObject : public wxObject
 {
-  DECLARE_DYNAMIC_CLASS( wxDataObject )
-
 public:
+    /* constructor */
+    wxDataObject();
 
-  /* constructor */
-  wxDataObject();
-
-  /* destructor */
-  ~wxDataObject();
+    /* destructor */
+    ~wxDataObject();
 
-  /* write data to dest */
-  virtual void WriteData( void *dest ) const = 0;
+    /* write data to dest */
+    virtual void WriteData( void *dest ) const = 0;
 
-  /* get size of data */
-  virtual size_t GetSize() const = 0;
+    /* get size of data */
+    virtual size_t GetSize() const = 0;
 
-  /* implementation */
-
-  wxDataFormat &GetFormat();
+public:
+    /* implementation */
+    wxDataFormat m_format;
+    
+    wxDataFormat &GetFormat();
 
-  wxDataFormatId GetFormatType() const;
-  wxString   GetFormatId() const;
-  GdkAtom    GetFormatAtom() const;
+    wxDataFormatId GetFormatType() const;
+    wxString   GetFormatId() const;
+    GdkAtom    GetFormatAtom() const;
 
-  wxDataFormat m_format;
+private:
+    DECLARE_DYNAMIC_CLASS( wxDataObject )
 };
 
 //----------------------------------------------------------------------------
@@ -160,37 +160,37 @@ public:
 
 class wxTextDataObject : public wxDataObject
 {
-  DECLARE_DYNAMIC_CLASS( wxTextDataObject )
-
 public:
+    /* default constructor. call SetText() later or override
+       WriteData() and GetSize() for working on-demand */
+    wxTextDataObject();
 
-  /* default constructor. call SetText() later or override
-     WriteData() and GetSize() for working on-demand */
-  wxTextDataObject();
+    /* constructor */
+    wxTextDataObject( const wxString& data );
 
-  /* constructor */
-  wxTextDataObject( const wxString& data );
+    /* set current text data */
+    void SetText( const wxString& data );
 
-  /* set current text data */
-  void SetText( const wxString& data );
+    /* get current text data */
+    wxString GetText() const;
 
-  /* get current text data */
-  wxString GetText() const;
+    /* by default calls WriteString() with string set by constructor or
+       by SetText(). can be overridden for working on-demand */
+    virtual void WriteData( void *dest ) const;
 
-  /* by default calls WriteString() with string set by constructor or
-     by SetText(). can be overridden for working on-demand */
-  virtual void WriteData( void *dest ) const;
+    /* by default, returns length of string as set by constructor or
+       by SetText(). can be overridden for working on-demand */
+    virtual size_t GetSize() const;
 
-  /* by default, returns length of string as set by constructor or
-     by SetText(). can be overridden for working on-demand */
-  virtual size_t GetSize() const;
+    /* write string to dest */
+    void WriteString( const wxString &str, void *dest ) const;
 
-  /* write string to dest */
-  void WriteString( const wxString &str, void *dest ) const;
-
-  /* implementation */
+public:
+    /* implementation */
+    wxString  m_data;
 
-  wxString  m_data;
+private:
+    DECLARE_DYNAMIC_CLASS( wxTextDataObject )
 };
 
 //----------------------------------------------------------------------------
@@ -199,29 +199,29 @@ public:
 
 class wxFileDataObject : public wxDataObject
 {
-  DECLARE_DYNAMIC_CLASS( wxFileDataObject )
-
 public:
+    /* default constructor */
+    wxFileDataObject();
 
-  /* default constructor */
-  wxFileDataObject();
-
-  /* add file name to list */
-  void AddFile( const wxString &file );
+    /* add file name to list */
+    void AddFile( const wxString &file );
 
-  /* get all filename as one string. each file name is 0 terminated,
-     the list is double zero terminated */
-  wxString GetFiles() const;
+    /* get all filename as one string. each file name is 0 terminated,
+       the list is double zero terminated */
+    wxString GetFiles() const;
 
-  /* write list of filenames */
-  virtual void WriteData( void *dest ) const;
+    /* write list of filenames */
+    virtual void WriteData( void *dest ) const;
 
-  /* return length of list of filenames */
-  virtual size_t GetSize() const;
+    /* return length of list of filenames */
+    virtual size_t GetSize() const;
 
-  /* implementation */
-
-  wxString  m_files;
+public:
+    /* implementation */
+    wxString  m_files;
+  
+private:
+    DECLARE_DYNAMIC_CLASS( wxFileDataObject )
 };
 
 //----------------------------------------------------------------------------
@@ -230,27 +230,32 @@ public:
 
 class wxBitmapDataObject : public wxDataObject
 {
-  DECLARE_DYNAMIC_CLASS( wxBitmapDataObject )
-
 public:
-
-  /* see wxTextDataObject for explanation */
-
-  wxBitmapDataObject();
-  wxBitmapDataObject( const wxBitmap& bitmap );
-
-  void SetBitmap( const wxBitmap &bitmap );
-  wxBitmap GetBitmap() const;
-
-  virtual void WriteData( void *dest ) const;
-  virtual size_t GetSize() const;
-
-  void WriteBitmap( const wxBitmap &bitmap, void *dest ) const;
-
-  // implementation
-
-  wxBitmap  m_bitmap;
-
+    /* see wxTextDataObject for explanation */
+    wxBitmapDataObject();
+    wxBitmapDataObject( const wxBitmap& bitmap );
+    ~wxBitmapDataObject();
+
+    void SetBitmap( const wxBitmap &bitmap );
+    wxBitmap GetBitmap() const;
+
+    virtual void WriteData( void *dest ) const;
+    virtual size_t GetSize() const;
+    void *GetData() const { return (void*)m_pngData; }
+
+    void WriteBitmap( const wxBitmap &bitmap, void *dest ) const;
+    
+    void SetPngData( const char *pngData, size_t pngSize );
+
+private: 
+    wxBitmap    m_bitmap;
+    size_t      m_pngSize;
+    char       *m_pngData;
+  
+    void DoConvertToPng();
+private: 
+    DECLARE_DYNAMIC_CLASS( wxBitmapDataObject );
 };
 
 #endif
index d9fe1b89c00f6dc8ce8d41ce3c19351f6ab20bec..44660c9e90bd0e7a262dfe8b654110c02c41d1c6 100644 (file)
@@ -136,6 +136,28 @@ class WXDLLEXPORT wxOutputStream: public wxStreamBase {
   wxOutputStream& operator<<( __wxOutputManip func) { return func(*this); }
 };
 
+// ---------------------------------------------------------------------------
+// A stream for measuring streamed output
+// ---------------------------------------------------------------------------
+
+class wxCountingOutputStream: public wxOutputStream {
+ public:
+  wxCountingOutputStream();
+
+  size_t GetSize() const;
+  bool Ok() const { return TRUE; }
+
+ protected:
+
+  size_t OnSysWrite(const void *buffer, size_t size);
+  off_t OnSysSeek(off_t pos, wxSeekMode mode);
+  off_t OnSysTell() const;
+
+ protected:
+  size_t m_currentPos;
+};
+
+
 // ---------------------------------------------------------------------------
 // "Filter" streams
 // ---------------------------------------------------------------------------
index 7c88bd2be8dafcae69db6b5dd2325390e798d262..1afad34b83452defc1b1f02fccd0a672ffd44f52 100644 (file)
@@ -13,6 +13,8 @@ top_srcdir = @top_srcdir@
 top_builddir = ../..
 program_dir = samples/dnd
 
+DATAFILES=julian.png
+
 PROGRAM=dnd
 
 OBJECTS=$(PROGRAM).o
index 046f9431995d0aaa490e4267d8e1aad4755b2bf8..b8cc40a8c39361ecf1e7ee31c999b63a0e5ff1a2 100644 (file)
 #include "wx/wx.h"
 #endif
 
+#ifdef __WXMOTIF__
+    #error Sorry, drag and drop is not yet implemented on wxMotif.
+#endif
+
 #include "wx/intl.h"
 #include "wx/log.h"
 
 #include "wx/dnd.h"
 #include "wx/dirdlg.h"
-
-#ifdef __WXMOTIF__
-    #error Sorry, drag and drop is not yet implemented on wxMotif.
-#endif
+#include "wx/filedlg.h"
+#include "wx/image.h"
+#include "wx/clipbrd.h"
 
 #if defined(__WXGTK__) || defined(__WXMOTIF__)
     #include "mondrian.xpm"
 #endif
 
-#include "wx/clipbrd.h"
-
 // ----------------------------------------------------------------------------
 // Derive two simple classes which just put in the listbox the strings (text or
 // file names) we drop on them
@@ -95,6 +96,10 @@ public:
     void OnLogClear(wxCommandEvent& event);
     void OnCopy(wxCommandEvent& event);
     void OnPaste(wxCommandEvent& event);
+    void OnCopyBitmap(wxCommandEvent& event);
+    void OnPasteBitmap(wxCommandEvent& event);
+    void OnClipboardHasText(wxCommandEvent& event);
+    void OnClipboardHasBitmap(wxCommandEvent& event);
 
     void OnLeftDown(wxMouseEvent& event);
     void OnRightDown(wxMouseEvent& event);
@@ -102,13 +107,14 @@ public:
     DECLARE_EVENT_TABLE()
 
 private:
-        wxListBox  *m_ctrlFile,
-        *m_ctrlText;
-        wxTextCtrl *m_ctrlLog;
+    wxListBox  *m_ctrlFile,
+    *m_ctrlText;
+    wxTextCtrl *m_ctrlLog;
 
-        wxLog *m_pLog, *m_pLogPrev;
+    wxLog *m_pLog, *m_pLogPrev;
 
-        wxString m_strText;
+    wxString  m_strText;
+    wxBitmap  m_bitmap;
 };
 
 // ----------------------------------------------------------------------------
@@ -123,26 +129,38 @@ enum
     Menu_Help,
     Menu_Clear,
     Menu_Copy,
-    Menu_Paste
+    Menu_Paste,
+    Menu_CopyBitmap,
+    Menu_PasteBitmap,
+    Menu_HasText,
+    Menu_HasBitmap
 };
 
 BEGIN_EVENT_TABLE(DnDFrame, wxFrame)
-    EVT_MENU(Menu_Quit,  DnDFrame::OnQuit)
-    EVT_MENU(Menu_About, DnDFrame::OnAbout)
-    EVT_MENU(Menu_Drag,  DnDFrame::OnDrag)
-    EVT_MENU(Menu_Help,  DnDFrame::OnHelp)
-    EVT_MENU(Menu_Clear, DnDFrame::OnLogClear)
-    EVT_MENU(Menu_Copy,  DnDFrame::OnCopy)
-    EVT_MENU(Menu_Paste, DnDFrame::OnPaste)
-
-    EVT_LEFT_DOWN(       DnDFrame::OnLeftDown)
-    EVT_RIGHT_DOWN(      DnDFrame::OnRightDown)
-    EVT_PAINT(           DnDFrame::OnPaint)
+    EVT_MENU(Menu_Quit,       DnDFrame::OnQuit)
+    EVT_MENU(Menu_About,      DnDFrame::OnAbout)
+    EVT_MENU(Menu_Drag,       DnDFrame::OnDrag)
+    EVT_MENU(Menu_Help,       DnDFrame::OnHelp)
+    EVT_MENU(Menu_Clear,      DnDFrame::OnLogClear)
+    EVT_MENU(Menu_Copy,       DnDFrame::OnCopy)
+    EVT_MENU(Menu_Paste,      DnDFrame::OnPaste)
+    EVT_MENU(Menu_CopyBitmap, DnDFrame::OnCopyBitmap)
+    EVT_MENU(Menu_PasteBitmap,DnDFrame::OnPasteBitmap)
+    EVT_MENU(Menu_HasText,    DnDFrame::OnClipboardHasText)
+    EVT_MENU(Menu_HasBitmap,  DnDFrame::OnClipboardHasBitmap)
+
+    EVT_LEFT_DOWN(            DnDFrame::OnLeftDown)
+    EVT_RIGHT_DOWN(           DnDFrame::OnRightDown)
+    EVT_PAINT(                DnDFrame::OnPaint)
 END_EVENT_TABLE()
 
     // `Main program' equivalent, creating windows and returning main app frame
 bool DnDApp::OnInit()
 {
+#if wxUSE_LIBPNG
+    wxImage::AddHandler( new wxPNGHandler );
+#endif
+
     // create the main frame window
     DnDFrame *frame = new DnDFrame((wxFrame  *) NULL,
                                    "Drag-and-Drop/Clipboard wxWindows Sample",
@@ -181,9 +199,15 @@ DnDFrame::DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
     help_menu->Append(Menu_About, "&About");
 
     wxMenu *clip_menu = new wxMenu;
-    clip_menu->Append(Menu_Copy, "&Copy\tCtrl+C");
-    clip_menu->Append(Menu_Paste, "&Paste\tCtrl+V");
-
+    clip_menu->Append(Menu_Copy, "&Copy text\tCtrl+C");
+    clip_menu->Append(Menu_Paste, "&Paste text\tCtrl+V");
+    clip_menu->AppendSeparator();
+    clip_menu->Append(Menu_CopyBitmap, "&Copy bitmap");
+    clip_menu->Append(Menu_PasteBitmap, "&Paste bitmap");
+    clip_menu->AppendSeparator();
+    clip_menu->Append(Menu_HasText, "Clipboard has &text\tCtrl+T");
+    clip_menu->Append(Menu_HasBitmap, "Clipboard has a &bitmap\tCtrl+B");
+    
     wxMenuBar *menu_bar = new wxMenuBar;
     menu_bar->Append(file_menu, "&File");
     menu_bar->Append(log_menu,  "&Log");
@@ -198,58 +222,55 @@ DnDFrame::DnDFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
 
     wxString strFile("Drop files here!"), strText("Drop text on me");
 
-    m_ctrlFile  = new wxListBox(this, -1, pos, size, 1, &strFile, wxLB_HSCROLL);
-    m_ctrlText  = new wxListBox(this, -1, pos, size, 1, &strText, wxLB_HSCROLL);
+    m_ctrlFile  = new wxListBox(this, -1, pos, size, 1, &strFile, wxLB_HSCROLL | wxLB_ALWAYS_SB );
+    m_ctrlText  = new wxListBox(this, -1, pos, size, 1, &strText, wxLB_HSCROLL | wxLB_ALWAYS_SB );
 
     m_ctrlLog   = new wxTextCtrl(this, -1, "", pos, size,
                                wxTE_MULTILINE | wxTE_READONLY |
                                wxSUNKEN_BORDER );
-
-#if wxUSE_STD_IOSTREAM  
-// redirect log messages to the text window (don't forget to delete it!)
-  m_pLog = new wxLogTextCtrl(m_ctrlLog);
-  m_pLogPrev = wxLog::SetActiveTarget(m_pLog);
-#endif
-
-  // associate drop targets with 2 text controls
-  m_ctrlFile->SetDropTarget(new DnDFile(m_ctrlFile));
-  m_ctrlText->SetDropTarget(new DnDText(m_ctrlText));
-
-  wxLayoutConstraints *c;
-
-  // Top-left listbox
-  c = new wxLayoutConstraints;
-  c->left.SameAs(this, wxLeft);
-  c->top.SameAs(this, wxTop);
-  c->right.PercentOf(this, wxRight, 50);
-  c->height.PercentOf(this, wxHeight, 40);
-  m_ctrlFile->SetConstraints(c);
-
-  // Top-right listbox
-  c = new wxLayoutConstraints;
-  c->left.SameAs    (m_ctrlFile, wxRight);
-  c->top.SameAs     (this, wxTop);
-  c->right.SameAs   (this, wxRight);
-  c->height.PercentOf(this, wxHeight, 40);
-  m_ctrlText->SetConstraints(c);
-
-  // Lower text control
-  c = new wxLayoutConstraints;
-  c->left.SameAs    (this, wxLeft);
-  c->right.SameAs   (this, wxRight);
-  c->height.PercentOf(this, wxHeight, 40);
-  c->top.SameAs(m_ctrlText, wxBottom);
-  m_ctrlLog->SetConstraints(c);
-
-  SetAutoLayout(TRUE);
+    // redirect log messages to the text window (don't forget to delete it!)
+    m_pLog = new wxLogTextCtrl(m_ctrlLog);
+    m_pLogPrev = wxLog::SetActiveTarget(m_pLog);
+
+    // associate drop targets with 2 text controls
+    m_ctrlFile->SetDropTarget(new DnDFile(m_ctrlFile));
+    m_ctrlText->SetDropTarget(new DnDText(m_ctrlText));
+
+    wxLayoutConstraints *c;
+
+    // Top-left listbox
+    c = new wxLayoutConstraints;
+    c->left.SameAs(this, wxLeft);
+    c->top.SameAs(this, wxTop);
+    c->right.PercentOf(this, wxRight, 50);
+    c->height.PercentOf(this, wxHeight, 30);
+    m_ctrlFile->SetConstraints(c);
+
+    // Top-right listbox
+    c = new wxLayoutConstraints;
+    c->left.SameAs    (m_ctrlFile, wxRight);
+    c->top.SameAs     (this, wxTop);
+    c->right.SameAs   (this, wxRight);
+    c->height.PercentOf(this, wxHeight, 30);
+    m_ctrlText->SetConstraints(c);
+
+    // Lower text control
+    c = new wxLayoutConstraints;
+    c->left.SameAs    (this, wxLeft);
+    c->right.SameAs   (this, wxRight);
+    c->height.PercentOf(this, wxHeight, 30);
+    c->top.SameAs(m_ctrlText, wxBottom);
+    m_ctrlLog->SetConstraints(c);
+
+    SetAutoLayout(TRUE);
 }
 
-void DnDFrame::OnQuit(wxCommandEvent& /* event */)
+void DnDFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
 {
     Close(TRUE);
 }
 
-void DnDFrame::OnPaint(wxPaintEvent& /*event*/)
+void DnDFrame::OnPaint(wxPaintEvent& WXUNUSED(event))
 {
     int w = 0;
     int h = 0;
@@ -257,10 +278,55 @@ void DnDFrame::OnPaint(wxPaintEvent& /*event*/)
 
     wxPaintDC dc(this);
     dc.SetFont( wxFont( 24, wxDECORATIVE, wxNORMAL, wxNORMAL, FALSE, "charter" ) );
-    dc.DrawText( "Drag text from here!", 20, h-35 );
+    dc.DrawText( "Drag text from here!", 20, h-50 );
+    
+    if (m_bitmap.Ok())
+        dc.DrawBitmap( m_bitmap, 280, h-120, TRUE );
 }
 
-void DnDFrame::OnDrag(wxCommandEvent& /* event */)
+void DnDFrame::OnClipboardHasText(wxCommandEvent& WXUNUSED(event))
+{
+    if ( !wxTheClipboard->Open() )
+    {
+        wxLogError( _T("Can't open clipboard.") );
+
+        return;
+    }
+
+    if ( !wxTheClipboard->IsSupported( wxDF_TEXT ) )
+    {
+        wxLogMessage( _T("No text is on the clipboard") );
+    }
+    else
+    {
+        wxLogMessage( _T("There is text is on the clipboard") );
+    }
+
+    wxTheClipboard->Close();
+}
+
+void DnDFrame::OnClipboardHasBitmap(wxCommandEvent& WXUNUSED(event))
+{
+    if ( !wxTheClipboard->Open() )
+    {
+        wxLogError( _T("Can't open clipboard.") );
+
+        return;
+    }
+
+    if ( !wxTheClipboard->IsSupported( wxDF_BITMAP ) )
+    {
+        wxLogMessage( _T("No bitmap is on the clipboard") );
+    }
+    else
+    {
+        wxLogMessage( _T("A bitmap is on the clipboard") );
+    }
+
+    wxTheClipboard->Close();
+}
+
+void DnDFrame::OnDrag(wxCommandEvent& WXUNUSED(event))
 {
     wxString strText = wxGetTextFromUser
         (
@@ -274,7 +340,7 @@ void DnDFrame::OnDrag(wxCommandEvent& /* event */)
     m_strText = strText;
 }
 
-void DnDFrame::OnAbout(wxCommandEvent& /* event */)
+void DnDFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
 {
     wxMessageBox("Drag-&-Drop Demo\n"
                  "Please see \"Help|Help...\" for details\n"
@@ -357,16 +423,108 @@ void DnDFrame::OnRightDown(wxMouseEvent &event )
 
 DnDFrame::~DnDFrame()
 {
-#if wxUSE_STD_IOSTREAM  
     if ( m_pLog != NULL ) {
         if ( wxLog::SetActiveTarget(m_pLogPrev) == m_pLog )
             delete m_pLog;
     }
-#endif
 }
 
 // ---------------------------------------------------------------------------
-// clipboard
+// bitmap clipboard
+// ---------------------------------------------------------------------------
+
+void DnDFrame::OnCopyBitmap(wxCommandEvent& WXUNUSED(event))
+{
+    wxFileDialog dialog(this, "Open a PNG file", "", "", "PNG files (*.png)|*.png", 0);
+
+    if (dialog.ShowModal() != wxID_OK)
+    { 
+        wxLogMessage( _T("Aborted file open") );
+        return;
+    }
+    
+    if (dialog.GetPath().IsEmpty())
+    { 
+        wxLogMessage( _T("Returned empty string.") );
+        return;
+    }
+    
+    if (!wxFileExists(dialog.GetPath()))
+    {
+        wxLogMessage( _T("File doesn't exist.") );
+        return;
+    }
+    
+    wxImage image;
+    image.LoadFile( dialog.GetPath(), wxBITMAP_TYPE_PNG );
+    if (!image.Ok())
+    {
+        wxLogMessage( _T("Invalid image file...") );
+        return;
+    }
+    
+    wxLogMessage( _T("Decoding image file...") );
+    wxYield();
+    
+    wxBitmap bitmap( image.ConvertToBitmap() );
+
+    if ( !wxTheClipboard->Open() )
+    {
+        wxLogError(_T("Can't open clipboard."));
+
+        return;
+    }
+
+    wxLogMessage( _T("Creating wxBitmapDataObject...") );
+    wxYield();
+    
+    if ( !wxTheClipboard->AddData(new wxBitmapDataObject(bitmap)) )
+    {
+        wxLogError(_T("Can't copy image to the clipboard."));
+    }
+    else
+    {
+        wxLogMessage(_T("Image has been put on the clipboard.") );
+        wxLogMessage(_T("You can paste it now and look at it.") );
+    }
+
+    wxTheClipboard->Close();
+}
+
+void DnDFrame::OnPasteBitmap(wxCommandEvent& WXUNUSED(event))
+{
+    if ( !wxTheClipboard->Open() )
+    {
+        wxLogError(_T("Can't open clipboard."));
+
+        return;
+    }
+
+    if ( !wxTheClipboard->IsSupported(wxDF_BITMAP) )
+    {
+        wxLogWarning(_T("No bitmap on clipboard"));
+
+        wxTheClipboard->Close();
+        return;
+    }
+
+    wxBitmapDataObject data;
+    if ( !wxTheClipboard->GetData(&data) )
+    {
+        wxLogError(_T("Can't paste bitmap from the clipboard"));
+    }
+    else
+    {
+        wxLogMessage(_T("Bitmap pasted from the clipboard") );
+       m_bitmap = data.GetBitmap();
+       Refresh();
+    }
+
+    wxTheClipboard->Close();
+}
+
+// ---------------------------------------------------------------------------
+// text clipboard
 // ---------------------------------------------------------------------------
 
 void DnDFrame::OnCopy(wxCommandEvent& WXUNUSED(event))
@@ -403,6 +561,7 @@ void DnDFrame::OnPaste(wxCommandEvent& WXUNUSED(event))
     {
         wxLogWarning(_T("No text data on clipboard"));
 
+        wxTheClipboard->Close();
         return;
     }
 
@@ -423,6 +582,7 @@ void DnDFrame::OnPaste(wxCommandEvent& WXUNUSED(event))
 // ----------------------------------------------------------------------------
 // Notifications called by the base class
 // ----------------------------------------------------------------------------
+
 bool DnDText::OnDropText( wxDropPointCoord, wxDropPointCoord, const wxChar *psz )
 {
     m_pOwner->Append(psz);
diff --git a/samples/dnd/julian.png b/samples/dnd/julian.png
new file mode 100644 (file)
index 0000000..9e875e0
Binary files /dev/null and b/samples/dnd/julian.png differ
index 76a0b3fdbf15bc4930f34fdc694386a90335f5a1..fdfc9123339422458b9a29b0742c56b2db1124ef 100644 (file)
@@ -645,9 +645,56 @@ wxOutputStream& wxOutputStream::operator<<(wxObject& obj)
 }
 #endif
 
+// ----------------------------------------------------------------------------
+// wxCountingOutputStream
+// ----------------------------------------------------------------------------
+
+wxCountingOutputStream::wxCountingOutputStream ()
+  : wxOutputStream()
+{
+   m_currentPos = 0;
+}
+
+size_t wxCountingOutputStream::GetSize() const
+{
+  return m_lastcount;
+}
+
+size_t wxCountingOutputStream::OnSysWrite(const void *buffer, size_t size)
+{
+  m_currentPos += size;
+  if (m_currentPos > m_lastcount) m_lastcount = m_currentPos;
+  return m_currentPos;
+}
+
+off_t wxCountingOutputStream::OnSysSeek(off_t pos, wxSeekMode mode)
+{
+  if (mode == wxFromStart)
+  {
+    m_currentPos = pos;
+  }
+  if (mode == wxFromEnd)
+  {
+    m_currentPos = m_lastcount + pos;
+  }
+  else
+  {
+    m_currentPos += pos;
+  }
+  if (m_currentPos > m_lastcount) m_lastcount = m_currentPos;
+  
+  return m_currentPos;  // ?
+}
+
+off_t wxCountingOutputStream::OnSysTell() const
+{
+  return m_currentPos;  // ?
+}
+  
 // ----------------------------------------------------------------------------
 // wxFilterInputStream
 // ----------------------------------------------------------------------------
+
 wxFilterInputStream::wxFilterInputStream()
   : wxInputStream()
 {
index 827e86ea22da383f6744af0444e3f3418814a2aa..d3cd53bc4e8530fea668afb86c9a885b87fa5d0b 100644 (file)
@@ -153,7 +153,7 @@ selection_received( GtkWidget *WXUNUSED(widget),
         clipboard->m_waiting = FALSE;
         return;
     }
-    
+
     /* make sure we got the data in the correct form (selection type).
        if so, copy data to target object */
     
@@ -178,12 +178,16 @@ selection_received( GtkWidget *WXUNUSED(widget),
        
        case wxDF_BITMAP:
        {
-            if (selection_data->type != GDK_SELECTION_TYPE_BITMAP)
+            if (selection_data->type != GDK_SELECTION_TYPE_STRING)
             {
                 clipboard->m_waiting = FALSE;
                 return;
             }
            
+           wxBitmapDataObject *bitmap_object = (wxBitmapDataObject *) data_object;
+           
+           bitmap_object->SetPngData( (const char*) selection_data->data, (size_t) selection_data->length );
+           
            break;
        }
        
@@ -268,7 +272,7 @@ selection_handler( GtkWidget *WXUNUSED(widget), GtkSelectionData *selection_data
     while (node)
     {
         wxDataObject *data_object = (wxDataObject *)node->Data();
-    
+       
        if (data_object->GetFormat().GetAtom() != selection_data->target)
        {
            node = node->Next();
@@ -303,10 +307,17 @@ selection_handler( GtkWidget *WXUNUSED(widget), GtkSelectionData *selection_data
            
            case wxDF_BITMAP:
            {
-               // wxBitmapDataObject *private_object = (wxBitmapDataObject*) data_object;
+               wxBitmapDataObject *bitmap_object = (wxBitmapDataObject*) data_object;
            
-               // how do we do that ?
-               
+               if (bitmap_object->GetSize() == 0) return;
+           
+                gtk_selection_data_set( 
+                    selection_data, 
+                   GDK_SELECTION_TYPE_STRING, 
+                   8*sizeof(gchar), 
+                   (unsigned char*) bitmap_object->GetData(), 
+                   (int) bitmap_object->GetSize() );
+                   
                break;
            }
            
index bb9e817c05304aa895feea142831dde22e273d31..1e87427cd71d24e8a2ae581faca475e00b0c5c77 100644 (file)
@@ -14,6 +14,8 @@
 #include "wx/dataobj.h"
 #include "wx/app.h"
 #include "wx/debug.h"
+#include "wx/mstream.h"
+#include "wx/image.h"
 
 #include "gdk/gdk.h"
 
@@ -23,6 +25,7 @@
 //-------------------------------------------------------------------------
 
 GdkAtom  g_textAtom        = 0;
+GdkAtom  g_pngAtom         = 0;
 
 //-------------------------------------------------------------------------
 // wxDataFormat
@@ -32,7 +35,7 @@ IMPLEMENT_CLASS(wxDataFormat, wxObject)
 
 wxDataFormat::wxDataFormat()
 {
-    if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
+    PrepareFormats();
     m_type = wxDF_INVALID;
     m_hasAtom = FALSE;
     m_atom = (GdkAtom) 0;
@@ -40,25 +43,25 @@ wxDataFormat::wxDataFormat()
 
 wxDataFormat::wxDataFormat( wxDataFormatId type )
 {
-    if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
+    PrepareFormats();
     SetType( type );
 }
 
 wxDataFormat::wxDataFormat( const wxChar *id )
 {
-    if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
+    PrepareFormats();
     SetId( id );
 }
 
 wxDataFormat::wxDataFormat( const wxString &id )
 {
-    if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
+    PrepareFormats();
     SetId( id );
 }
 
 wxDataFormat::wxDataFormat( const wxDataFormat &format )
 {
-    if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
+    PrepareFormats();
     m_type = format.GetType();
     m_id = format.GetId();
     m_hasAtom = TRUE;
@@ -67,7 +70,7 @@ wxDataFormat::wxDataFormat( const wxDataFormat &format )
 
 wxDataFormat::wxDataFormat( const GdkAtom atom )
 {
-    if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
+    PrepareFormats();
     m_hasAtom = TRUE;
 
     m_atom = atom;
@@ -102,7 +105,7 @@ void wxDataFormat::SetType( wxDataFormatId type )
     else
     if (m_type == wxDF_BITMAP)
     {
-        m_id = _T("BITMAP");
+        m_id = _T("image/png");
     }
     else
     if (m_type == wxDF_FILENAME)
@@ -169,6 +172,12 @@ GdkAtom wxDataFormat::GetAtom()
     return m_atom;
 }
 
+void wxDataFormat::PrepareFormats()
+{
+    if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
+    if (!g_pngAtom) g_pngAtom = gdk_atom_intern( "image/png", FALSE );
+}
+
 //-------------------------------------------------------------------------
 // wxDataBroker
 //-------------------------------------------------------------------------
@@ -385,18 +394,28 @@ IMPLEMENT_DYNAMIC_CLASS( wxBitmapDataObject, wxDataObject )
 wxBitmapDataObject::wxBitmapDataObject()
 {
     m_format.SetType( wxDF_BITMAP );
+    m_pngData = (char*)NULL;
+    m_pngSize = 0;
 }
 
 wxBitmapDataObject::wxBitmapDataObject( const wxBitmap& bitmap )
 {
     m_format.SetType( wxDF_BITMAP );
-
+    m_pngData = (char*)NULL;
+    m_pngSize = 0;
     m_bitmap = bitmap;
+    DoConvertToPng();
+}
+
+wxBitmapDataObject::~wxBitmapDataObject()
+{
+    if (m_pngData) delete[] m_pngData;
 }
 
 void wxBitmapDataObject::SetBitmap( const wxBitmap &bitmap )
 {
     m_bitmap = bitmap;
+    DoConvertToPng();
 }
 
 wxBitmap wxBitmapDataObject::GetBitmap() const
@@ -411,12 +430,44 @@ void wxBitmapDataObject::WriteData( void *dest ) const
 
 size_t wxBitmapDataObject::GetSize() const
 {
-    return 0;
+    return m_pngSize;
 }
 
 void wxBitmapDataObject::WriteBitmap( const wxBitmap &bitmap, void *dest ) const
 {
-    memcpy( dest, m_bitmap.GetPixmap(), GetSize() );
+//    if (m_bitmap == bitmap)
+        memcpy( dest, m_pngData, m_pngSize );
+}
+
+void wxBitmapDataObject::SetPngData( const char *pngData, size_t pngSize )
+{
+    if (m_pngData) delete[] m_pngData;
+    m_pngData = (char*) NULL;
+    m_pngSize = pngSize;
+    m_pngData = new char[m_pngSize];
+    memcpy( m_pngData, pngData, m_pngSize );
+    
+    wxMemoryInputStream mstream( pngData, pngSize );
+    wxImage image;
+    wxPNGHandler handler;
+    handler.LoadFile( &image, mstream );
+    m_bitmap = image.ConvertToBitmap();
+}
+
+void wxBitmapDataObject::DoConvertToPng()
+{
+    if (m_pngData) delete[] m_pngData;
+    
+    wxImage image( m_bitmap );
+    wxPNGHandler handler;
+    
+    wxCountingOutputStream count;
+    handler.SaveFile( &image, count );
+    m_pngSize = count.GetSize() + 100; // sometimes the size seems to vary ???
+    m_pngData = new char[m_pngSize];
+    
+    wxMemoryOutputStream mstream( m_pngData, m_pngSize );
+    handler.SaveFile( &image, mstream );
 }
 
 // ----------------------------------------------------------------------------
index 827e86ea22da383f6744af0444e3f3418814a2aa..d3cd53bc4e8530fea668afb86c9a885b87fa5d0b 100644 (file)
@@ -153,7 +153,7 @@ selection_received( GtkWidget *WXUNUSED(widget),
         clipboard->m_waiting = FALSE;
         return;
     }
-    
+
     /* make sure we got the data in the correct form (selection type).
        if so, copy data to target object */
     
@@ -178,12 +178,16 @@ selection_received( GtkWidget *WXUNUSED(widget),
        
        case wxDF_BITMAP:
        {
-            if (selection_data->type != GDK_SELECTION_TYPE_BITMAP)
+            if (selection_data->type != GDK_SELECTION_TYPE_STRING)
             {
                 clipboard->m_waiting = FALSE;
                 return;
             }
            
+           wxBitmapDataObject *bitmap_object = (wxBitmapDataObject *) data_object;
+           
+           bitmap_object->SetPngData( (const char*) selection_data->data, (size_t) selection_data->length );
+           
            break;
        }
        
@@ -268,7 +272,7 @@ selection_handler( GtkWidget *WXUNUSED(widget), GtkSelectionData *selection_data
     while (node)
     {
         wxDataObject *data_object = (wxDataObject *)node->Data();
-    
+       
        if (data_object->GetFormat().GetAtom() != selection_data->target)
        {
            node = node->Next();
@@ -303,10 +307,17 @@ selection_handler( GtkWidget *WXUNUSED(widget), GtkSelectionData *selection_data
            
            case wxDF_BITMAP:
            {
-               // wxBitmapDataObject *private_object = (wxBitmapDataObject*) data_object;
+               wxBitmapDataObject *bitmap_object = (wxBitmapDataObject*) data_object;
            
-               // how do we do that ?
-               
+               if (bitmap_object->GetSize() == 0) return;
+           
+                gtk_selection_data_set( 
+                    selection_data, 
+                   GDK_SELECTION_TYPE_STRING, 
+                   8*sizeof(gchar), 
+                   (unsigned char*) bitmap_object->GetData(), 
+                   (int) bitmap_object->GetSize() );
+                   
                break;
            }
            
index bb9e817c05304aa895feea142831dde22e273d31..1e87427cd71d24e8a2ae581faca475e00b0c5c77 100644 (file)
@@ -14,6 +14,8 @@
 #include "wx/dataobj.h"
 #include "wx/app.h"
 #include "wx/debug.h"
+#include "wx/mstream.h"
+#include "wx/image.h"
 
 #include "gdk/gdk.h"
 
@@ -23,6 +25,7 @@
 //-------------------------------------------------------------------------
 
 GdkAtom  g_textAtom        = 0;
+GdkAtom  g_pngAtom         = 0;
 
 //-------------------------------------------------------------------------
 // wxDataFormat
@@ -32,7 +35,7 @@ IMPLEMENT_CLASS(wxDataFormat, wxObject)
 
 wxDataFormat::wxDataFormat()
 {
-    if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
+    PrepareFormats();
     m_type = wxDF_INVALID;
     m_hasAtom = FALSE;
     m_atom = (GdkAtom) 0;
@@ -40,25 +43,25 @@ wxDataFormat::wxDataFormat()
 
 wxDataFormat::wxDataFormat( wxDataFormatId type )
 {
-    if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
+    PrepareFormats();
     SetType( type );
 }
 
 wxDataFormat::wxDataFormat( const wxChar *id )
 {
-    if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
+    PrepareFormats();
     SetId( id );
 }
 
 wxDataFormat::wxDataFormat( const wxString &id )
 {
-    if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
+    PrepareFormats();
     SetId( id );
 }
 
 wxDataFormat::wxDataFormat( const wxDataFormat &format )
 {
-    if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
+    PrepareFormats();
     m_type = format.GetType();
     m_id = format.GetId();
     m_hasAtom = TRUE;
@@ -67,7 +70,7 @@ wxDataFormat::wxDataFormat( const wxDataFormat &format )
 
 wxDataFormat::wxDataFormat( const GdkAtom atom )
 {
-    if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
+    PrepareFormats();
     m_hasAtom = TRUE;
 
     m_atom = atom;
@@ -102,7 +105,7 @@ void wxDataFormat::SetType( wxDataFormatId type )
     else
     if (m_type == wxDF_BITMAP)
     {
-        m_id = _T("BITMAP");
+        m_id = _T("image/png");
     }
     else
     if (m_type == wxDF_FILENAME)
@@ -169,6 +172,12 @@ GdkAtom wxDataFormat::GetAtom()
     return m_atom;
 }
 
+void wxDataFormat::PrepareFormats()
+{
+    if (!g_textAtom) g_textAtom = gdk_atom_intern( "STRING", FALSE );
+    if (!g_pngAtom) g_pngAtom = gdk_atom_intern( "image/png", FALSE );
+}
+
 //-------------------------------------------------------------------------
 // wxDataBroker
 //-------------------------------------------------------------------------
@@ -385,18 +394,28 @@ IMPLEMENT_DYNAMIC_CLASS( wxBitmapDataObject, wxDataObject )
 wxBitmapDataObject::wxBitmapDataObject()
 {
     m_format.SetType( wxDF_BITMAP );
+    m_pngData = (char*)NULL;
+    m_pngSize = 0;
 }
 
 wxBitmapDataObject::wxBitmapDataObject( const wxBitmap& bitmap )
 {
     m_format.SetType( wxDF_BITMAP );
-
+    m_pngData = (char*)NULL;
+    m_pngSize = 0;
     m_bitmap = bitmap;
+    DoConvertToPng();
+}
+
+wxBitmapDataObject::~wxBitmapDataObject()
+{
+    if (m_pngData) delete[] m_pngData;
 }
 
 void wxBitmapDataObject::SetBitmap( const wxBitmap &bitmap )
 {
     m_bitmap = bitmap;
+    DoConvertToPng();
 }
 
 wxBitmap wxBitmapDataObject::GetBitmap() const
@@ -411,12 +430,44 @@ void wxBitmapDataObject::WriteData( void *dest ) const
 
 size_t wxBitmapDataObject::GetSize() const
 {
-    return 0;
+    return m_pngSize;
 }
 
 void wxBitmapDataObject::WriteBitmap( const wxBitmap &bitmap, void *dest ) const
 {
-    memcpy( dest, m_bitmap.GetPixmap(), GetSize() );
+//    if (m_bitmap == bitmap)
+        memcpy( dest, m_pngData, m_pngSize );
+}
+
+void wxBitmapDataObject::SetPngData( const char *pngData, size_t pngSize )
+{
+    if (m_pngData) delete[] m_pngData;
+    m_pngData = (char*) NULL;
+    m_pngSize = pngSize;
+    m_pngData = new char[m_pngSize];
+    memcpy( m_pngData, pngData, m_pngSize );
+    
+    wxMemoryInputStream mstream( pngData, pngSize );
+    wxImage image;
+    wxPNGHandler handler;
+    handler.LoadFile( &image, mstream );
+    m_bitmap = image.ConvertToBitmap();
+}
+
+void wxBitmapDataObject::DoConvertToPng()
+{
+    if (m_pngData) delete[] m_pngData;
+    
+    wxImage image( m_bitmap );
+    wxPNGHandler handler;
+    
+    wxCountingOutputStream count;
+    handler.SaveFile( &image, count );
+    m_pngSize = count.GetSize() + 100; // sometimes the size seems to vary ???
+    m_pngData = new char[m_pngSize];
+    
+    wxMemoryOutputStream mstream( m_pngData, m_pngSize );
+    handler.SaveFile( &image, mstream );
 }
 
 // ----------------------------------------------------------------------------
index a46821b38c52f11655236899c56a83332e523b6b..427f62cafca7f74f98718862b786ad8d2a512b0b 100644 (file)
@@ -17,6 +17,8 @@
 
 #include "wx/wxprec.h"
 
+#include "wx/object.h"
+
 typedef struct wxCDtime {
   wxUint8 track;
   wxUint8 hour, min, sec;