home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / common / dobjcmn.cpp < prev    next >
C/C++ Source or Header  |  2002-08-16  |  12KB  |  433 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name:        common/dobjcmn.cpp
  3. // Purpose:     implementation of data object methods common to all platforms
  4. // Author:      Vadim Zeitlin, Robert Roebling
  5. // Modified by:
  6. // Created:     19.10.99
  7. // RCS-ID:      $Id: dobjcmn.cpp,v 1.20 2002/08/15 20:47:04 RR Exp $
  8. // Copyright:   (c) wxWindows Team
  9. // Licence:     wxWindows license
  10. ///////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ============================================================================
  13. // declarations
  14. // ============================================================================
  15.  
  16. // ----------------------------------------------------------------------------
  17. // headers
  18. // ----------------------------------------------------------------------------
  19.  
  20. #ifdef __GNUG__
  21.     #pragma implementation "dataobjbase.h"
  22. #endif
  23.  
  24. #include "wx/wxprec.h"
  25.  
  26. #ifdef __BORLANDC__
  27.     #pragma hdrstop
  28. #endif
  29.  
  30. #if wxUSE_DATAOBJ
  31.  
  32. #ifndef WX_PRECOMP
  33.     #include "wx/app.h"
  34.     #include "wx/debug.h"
  35. #endif // WX_PRECOMP
  36.  
  37. #include "wx/dataobj.h"
  38.  
  39. // ----------------------------------------------------------------------------
  40. // lists
  41. // ----------------------------------------------------------------------------
  42.  
  43. #include "wx/listimpl.cpp"
  44.  
  45. WX_DEFINE_LIST(wxSimpleDataObjectList);
  46.  
  47. // ----------------------------------------------------------------------------
  48. // globals
  49. // ----------------------------------------------------------------------------
  50.  
  51. static wxDataFormat dataFormatInvalid;
  52. WXDLLEXPORT const wxDataFormat& wxFormatInvalid = dataFormatInvalid;
  53.  
  54. // ============================================================================
  55. // implementation
  56. // ============================================================================
  57.  
  58. // ----------------------------------------------------------------------------
  59. // wxDataObjectBase
  60. // ----------------------------------------------------------------------------
  61.  
  62. wxDataObjectBase::~wxDataObjectBase()
  63. {
  64. }
  65.  
  66. bool wxDataObjectBase::IsSupported(const wxDataFormat& format,
  67.                                    Direction dir) const
  68. {
  69.     size_t nFormatCount = GetFormatCount(dir);
  70.     if ( nFormatCount == 1 )
  71.     {
  72.         return format == GetPreferredFormat(dir);
  73.     }
  74.     else
  75.     {
  76.         wxDataFormat *formats = new wxDataFormat[nFormatCount];
  77.         GetAllFormats(formats, dir);
  78.  
  79.         size_t n;
  80.         for ( n = 0; n < nFormatCount; n++ )
  81.         {
  82.             if ( formats[n] == format )
  83.                 break;
  84.         }
  85.  
  86.         delete [] formats;
  87.  
  88.         // found?
  89.         return n < nFormatCount;
  90.     }
  91. }
  92.  
  93. // ----------------------------------------------------------------------------
  94. // wxDataObjectComposite
  95. // ----------------------------------------------------------------------------
  96.  
  97. wxDataObjectComposite::wxDataObjectComposite()
  98. {
  99.     m_preferred = 0;
  100.  
  101.     m_dataObjects.DeleteContents(TRUE);
  102. }
  103.  
  104. wxDataObjectSimple *
  105. wxDataObjectComposite::GetObject(const wxDataFormat& format) const
  106. {
  107.     wxSimpleDataObjectList::Node *node = m_dataObjects.GetFirst();
  108.     while ( node )
  109.     {
  110.         wxDataObjectSimple *dataObj = node->GetData();
  111.  
  112.         if ( dataObj->GetFormat() == format )
  113.         {
  114.             return dataObj;
  115.         }
  116.  
  117.         node = node->GetNext();
  118.     }
  119.  
  120.     return (wxDataObjectSimple *)NULL;
  121. }
  122.  
  123. void wxDataObjectComposite::Add(wxDataObjectSimple *dataObject, bool preferred)
  124. {
  125.     if ( preferred )
  126.         m_preferred = m_dataObjects.GetCount();
  127.  
  128.     m_dataObjects.Append( dataObject );
  129. }
  130.  
  131. wxDataFormat
  132. wxDataObjectComposite::GetPreferredFormat(Direction WXUNUSED(dir)) const
  133. {
  134.     wxSimpleDataObjectList::Node *node = m_dataObjects.Item( m_preferred );
  135.  
  136.     wxCHECK_MSG( node, wxFormatInvalid, wxT("no preferred format") );
  137.  
  138.     wxDataObjectSimple* dataObj = node->GetData();
  139.  
  140.     return dataObj->GetFormat();
  141. }
  142.  
  143. #if defined(__WXMSW__)
  144.  
  145. size_t wxDataObjectComposite::GetBufferOffset( const wxDataFormat& format )
  146. {
  147.     wxDataObjectSimple *dataObj = GetObject(format);
  148.  
  149.     wxCHECK_MSG( dataObj, 0,
  150.                  wxT("unsupported format in wxDataObjectComposite"));
  151.  
  152.     return dataObj->GetBufferOffset( format );
  153. }
  154.  
  155. const void* wxDataObjectComposite::GetSizeFromBuffer( const void* buffer,
  156.                                                       size_t* size,
  157.                                                       const wxDataFormat& format )
  158. {
  159.     wxDataObjectSimple *dataObj = GetObject(format);
  160.  
  161.     wxCHECK_MSG( dataObj, NULL,
  162.                  wxT("unsupported format in wxDataObjectComposite"));
  163.  
  164.     return dataObj->GetSizeFromBuffer( buffer, size, format );
  165. }
  166.  
  167. void* wxDataObjectComposite::SetSizeInBuffer( void* buffer, size_t size,
  168.                                               const wxDataFormat& format )
  169. {
  170.     wxDataObjectSimple *dataObj = GetObject(format);
  171.  
  172.     wxCHECK_MSG( dataObj, NULL,
  173.                  wxT("unsupported format in wxDataObjectComposite"));
  174.  
  175.     return dataObj->SetSizeInBuffer( buffer, size, format );
  176. }
  177.  
  178. #endif
  179.  
  180. size_t wxDataObjectComposite::GetFormatCount(Direction WXUNUSED(dir)) const
  181. {
  182.     // TODO what about the Get/Set only formats?
  183.     return m_dataObjects.GetCount();
  184. }
  185.  
  186. void wxDataObjectComposite::GetAllFormats(wxDataFormat *formats,
  187.                                           Direction WXUNUSED(dir)) const
  188. {
  189.     size_t n = 0;
  190.     wxSimpleDataObjectList::Node *node;
  191.     for ( node = m_dataObjects.GetFirst(); node; node = node->GetNext() )
  192.     {
  193.         // TODO if ( !outputOnlyToo ) && this one counts ...
  194.         formats[n++] = node->GetData()->GetFormat();
  195.     }
  196. }
  197.  
  198. size_t wxDataObjectComposite::GetDataSize(const wxDataFormat& format) const
  199. {
  200.     wxDataObjectSimple *dataObj = GetObject(format);
  201.  
  202.     wxCHECK_MSG( dataObj, 0,
  203.                  wxT("unsupported format in wxDataObjectComposite"));
  204.  
  205.     return dataObj->GetDataSize();
  206. }
  207.  
  208. bool wxDataObjectComposite::GetDataHere(const wxDataFormat& format,
  209.                                         void *buf) const
  210. {
  211.     wxDataObjectSimple *dataObj = GetObject(format);
  212.  
  213.     wxCHECK_MSG( dataObj, FALSE,
  214.                  wxT("unsupported format in wxDataObjectComposite"));
  215.  
  216.     return dataObj->GetDataHere(buf);
  217. }
  218.  
  219. bool wxDataObjectComposite::SetData(const wxDataFormat& format,
  220.                                     size_t len,
  221.                                     const void *buf)
  222. {
  223.     wxDataObjectSimple *dataObj = GetObject(format);
  224.  
  225.     wxCHECK_MSG( dataObj, FALSE,
  226.                  wxT("unsupported format in wxDataObjectComposite"));
  227.  
  228.     return dataObj->SetData(len, buf);
  229. }
  230.  
  231. // ----------------------------------------------------------------------------
  232. // wxTextDataObject
  233. // ----------------------------------------------------------------------------
  234.  
  235. size_t wxTextDataObject::GetDataSize() const
  236. {
  237. #if defined(__WXGTK20__) && wxUSE_UNICODE
  238.     // Use UTF8 not UCS4
  239.     wxCharBuffer buffer = wxConvUTF8.cWX2MB( GetText().c_str() );
  240.     return strlen( (const char*) buffer ) + 1;
  241. #else
  242.     return GetTextLength() * sizeof(wxChar);
  243. #endif
  244. }
  245.  
  246. bool wxTextDataObject::GetDataHere(void *buf) const
  247. {
  248. #if defined(__WXGTK20__) && wxUSE_UNICODE
  249.     // Use UTF8 not UCS4
  250.     wxCharBuffer buffer = wxConvUTF8.cWX2MB( GetText().c_str() );
  251.     strcpy( (char*) buf, (const char*) buffer );
  252. #else
  253.     wxStrcpy((wxChar *)buf, GetText().c_str());
  254. #endif
  255.  
  256.     return TRUE;
  257. }
  258.  
  259. bool wxTextDataObject::SetData(size_t WXUNUSED(len), const void *buf)
  260. {
  261. #if defined(__WXGTK20__) && wxUSE_UNICODE
  262.     // Use UTF8 not UCS4
  263.     SetText( wxConvUTF8.cMB2WX( (const char*) buf ) );
  264. #else
  265.     SetText(wxString((const wxChar *)buf));
  266. #endif
  267.  
  268.     return TRUE;
  269. }
  270.  
  271. // ----------------------------------------------------------------------------
  272. // wxFileDataObjectBase
  273. // ----------------------------------------------------------------------------
  274.  
  275. // VZ: I don't need this in MSW finally, so if it is needed in wxGTK, it should
  276. //     be moved to gtk/dataobj.cpp
  277. #if 0
  278.  
  279. wxString wxFileDataObjectBase::GetFilenames() const
  280. {
  281.     wxString str;
  282.     size_t count = m_filenames.GetCount();
  283.     for ( size_t n = 0; n < count; n++ )
  284.     {
  285.         str << m_filenames[n] << wxT('\0');
  286.     }
  287.  
  288.     return str;
  289. }
  290.  
  291. void wxFileDataObjectBase::SetFilenames(const wxChar* filenames)
  292. {
  293.     m_filenames.Empty();
  294.  
  295.     wxString current;
  296.     for ( const wxChar *pc = filenames; ; pc++ )
  297.     {
  298.         if ( *pc )
  299.         {
  300.             current += *pc;
  301.         }
  302.         else
  303.         {
  304.             if ( !current )
  305.             {
  306.                 // 2 consecutive NULs - this is the end of the string
  307.                 break;
  308.             }
  309.  
  310.             m_filenames.Add(current);
  311.             current.Empty();
  312.         }
  313.     }
  314. }
  315.  
  316. #endif // 0
  317.  
  318. // ----------------------------------------------------------------------------
  319. // wxCustomDataObject
  320. // ----------------------------------------------------------------------------
  321.  
  322. wxCustomDataObject::wxCustomDataObject(const wxDataFormat& format)
  323.     : wxDataObjectSimple(format)
  324. {
  325.     m_data = (void *)NULL;
  326. }
  327.  
  328. wxCustomDataObject::~wxCustomDataObject()
  329. {
  330.     Free();
  331. }
  332.  
  333. void wxCustomDataObject::TakeData(size_t size, void *data)
  334. {
  335.     Free();
  336.  
  337.     m_size = size;
  338.     m_data = data;
  339. }
  340.  
  341. void *wxCustomDataObject::Alloc(size_t size)
  342. {
  343.     return (void *)new char[size];
  344. }
  345.  
  346. void wxCustomDataObject::Free()
  347. {
  348.     delete [] (char *)m_data;
  349.     m_size = 0;
  350.     m_data = (void *)NULL;
  351. }
  352.  
  353. size_t wxCustomDataObject::GetDataSize() const
  354. {
  355.     return GetSize();
  356. }
  357.  
  358. bool wxCustomDataObject::GetDataHere(void *buf) const
  359. {
  360.     void *data = GetData();
  361.     if ( !data )
  362.         return FALSE;
  363.  
  364.     memcpy(buf, data, GetSize());
  365.  
  366.     return TRUE;
  367. }
  368.  
  369. bool wxCustomDataObject::SetData(size_t size, const void *buf)
  370. {
  371.     Free();
  372.  
  373.     m_data = Alloc(size);
  374.     if ( !m_data )
  375.         return FALSE;
  376.  
  377.     memcpy(m_data, buf, m_size = size);
  378.  
  379.     return TRUE;
  380. }
  381.  
  382. // ============================================================================
  383. // some common dnd related code
  384. // ============================================================================
  385.  
  386. #if wxUSE_DRAG_AND_DROP
  387.  
  388. #include "wx/dnd.h"
  389.  
  390. // ----------------------------------------------------------------------------
  391. // wxTextDropTarget
  392. // ----------------------------------------------------------------------------
  393.  
  394. // NB: we can't use "new" in ctor initializer lists because this provokes an
  395. //     internal compiler error with VC++ 5.0 (hey, even gcc compiles this!),
  396. //     so use SetDataObject() instead
  397.  
  398. wxTextDropTarget::wxTextDropTarget()
  399. {
  400.     SetDataObject(new wxTextDataObject);
  401. }
  402.  
  403. wxDragResult wxTextDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult def)
  404. {
  405.     if ( !GetData() )
  406.         return wxDragNone;
  407.  
  408.     wxTextDataObject *dobj = (wxTextDataObject *)m_dataObject;
  409.     return OnDropText(x, y, dobj->GetText()) ? def : wxDragNone;
  410. }
  411.  
  412. // ----------------------------------------------------------------------------
  413. // wxFileDropTarget
  414. // ----------------------------------------------------------------------------
  415.  
  416. wxFileDropTarget::wxFileDropTarget()
  417. {
  418.     SetDataObject(new wxFileDataObject);
  419. }
  420.  
  421. wxDragResult wxFileDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult def)
  422. {
  423.     if ( !GetData() )
  424.         return wxDragNone;
  425.  
  426.     wxFileDataObject *dobj = (wxFileDataObject *)m_dataObject;
  427.     return OnDropFiles(x, y, dobj->GetFilenames()) ? def : wxDragNone;
  428. }
  429.  
  430. #endif // wxUSE_DRAG_AND_DROP
  431.  
  432. #endif // wxUSE_DATAOBJ
  433.