1///////////////////////////////////////////////////////////////////////////////
2// Name:        src/mac/classic/dataobj.cpp
3// Purpose:     implementation of wxDataObject class
4// Author:      Stefan Csomor
5// Modified by:
6// Created:     10/21/99
7// RCS-ID:      $Id: dataobj.cpp 40345 2006-07-27 12:57:16Z ABX $
8// Copyright:   (c) 1999 Stefan Csomor
9// Licence:     wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15    #pragma hdrstop
16#endif
17
18// ============================================================================
19// declarations
20// ============================================================================
21
22// ----------------------------------------------------------------------------
23// headers
24// ----------------------------------------------------------------------------
25
26#include "wx/dataobj.h"
27
28#ifndef WX_PRECOMP
29    #include "wx/intl.h"
30    #include "wx/log.h"
31    #include "wx/image.h"
32#endif
33
34#include "wx/mstream.h"
35#include "wx/mac/private.h"
36#include <Scrap.h>
37
38// ----------------------------------------------------------------------------
39// functions
40// ----------------------------------------------------------------------------
41
42// ----------------------------------------------------------------------------
43// wxDataFormat
44// ----------------------------------------------------------------------------
45
46wxDataFormat::wxDataFormat()
47{
48    m_type = wxDF_INVALID;
49    m_format = 0;
50}
51
52wxDataFormat::wxDataFormat(  wxDataFormatId   vType )
53{
54    SetType(vType);
55}
56
57wxDataFormat::wxDataFormat(  const wxChar*  zId)
58{
59    SetId(zId);
60}
61
62wxDataFormat::wxDataFormat(  const wxString&   rId)
63{
64    SetId(rId);
65}
66
67wxDataFormat::wxDataFormat( NativeFormat vFormat)
68{
69    SetId(vFormat);
70}
71
72void wxDataFormat::SetType(  wxDataFormatId  Type )
73{
74    m_type = Type;
75
76    if (m_type == wxDF_TEXT )
77        m_format = kScrapFlavorTypeText;
78    else if (m_type == wxDF_UNICODETEXT )
79        m_format = kScrapFlavorTypeUnicode ;
80    else if (m_type == wxDF_BITMAP || m_type == wxDF_METAFILE )
81        m_format = kScrapFlavorTypePicture;
82    else if (m_type == wxDF_FILENAME)
83        m_format = kDragFlavorTypeHFS ;
84    else
85    {
86       wxFAIL_MSG( wxT("invalid dataformat") );
87
88       // this is '????' but it can't be used in the code because ??' is
89       // parsed as a trigraph!
90       m_format = 0x3f3f3f3f;
91    }
92}
93
94wxString wxDataFormat::GetId() const
95{
96    // note that m_format is not a pointer to string, it *is* itself a 4
97    // character string
98    char text[5] ;
99    strncpy( text , (char*) &m_format , 4 ) ;
100    text[4] = 0 ;
101
102    return wxString::FromAscii( text ) ;
103}
104
105void wxDataFormat::SetId(  NativeFormat  format )
106{
107    m_format = format;
108
109    if (m_format == kScrapFlavorTypeText)
110        m_type = wxDF_TEXT;
111    else if (m_format == kScrapFlavorTypeUnicode )
112        m_type = wxDF_UNICODETEXT;
113    else if (m_format == kScrapFlavorTypePicture)
114        m_type = wxDF_BITMAP;
115    else if (m_format == kDragFlavorTypeHFS )
116        m_type = wxDF_FILENAME;
117    else
118        m_type = wxDF_PRIVATE;
119}
120
121void wxDataFormat::SetId( const wxChar* zId )
122{
123    m_type = wxDF_PRIVATE;
124    m_format = 0;// TODO: get the format gdk_atom_intern( wxMBSTRINGCAST tmp.mbc_str(), FALSE );
125}
126
127//-------------------------------------------------------------------------
128// wxDataObject
129//-------------------------------------------------------------------------
130
131wxDataObject::wxDataObject()
132{
133}
134
135bool wxDataObject::IsSupportedFormat(
136  const wxDataFormat&               rFormat
137, Direction                         vDir
138) const
139{
140    size_t                          nFormatCount = GetFormatCount(vDir);
141
142    if (nFormatCount == 1)
143    {
144        return rFormat == GetPreferredFormat();
145    }
146    else
147    {
148        wxDataFormat* pFormats = new wxDataFormat[nFormatCount];
149        GetAllFormats( pFormats
150                      ,vDir
151                     );
152
153        size_t                      n;
154
155        for (n = 0; n < nFormatCount; n++)
156        {
157            if (pFormats[n] == rFormat)
158                break;
159        }
160
161        delete [] pFormats;
162
163        // found?
164        return n < nFormatCount;
165    }
166}
167
168// ----------------------------------------------------------------------------
169// wxFileDataObject
170// ----------------------------------------------------------------------------
171
172bool wxFileDataObject::GetDataHere( void* pBuf ) const
173{
174    wxString sFilenames;
175
176    for (size_t i = 0; i < m_filenames.GetCount(); i++)
177    {
178        sFilenames += m_filenames[i];
179        sFilenames += (wxChar)0;
180    }
181
182    memcpy(pBuf, sFilenames.mbc_str(), sFilenames.length() + 1);
183    return true;
184}
185
186size_t wxFileDataObject::GetDataSize() const
187{
188    size_t nRes = 0;
189
190    for (size_t i = 0; i < m_filenames.GetCount(); i++)
191    {
192        nRes += m_filenames[i].length();
193        nRes += 1;
194    }
195
196    return nRes + 1;
197}
198
199bool wxFileDataObject::SetData(
200  size_t                            WXUNUSED(nSize)
201, const void*                       pBuf
202)
203{
204    m_filenames.Empty();
205
206    AddFile(wxString::FromAscii((char*)pBuf));
207
208    return true;
209}
210
211void wxFileDataObject::AddFile(
212  const wxString&                   rFilename
213)
214{
215    m_filenames.Add(rFilename);
216}
217
218// ----------------------------------------------------------------------------
219// wxBitmapDataObject
220// ----------------------------------------------------------------------------
221
222wxBitmapDataObject::wxBitmapDataObject()
223{
224    Init();
225}
226
227wxBitmapDataObject::wxBitmapDataObject(
228  const wxBitmap& rBitmap
229)
230: wxBitmapDataObjectBase(rBitmap)
231{
232    Init();
233    if ( m_bitmap.Ok() )
234    {
235        m_pictHandle = m_bitmap.GetPict( &m_pictCreated ) ;
236    }
237}
238
239wxBitmapDataObject::~wxBitmapDataObject()
240{
241    Clear();
242}
243
244void wxBitmapDataObject::SetBitmap(
245  const wxBitmap&                   rBitmap
246)
247{
248    Clear();
249    wxBitmapDataObjectBase::SetBitmap(rBitmap);
250    if ( m_bitmap.Ok() )
251    {
252        m_pictHandle = m_bitmap.GetPict( &m_pictCreated ) ;
253    }
254}
255
256void wxBitmapDataObject::Init()
257{
258    m_pictHandle = NULL ;
259    m_pictCreated = false ;
260}
261
262void wxBitmapDataObject::Clear()
263{
264    if ( m_pictCreated && m_pictHandle )
265    {
266        KillPicture( (PicHandle) m_pictHandle ) ;
267    }
268    m_pictHandle = NULL ;
269}
270
271bool wxBitmapDataObject::GetDataHere( void* pBuf ) const
272{
273    if (!m_pictHandle)
274    {
275        wxFAIL_MSG(wxT("attempt to copy empty bitmap failed"));
276        return false;
277    }
278    memcpy(pBuf, *(Handle)m_pictHandle, GetHandleSize((Handle)m_pictHandle));
279    return true;
280}
281
282size_t wxBitmapDataObject::GetDataSize() const
283{
284    return GetHandleSize((Handle)m_pictHandle) ;
285}
286
287bool wxBitmapDataObject::SetData(
288  size_t                            nSize
289, const void*                       pBuf
290)
291{
292    Clear();
293    PicHandle picHandle = (PicHandle) NewHandle( nSize ) ;
294    memcpy( *picHandle , pBuf , nSize ) ;
295    m_pictHandle = picHandle ;
296    m_pictCreated = false ;
297    Rect frame = (**picHandle).picFrame ;
298
299    m_bitmap.SetPict( picHandle ) ;
300    m_bitmap.SetWidth( frame.right - frame.left ) ;
301    m_bitmap.SetHeight( frame.bottom - frame.top ) ;
302    return m_bitmap.Ok();
303}
304