1 /////////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxDataObject class 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling 
   7 // Licence:     wxWindows licence 
   8 /////////////////////////////////////////////////////////////////////////////// 
  11     #pragma implementation "dataobj.h" 
  14 #include "wx/dataobj.h" 
  17 #include "wx/mstream.h" 
  22 //------------------------------------------------------------------------- 
  24 //------------------------------------------------------------------------- 
  26 GdkAtom  g_textAtom        
= 0; 
  27 GdkAtom  g_pngAtom         
= 0; 
  28 GdkAtom  g_fileAtom        
= 0; 
  30 //------------------------------------------------------------------------- 
  32 //------------------------------------------------------------------------- 
  34 wxDataFormat::wxDataFormat() 
  36     // do *not* call PrepareFormats() from here for 2 reasons: 
  38     // 1. we will have time to do it later because some other Set function 
  39     //    must be called before we really need them 
  41     // 2. doing so prevents us from declaring global wxDataFormats because 
  42     //    calling PrepareFormats (and thus gdk_atom_intern) before GDK is 
  43     //    initialised will result in a crash 
  44     m_type 
= wxDF_INVALID
; 
  45     m_format 
= (GdkAtom
) 0; 
  48 wxDataFormat::wxDataFormat( wxDataFormatId type 
) 
  54 wxDataFormat::wxDataFormat( const wxChar 
*id 
) 
  60 wxDataFormat::wxDataFormat( const wxString 
&id 
) 
  66 wxDataFormat::wxDataFormat( NativeFormat format 
) 
  72 void wxDataFormat::SetType( wxDataFormatId type 
) 
  77     if (m_type 
== wxDF_TEXT
) 
  78         m_format 
= g_textAtom
; 
  80     if (m_type 
== wxDF_BITMAP
) 
  83     if (m_type 
== wxDF_FILENAME
) 
  84         m_format 
= g_fileAtom
; 
  87        wxFAIL_MSG( wxT("invalid dataformat") ); 
  91 wxDataFormatId 
wxDataFormat::GetType() const 
  96 wxString 
wxDataFormat::GetId() const 
  98     wxString 
ret( gdk_atom_name( m_format 
) );  // this will convert from ascii to Unicode 
 102 void wxDataFormat::SetId( NativeFormat format 
) 
 107     if (m_format 
== g_textAtom
) 
 110     if (m_format 
== g_pngAtom
) 
 111         m_type 
= wxDF_BITMAP
; 
 113     if (m_format 
== g_fileAtom
) 
 114         m_type 
= wxDF_FILENAME
; 
 116         m_type 
= wxDF_PRIVATE
; 
 119 void wxDataFormat::SetId( const wxChar 
*id 
) 
 122     m_type 
= wxDF_PRIVATE
; 
 124     m_format 
= gdk_atom_intern( wxMBSTRINGCAST tmp
.mbc_str(), FALSE 
);  // what is the string cast for? 
 127 void wxDataFormat::PrepareFormats() 
 129     // VZ: GNOME included in RedHat 6.1 uses the MIME types below and not the 
 130     //     atoms STRING and file:ALL as the old code was, but normal X apps 
 131     //     use STRING for text selection when transfering the data via 
 132     //     clipboard, for example, so do use STRING for now (GNOME apps will 
 133     //     probably support STRING as well for compatibility anyhow), but use 
 134     //     text/uri-list for file dnd because compatibility is not important 
 137         g_textAtom 
= gdk_atom_intern( "STRING" /* "text/plain" */, FALSE 
); 
 139         g_pngAtom 
= gdk_atom_intern( "image/png", FALSE 
); 
 141         g_fileAtom 
= gdk_atom_intern( "text/uri-list", FALSE 
); 
 144 //------------------------------------------------------------------------- 
 146 //------------------------------------------------------------------------- 
 148 wxDataObject::wxDataObject() 
 152 bool wxDataObject::IsSupportedFormat(const wxDataFormat
& format
, Direction dir
) const 
 154     size_t nFormatCount 
= GetFormatCount(dir
); 
 155     if ( nFormatCount 
== 1 ) { 
 156         return format 
== GetPreferredFormat(); 
 159         wxDataFormat 
*formats 
= new wxDataFormat
[nFormatCount
]; 
 160         GetAllFormats(formats
,dir
); 
 163         for ( n 
= 0; n 
< nFormatCount
; n
++ ) { 
 164             if ( formats
[n
] == format 
) 
 171         return n 
< nFormatCount
; 
 175 // ---------------------------------------------------------------------------- 
 177 // ---------------------------------------------------------------------------- 
 179 bool wxFileDataObject::GetDataHere(void *buf
) const 
 183     for (size_t i 
= 0; i 
< m_filenames
.GetCount(); i
++) 
 185         filenames 
+= m_filenames
[i
]; 
 186         filenames 
+= (wxChar
) 0; 
 189     memcpy( buf
, filenames
.mbc_str(), filenames
.Len() + 1 ); 
 194 size_t wxFileDataObject::GetDataSize() const 
 198     for (size_t i 
= 0; i 
< m_filenames
.GetCount(); i
++) 
 200         res 
+= m_filenames
[i
].Len(); 
 207 bool wxFileDataObject::SetData(size_t WXUNUSED(size
), const void *buf
) 
 211     // filenames are stores as a string with #0 as deliminators 
 212     const char *filenames 
= (const char*) buf
; 
 216         if (filenames
[0] == 0) 
 220         wxString 
file( filenames 
);  // this returns the first file 
 223         filenames 
+= file
.Len()+1; 
 228     // the text/uri-list format is a sequence of URIs (filenames prefixed by 
 229     // "file:" as far as I see) delimited by "\r\n" of total length size 
 230     // (I wonder what happens if the file has '\n' in its filename??) 
 232     for ( const char *p 
= (const char *)buf
; ; p
++ ) 
 234         // some broken programs (testdnd GTK+ sample!) omit the trailing 
 235         // "\r\n", so check for '\0' explicitly here instead of doing it in 
 236         // the loop statement to account for it 
 237         if ( (*p 
== '\r' && *(p
+1) == '\n') || !*p 
) 
 239             size_t lenPrefix 
= 5; // strlen("file:") 
 240             if ( filename
.Left(lenPrefix
).MakeLower() == _T("file:") ) 
 242                 // sometimes the syntax is "file:filename", sometimes it's 
 243                 // URL-like: "file://filename" - deal with both 
 244                 if ( filename
[lenPrefix
] == _T('/') && 
 245                      filename
[lenPrefix 
+ 1] == _T('/') ) 
 251                 AddFile(filename
.c_str() + lenPrefix
); 
 256                 wxLogDebug(_T("Unsupported URI '%s' in wxFileDataObject"), 
 276 void wxFileDataObject::AddFile( const wxString 
&filename 
) 
 278    m_filenames
.Add( filename 
); 
 281 // ---------------------------------------------------------------------------- 
 282 // wxBitmapDataObject 
 283 // ---------------------------------------------------------------------------- 
 285 wxBitmapDataObject::wxBitmapDataObject() 
 290 wxBitmapDataObject::wxBitmapDataObject( const wxBitmap
& bitmap 
) 
 291                   : wxBitmapDataObjectBase(bitmap
) 
 298 wxBitmapDataObject::~wxBitmapDataObject() 
 303 void wxBitmapDataObject::SetBitmap( const wxBitmap 
&bitmap 
) 
 307     wxBitmapDataObjectBase::SetBitmap(bitmap
); 
 312 bool wxBitmapDataObject::GetDataHere(void *buf
) const 
 316         wxFAIL_MSG( wxT("attempt to copy empty bitmap failed") ); 
 321     memcpy(buf
, m_pngData
, m_pngSize
); 
 326 bool wxBitmapDataObject::SetData(size_t size
, const void *buf
) 
 331     m_pngData 
= malloc(m_pngSize
); 
 333     memcpy( m_pngData
, buf
, m_pngSize 
); 
 335     wxMemoryInputStream 
mstream( (char*) m_pngData
, m_pngSize 
); 
 337     wxPNGHandler handler
; 
 338     if ( !handler
.LoadFile( &image
, mstream 
) ) 
 343     m_bitmap 
= image
.ConvertToBitmap(); 
 345     return m_bitmap
.Ok(); 
 348 void wxBitmapDataObject::DoConvertToPng() 
 353     wxImage 
image( m_bitmap 
); 
 354     wxPNGHandler handler
; 
 356     wxCountingOutputStream count
; 
 357     handler
.SaveFile( &image
, count 
); 
 359     m_pngSize 
= count
.GetSize() + 100; // sometimes the size seems to vary ??? 
 360     m_pngData 
= malloc(m_pngSize
); 
 362     wxMemoryOutputStream 
mstream( (char*) m_pngData
, m_pngSize 
); 
 363     handler
.SaveFile( &image
, mstream 
);