///////////////////////////////////////////////////////////////////////////////
-// Name: os2/dataobj.cpp
-// Purpose: implementation of wx[I]DataObject class
-// Author: David Webster
+// Name: src/mac/carbon/dataobj.cpp
+// Purpose: implementation of wxDataObject class
+// Author: Stefan Csomor
// Modified by:
// Created: 10/21/99
// RCS-ID: $Id$
-// Copyright: (c) 1999 David Webster
-// Licence: wxWindows license
+// Copyright: (c) 1999 Stefan Csomor
+// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
-// ============================================================================
-// declarations
-// ============================================================================
-
-// ----------------------------------------------------------------------------
-// headers
-// ----------------------------------------------------------------------------
-
-#ifdef __GNUG__
- #pragma implementation "dataobj.h"
-#endif
-
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
+#if wxUSE_DATAOBJ
+
+#include "wx/dataobj.h"
+
#ifndef WX_PRECOMP
-#include "wx/intl.h"
+ #include "wx/intl.h"
+ #include "wx/log.h"
+ #include "wx/dcmemory.h"
+ #include "wx/image.h"
#endif
-#include "wx/defs.h"
-#include "wx/log.h"
-#include "wx/dataobj.h"
#include "wx/mstream.h"
-#include "wx/image.h"
+#include "wx/metafile.h"
+#include "wx/tokenzr.h"
+
#include "wx/mac/private.h"
-// ----------------------------------------------------------------------------
-// functions
-// ----------------------------------------------------------------------------
+#ifndef __DARWIN__
+#include <Scrap.h>
+#endif
+
// ----------------------------------------------------------------------------
// wxDataFormat
m_format = 0;
}
-wxDataFormat::wxDataFormat( wxDataFormatId vType )
+wxDataFormat::wxDataFormat( wxDataFormatId vType )
{
- SetType(vType);
+ SetType( vType );
}
-wxDataFormat::wxDataFormat( const wxChar* zId)
+wxDataFormat::wxDataFormat( const wxChar *zId )
{
- SetId(zId);
+ SetId( zId );
}
-wxDataFormat::wxDataFormat( const wxString& rId)
+wxDataFormat::wxDataFormat( const wxString& rId )
{
- SetId(rId);
+ SetId( rId );
}
-wxDataFormat::wxDataFormat( NativeFormat vFormat)
+wxDataFormat::wxDataFormat( NativeFormat vFormat )
{
- SetId(vFormat);
+ SetId( vFormat );
}
-void wxDataFormat::SetType( wxDataFormatId Type )
+void wxDataFormat::SetType( wxDataFormatId dataType )
{
- m_type = Type;
-
- if (m_type == wxDF_TEXT)
- m_format = 'TEXT';
- else if (m_type == wxDF_BITMAP || m_type == wxDF_METAFILE )
- m_format = 'PICT';
- else if (m_type == wxDF_FILENAME)
- m_format = kDragFlavorTypeHFS ;
- else
+ m_type = dataType;
+
+ switch (m_type)
{
- wxFAIL_MSG( wxT("invalid dataformat") );
+ case wxDF_TEXT:
+ m_format = kScrapFlavorTypeText;
+ break;
+
+ case wxDF_UNICODETEXT:
+ m_format = kScrapFlavorTypeUnicode;
+ break;
+
+ case wxDF_BITMAP:
+ case wxDF_METAFILE:
+ m_format = kScrapFlavorTypePicture;
+ break;
+
+ case wxDF_FILENAME:
+ m_format = kDragFlavorTypeHFS;
+ break;
+
+ default:
+ wxFAIL_MSG( wxT("invalid data format") );
+
+ // NB: this translates to '????' ASCII but it can't be used in the code
+ // because '??' will get parsed as a trigraph!
+ m_format = 0x3f3f3f3f;
+ break;
}
}
-wxDataFormatId wxDataFormat::GetType() const
-{
- return m_type;
-}
-
wxString wxDataFormat::GetId() const
{
- wxString sRet(""); // TODO: to name of ( m_format ) );
- return sRet;
+ wxCHECK_MSG( !IsStandard(), wxEmptyString,
+ wxT("name of predefined format cannot be retrieved") );
+
+ return m_id;
}
-void wxDataFormat::SetId( NativeFormat format )
+void wxDataFormat::SetId( NativeFormat format )
{
m_format = format;
- if (m_format == 'TEXT')
+ switch (m_format)
+ {
+ case kScrapFlavorTypeText:
m_type = wxDF_TEXT;
- else
- if (m_format == 'PICT')
+ break;
+
+ case kScrapFlavorTypeUnicode:
+ m_type = wxDF_UNICODETEXT;
+ break;
+
+ case kScrapFlavorTypePicture:
m_type = wxDF_BITMAP;
- else
- if (m_format == kDragFlavorTypeHFS )
+ break;
+
+ case kDragFlavorTypeHFS:
m_type = wxDF_FILENAME;
- else
+ break;
+
+ default:
m_type = wxDF_PRIVATE;
+ char text[5];
+ memcpy( text, (const char*)&format, 4 );
+ text[4] = 0;
+ m_id = wxString::FromAscii( text );
+ break;
+ }
}
void wxDataFormat::SetId( const wxChar* zId )
{
- wxString tmp(zId);
-
m_type = wxDF_PRIVATE;
- m_format = 0;// TODO: get the format gdk_atom_intern( wxMBSTRINGCAST tmp.mbc_str(), FALSE );
+ m_id = zId;
+ m_format = 'WXPR';
+}
+
+bool wxDataFormat::operator==(const wxDataFormat& format) const
+{
+ if (IsStandard() || format.IsStandard())
+ return (format.m_type == m_type);
+ else
+ return (m_id == format.m_id);
}
//-------------------------------------------------------------------------
{
}
-bool wxDataObject::IsSupportedFormat(
- const wxDataFormat& rFormat
-, Direction vDir
-) const
+bool wxDataObject::IsSupportedFormat( const wxDataFormat& rFormat, Direction vDir ) const
{
- size_t nFormatCount = GetFormatCount(vDir);
+ size_t nFormatCount = GetFormatCount( vDir );
+ bool found = false;
if (nFormatCount == 1)
{
- return rFormat == GetPreferredFormat();
+ found = (rFormat == GetPreferredFormat());
}
else
{
- wxDataFormat* pFormats = new wxDataFormat[nFormatCount];
- GetAllFormats( pFormats
- ,vDir
- );
+ wxDataFormat *pFormats = new wxDataFormat[nFormatCount];
+ GetAllFormats( pFormats, vDir );
- size_t n;
-
- for (n = 0; n < nFormatCount; n++)
+ for (size_t n = 0; n < nFormatCount; n++)
{
if (pFormats[n] == rFormat)
+ {
+ found = true;
break;
+ }
}
delete [] pFormats;
-
- // found?
- return n < nFormatCount;
}
+
+ return found;
}
+// ----------------------------------------------------------------------------
+// wxTextDataObject
+// ----------------------------------------------------------------------------
+
+#if wxUSE_UNICODE
+void wxTextDataObject::GetAllFormats( wxDataFormat *formats, wxDataObjectBase::Direction dir ) const
+{
+ *formats++ = wxDataFormat( wxDF_TEXT );
+ *formats = wxDataFormat( wxDF_UNICODETEXT );
+}
+#endif
+
// ----------------------------------------------------------------------------
// wxFileDataObject
// ----------------------------------------------------------------------------
-bool wxFileDataObject::GetDataHere(
- void* pBuf
-) const
+void wxFileDataObject::GetFileNames( wxCharBuffer &buf ) const
{
- wxString sFilenames;
+ wxString filenames;
for (size_t i = 0; i < m_filenames.GetCount(); i++)
{
- sFilenames += m_filenames[i];
- sFilenames += (wxChar)0;
+ filenames += m_filenames[i];
+ filenames += wxT('\n');
}
- memcpy(pBuf, sFilenames.mbc_str(), sFilenames.Len() + 1);
- return TRUE;
+ buf = filenames.fn_str();
+}
+
+bool wxFileDataObject::GetDataHere( void *pBuf ) const
+{
+ if (pBuf == NULL)
+ return false;
+
+ wxCharBuffer buf;
+ size_t buffLength;
+
+ GetFileNames( buf );
+ buffLength = strlen( buf );
+ memcpy( pBuf, (const char*)buf, buffLength + 1 );
+
+ return true;
}
size_t wxFileDataObject::GetDataSize() const
{
- size_t nRes = 0;
+ wxCharBuffer buf;
+ size_t buffLength;
- for (size_t i = 0; i < m_filenames.GetCount(); i++)
- {
- nRes += m_filenames[i].Len();
- nRes += 1;
- }
+ GetFileNames( buf );
+ buffLength = strlen( buf );
- return nRes + 1;
+ return buffLength + 1;
}
-bool wxFileDataObject::SetData(
- size_t WXUNUSED(nSize)
-, const void* pBuf
-)
+bool wxFileDataObject::SetData( size_t nSize, const void *pBuf )
{
- m_filenames.Empty();
+ wxString filenames;
- wxString sFile( (const char *)pBuf); /* char, not wxChar */
+#if wxUSE_UNICODE
+ filenames = wxString( (const char*)pBuf, *wxConvFileName );
+#else
+ filenames = wxString (wxConvLocal.cWC2WX(wxConvFileName->cMB2WC( (const char*)pBuf)));
+#endif
- AddFile(sFile);
+ m_filenames = wxStringTokenize( filenames, wxT("\n"), wxTOKEN_STRTOK );
- return TRUE;
+ return true;
}
-void wxFileDataObject::AddFile(
- const wxString& rFilename
-)
+void wxFileDataObject::AddFile( const wxString& rFilename )
{
- m_filenames.Add(rFilename);
+ m_filenames.Add( rFilename );
}
// ----------------------------------------------------------------------------
Init();
}
-wxBitmapDataObject::wxBitmapDataObject(
- const wxBitmap& rBitmap
-)
-: wxBitmapDataObjectBase(rBitmap)
+wxBitmapDataObject::wxBitmapDataObject( const wxBitmap& rBitmap )
+: wxBitmapDataObjectBase( rBitmap )
{
Init();
- DoConvertToPng();
+ if (m_bitmap.Ok())
+ {
+ m_pictHandle = m_bitmap.GetBitmapData()->GetPictHandle();
+ m_pictCreated = false;
+ }
}
wxBitmapDataObject::~wxBitmapDataObject()
Clear();
}
-void wxBitmapDataObject::SetBitmap(
- const wxBitmap& rBitmap
-)
-{
- ClearAll();
- wxBitmapDataObjectBase::SetBitmap(rBitmap);
- DoConvertToPng();
-}
-
-bool wxBitmapDataObject::GetDataHere(
- void* pBuf
-) const
+void wxBitmapDataObject::SetBitmap( const wxBitmap& rBitmap )
{
- if (!m_pngSize)
+ Clear();
+ wxBitmapDataObjectBase::SetBitmap( rBitmap );
+ if (m_bitmap.Ok())
{
- wxFAIL_MSG(wxT("attempt to copy empty bitmap failed"));
- return FALSE;
+ m_pictHandle = m_bitmap.GetBitmapData()->GetPictHandle();
+ m_pictCreated = false;
}
- memcpy(pBuf, m_pngData, m_pngSize);
- return TRUE;
}
-bool wxBitmapDataObject::SetData(
- size_t nSize
-, const void* pBuf
-)
+void wxBitmapDataObject::Init()
{
- Clear();
- m_pngSize = nSize;
- m_pngData = malloc(m_pngSize);
-
- memcpy(m_pngData, pBuf, m_pngSize);
-
- wxMemoryInputStream vMstream((char*)m_pngData, m_pngSize);
- wxImage vImage;
- wxPNGHandler vHandler;
+ m_pictHandle = NULL;
+ m_pictCreated = false;
+}
- if (!vHandler.LoadFile(&vImage, vMstream))
+void wxBitmapDataObject::Clear()
+{
+ if (m_pictHandle != NULL)
{
- return FALSE;
+#ifndef __LP64__
+ if (m_pictCreated)
+ KillPicture( (PicHandle)m_pictHandle );
+#endif
+ m_pictHandle = NULL;
}
- m_bitmap = wxBitmap( vImage ) ;
- return m_bitmap.Ok();
+ m_pictCreated = false;
}
-void wxBitmapDataObject::DoConvertToPng()
+bool wxBitmapDataObject::GetDataHere( void *pBuf ) const
{
- if (!m_bitmap.Ok())
- return;
+ if (m_pictHandle == NULL)
+ {
+ wxFAIL_MSG( wxT("attempt to copy empty bitmap failed") );
+ return false;
+ }
+
+ if (pBuf == NULL)
+ return false;
- wxCHECK_RET( wxImage::FindHandler(wxBITMAP_TYPE_PNG) != NULL,
- wxT("You must call wxImage::AddHandler(new wxPNGHandler); to be able to use clipboard with bitmaps!") );
+ memcpy( pBuf, *(Handle)m_pictHandle, GetHandleSize( (Handle)m_pictHandle ) );
+
+ return true;
+}
- wxImage image = m_bitmap.ConvertToImage();
+size_t wxBitmapDataObject::GetDataSize() const
+{
+ if (m_pictHandle != NULL)
+ return GetHandleSize( (Handle)m_pictHandle );
+ else
+ return 0;
+}
- wxCountingOutputStream count;
- image.SaveFile(count, wxBITMAP_TYPE_PNG);
+bool wxBitmapDataObject::SetData( size_t nSize, const void *pBuf )
+{
+ Clear();
- m_pngSize = count.GetSize() + 100; // sometimes the size seems to vary ???
- m_pngData = malloc(m_pngSize);
+ if ((pBuf == NULL) || (nSize == 0))
+ return false;
+
+ PicHandle picHandle = (PicHandle)NewHandle( nSize );
+ memcpy( *picHandle, pBuf, nSize );
+ m_pictHandle = picHandle;
+
+ // ownership is transferred to the bitmap
+ m_pictCreated = false;
+#ifndef __LP64__
+ Rect frame;
+ wxMacGetPictureBounds( picHandle, &frame );
+#if wxUSE_METAFILE
+ wxMetafile mf;
+ mf.SetHMETAFILE( (WXHMETAFILE)m_pictHandle );
+#endif
+ wxMemoryDC mdc;
+ m_bitmap.Create( frame.right - frame.left, frame.bottom - frame.top );
+ mdc.SelectObject( m_bitmap );
+#if wxUSE_METAFILE
+ mf.Play( &mdc );
+#endif
+ mdc.SelectObject( wxNullBitmap );
+#endif
- wxMemoryOutputStream mstream((char*) m_pngData, m_pngSize);
- image.SaveFile(mstream, wxBITMAP_TYPE_PNG);
+ return m_bitmap.Ok();
}
+#endif