Merge branch 'image_data_object' of https://github.com/a-wi/wxWidgets

Implement wxImageDataObject to allow copying wxImage, including its
metadata, to/from clipboard.

See https://github.com/wxWidgets/wxWidgets/pull/2156
This commit is contained in:
Vadim Zeitlin
2021-01-02 00:27:44 +01:00
8 changed files with 313 additions and 24 deletions

View File

@@ -36,7 +36,9 @@
wxTextDataObject | wxBitmapDataObject wxTextDataObject | wxBitmapDataObject
| |
wxCustomDataObject wxCustomDataObject
|
|
wxImageDataObject
*/ */
// ============================================================================ // ============================================================================
@@ -545,6 +547,22 @@ private:
wxDECLARE_NO_COPY_CLASS(wxCustomDataObject); wxDECLARE_NO_COPY_CLASS(wxCustomDataObject);
}; };
// ----------------------------------------------------------------------------
// wxImageDataObject - data object for wxImage
// ----------------------------------------------------------------------------
class WXDLLIMPEXP_CORE wxImageDataObject : public wxCustomDataObject
{
public:
explicit wxImageDataObject(const wxImage& image = wxNullImage);
void SetImage(const wxImage& image);
wxImage GetImage() const;
private:
wxDECLARE_NO_COPY_CLASS(wxImageDataObject);
};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// include platform-specific declarations of wxXXXBase classes // include platform-specific declarations of wxXXXBase classes
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -2153,6 +2153,7 @@ enum wxDataFormatId
wxDF_LOCALE = 16, wxDF_LOCALE = 16,
wxDF_PRIVATE = 20, wxDF_PRIVATE = 20,
wxDF_HTML = 30, /* Note: does not correspond to CF_ constant */ wxDF_HTML = 30, /* Note: does not correspond to CF_ constant */
wxDF_PNG = 31, /* Note: does not correspond to CF_ constant */
wxDF_MAX wxDF_MAX
}; };

View File

@@ -34,6 +34,9 @@
A list of filenames.} A list of filenames.}
@itemdef{wxDF_HTML, @itemdef{wxDF_HTML,
An HTML string. This is currently only valid on Mac and MSW.} An HTML string. This is currently only valid on Mac and MSW.}
@itemdef{wxDF_PNG,
A PNG file. This is valid only on MSW. This constant is available
since wxWidgets 3.1.5.}
@endDefList @endDefList
As mentioned above, these standard formats may be passed to any function As mentioned above, these standard formats may be passed to any function
@@ -620,6 +623,42 @@ public:
/**
@class wxImageDataObject
wxImageDataObject is a specialization of wxDataObject for image data.
It can be used e.g. when you need to put on and retrieve from the clipboard
a wxImage with its metadata (like image resolution).
@since 3.1.5
@library{wxcore}
@category{dnd}
@see @ref overview_dnd, wxDataObject, wxCustomDataObject, wxBitmapDataObject
*/
class wxImageDataObject : public wxCustomDataObject
{
public:
/**
Constructor, optionally passing an image (otherwise use SetImage()
later).
*/
explicit wxImageDataObject(const wxImage& image = wxNullImage);
/**
Returns the image associated with the data object.
*/
wxImage GetImage() const;
/**
Sets the image stored by the data object.
*/
void SetImage(const wxImage& image);
};
/** /**
@class wxURLDataObject @class wxURLDataObject

View File

@@ -91,6 +91,8 @@ public:
#if wxUSE_CLIPBOARD #if wxUSE_CLIPBOARD
void OnCopy(wxCommandEvent& event); void OnCopy(wxCommandEvent& event);
void OnPaste(wxCommandEvent& event); void OnPaste(wxCommandEvent& event);
void OnCopyImage(wxCommandEvent& evt);
void OnPasteImage(wxCommandEvent& evt);
#endif // wxUSE_CLIPBOARD #endif // wxUSE_CLIPBOARD
MyCanvas *m_canvas; MyCanvas *m_canvas;
@@ -124,8 +126,39 @@ class MyImageFrame : public wxFrame
public: public:
MyImageFrame(wxFrame *parent, const wxString& desc, const wxImage& image, double scale = 1.0) MyImageFrame(wxFrame *parent, const wxString& desc, const wxImage& image, double scale = 1.0)
{ {
Create(parent, desc, wxBitmap(image, wxBITMAP_SCREEN_DEPTH, scale), // Retrieve image info
image.GetImageCount(desc)); wxString info;
int xres, yres;
switch ( GetResolutionFromOptions(image, &xres, &yres) )
{
case wxIMAGE_RESOLUTION_NONE:
break;
case wxIMAGE_RESOLUTION_CM:
// convert to DPI
xres = wxRound(xres / 10.0 * inches2mm);
yres = wxRound(yres / 10.0 * inches2mm);
wxFALLTHROUGH;
case wxIMAGE_RESOLUTION_INCHES:
info = wxString::Format("DPI %i x %i", xres, yres);
break;
default:
wxFAIL_MSG("unexpected image resolution units");
break;
}
int numImages = desc.StartsWith("Clipboard") ? 1 : image.GetImageCount(desc);
if ( numImages > 1 )
{
if ( !info.empty() )
info += ", ";
info += wxString::Format("%d images", numImages);
}
Create(parent, desc, wxBitmap(image, wxBITMAP_SCREEN_DEPTH, scale), info);
} }
MyImageFrame(wxFrame *parent, const wxString& desc, const wxBitmap& bitmap) MyImageFrame(wxFrame *parent, const wxString& desc, const wxBitmap& bitmap)
@@ -137,7 +170,7 @@ private:
bool Create(wxFrame *parent, bool Create(wxFrame *parent,
const wxString& desc, const wxString& desc,
const wxBitmap& bitmap, const wxBitmap& bitmap,
int numImages = 1) wxString info = wxString())
{ {
if ( !wxFrame::Create(parent, wxID_ANY, if ( !wxFrame::Create(parent, wxID_ANY,
wxString::Format("Image from %s", desc), wxString::Format("Image from %s", desc),
@@ -169,8 +202,7 @@ private:
mbar->Check(ID_PAINT_BG, true); mbar->Check(ID_PAINT_BG, true);
CreateStatusBar(2); CreateStatusBar(2);
if ( numImages != 1 ) SetStatusText(info, 1);
SetStatusText(wxString::Format("%d images", numImages), 1);
SetClientSize(bitmap.GetWidth(), bitmap.GetHeight()); SetClientSize(bitmap.GetWidth(), bitmap.GetHeight());
@@ -439,6 +471,41 @@ private:
Refresh(); Refresh();
} }
// This is a copy of protected wxImageHandler::GetResolutionFromOptions()
static wxImageResolution GetResolutionFromOptions(const wxImage& image, int* x, int* y)
{
wxCHECK_MSG(x && y, wxIMAGE_RESOLUTION_NONE, wxT("NULL pointer"));
if ( image.HasOption(wxIMAGE_OPTION_RESOLUTIONX) &&
image.HasOption(wxIMAGE_OPTION_RESOLUTIONY) )
{
*x = image.GetOptionInt(wxIMAGE_OPTION_RESOLUTIONX);
*y = image.GetOptionInt(wxIMAGE_OPTION_RESOLUTIONY);
}
else if ( image.HasOption(wxIMAGE_OPTION_RESOLUTION) )
{
*x =
*y = image.GetOptionInt(wxIMAGE_OPTION_RESOLUTION);
}
else // no resolution options specified
{
*x =
*y = 0;
return wxIMAGE_RESOLUTION_NONE;
}
// get the resolution unit too
int resUnit = image.GetOptionInt(wxIMAGE_OPTION_RESOLUTIONUNIT);
if ( !resUnit )
{
// this is the default
resUnit = wxIMAGE_RESOLUTION_INCHES;
}
return (wxImageResolution)resUnit;
}
wxBitmap m_bitmap; wxBitmap m_bitmap;
double m_zoom; double m_zoom;
@@ -631,7 +698,9 @@ enum
ID_INFO, ID_INFO,
ID_SHOWRAW, ID_SHOWRAW,
ID_GRAPHICS, ID_GRAPHICS,
ID_SHOWTHUMBNAIL ID_SHOWTHUMBNAIL,
ID_COPY_IMAGE,
ID_PASTE_IMAGE
}; };
wxIMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame ); wxIMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame );
@@ -651,6 +720,8 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
#if wxUSE_CLIPBOARD #if wxUSE_CLIPBOARD
EVT_MENU(wxID_COPY, MyFrame::OnCopy) EVT_MENU(wxID_COPY, MyFrame::OnCopy)
EVT_MENU(wxID_PASTE, MyFrame::OnPaste) EVT_MENU(wxID_PASTE, MyFrame::OnPaste)
EVT_MENU(ID_COPY_IMAGE, MyFrame::OnCopyImage)
EVT_MENU(ID_PASTE_IMAGE, MyFrame::OnPasteImage)
#endif // wxUSE_CLIPBOARD #endif // wxUSE_CLIPBOARD
EVT_UPDATE_UI(ID_NEW_HIDPI, MyFrame::OnUpdateNewFrameHiDPI) EVT_UPDATE_UI(ID_NEW_HIDPI, MyFrame::OnUpdateNewFrameHiDPI)
wxEND_EVENT_TABLE() wxEND_EVENT_TABLE()
@@ -686,8 +757,11 @@ MyFrame::MyFrame()
#if wxUSE_CLIPBOARD #if wxUSE_CLIPBOARD
wxMenu *menuClipboard = new wxMenu; wxMenu *menuClipboard = new wxMenu;
menuClipboard->Append(wxID_COPY, "&Copy test image\tCtrl-C"); menuClipboard->Append(wxID_COPY, "&Copy test image as wxBitmap\tCtrl-C");
menuClipboard->Append(wxID_PASTE, "&Paste image\tCtrl-V"); menuClipboard->Append(wxID_PASTE, "&Paste image as wxBitmap\tCtrl-V");
menuClipboard->AppendSeparator();
menuClipboard->Append(ID_COPY_IMAGE, "Copy image as wxImage");
menuClipboard->Append(ID_PASTE_IMAGE, "Paste image as wxImage");
menu_bar->Append(menuClipboard, "&Clipboard"); menu_bar->Append(menuClipboard, "&Clipboard");
#endif // wxUSE_CLIPBOARD #endif // wxUSE_CLIPBOARD
@@ -945,6 +1019,38 @@ void MyFrame::OnPaste(wxCommandEvent& WXUNUSED(event))
wxTheClipboard->Close(); wxTheClipboard->Close();
} }
void MyFrame::OnCopyImage(wxCommandEvent& WXUNUSED(evt))
{
wxImage img;
wxString filename = LoadUserImage(img);
if ( filename.empty() )
return;
wxImageDataObject* dobjImage = new wxImageDataObject;
dobjImage->SetImage(img);
wxClipboardLocker clipOpener;
if ( !wxTheClipboard->SetData(dobjImage) )
{
wxLogError("Failed to copy wxImage to clipboard");
}
}
void MyFrame::OnPasteImage(wxCommandEvent& WXUNUSED(evt))
{
wxImageDataObject dobjImage;
wxClipboardLocker clipOpener;
if ( !wxTheClipboard->GetData(dobjImage) )
{
wxLogMessage("No wxImage data in the clipboard");
}
else
{
new MyImageFrame(this, "Clipboard (wxImage)", dobjImage.GetImage());
}
}
#endif // wxUSE_CLIPBOARD #endif // wxUSE_CLIPBOARD
void MyFrame::OnThumbnail( wxCommandEvent &WXUNUSED(event) ) void MyFrame::OnThumbnail( wxCommandEvent &WXUNUSED(event) )

View File

@@ -20,6 +20,7 @@
#include "wx/app.h" #include "wx/app.h"
#endif #endif
#include "wx/mstream.h"
#include "wx/textbuf.h" #include "wx/textbuf.h"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -620,6 +621,59 @@ bool wxCustomDataObject::SetData(size_t size, const void *buf)
return true; return true;
} }
// ----------------------------------------------------------------------------
// wxImageDataObject
// ----------------------------------------------------------------------------
#if defined(__WXMSW__)
#define wxIMAGE_FORMAT_DATA wxDF_PNG
#define wxIMAGE_FORMAT_BITMAP_TYPE wxBITMAP_TYPE_PNG
#define wxIMAGE_FORMAT_NAME "PNG"
#elif defined(__WXGTK__)
#define wxIMAGE_FORMAT_DATA wxDF_BITMAP
#define wxIMAGE_FORMAT_BITMAP_TYPE wxBITMAP_TYPE_PNG
#define wxIMAGE_FORMAT_NAME "PNG"
#elif defined(__WXOSX__)
#define wxIMAGE_FORMAT_DATA wxDF_BITMAP
#define wxIMAGE_FORMAT_BITMAP_TYPE wxBITMAP_TYPE_TIFF
#define wxIMAGE_FORMAT_NAME "TIFF"
#else
#define wxIMAGE_FORMAT_DATA wxDF_BITMAP
#define wxIMAGE_FORMAT_BITMAP_TYPE wxBITMAP_TYPE_PNG
#define wxIMAGE_FORMAT_NAME "PNG"
#endif
wxImageDataObject::wxImageDataObject(const wxImage& image)
: wxCustomDataObject(wxIMAGE_FORMAT_DATA)
{
if ( image.IsOk() )
{
SetImage(image);
}
}
void wxImageDataObject::SetImage(const wxImage& image)
{
wxCHECK_RET(wxImage::FindHandler(wxIMAGE_FORMAT_BITMAP_TYPE) != NULL,
wxIMAGE_FORMAT_NAME " image handler must be installed to use clipboard with image");
wxMemoryOutputStream mem;
image.SaveFile(mem, wxIMAGE_FORMAT_BITMAP_TYPE);
SetData(mem.GetLength(), mem.GetOutputStreamBuffer()->GetBufferStart());
}
wxImage wxImageDataObject::GetImage() const
{
wxCHECK_MSG(wxImage::FindHandler(wxIMAGE_FORMAT_BITMAP_TYPE) != NULL, wxNullImage,
wxIMAGE_FORMAT_NAME " image handler must be installed to use clipboard with image");
wxMemoryInputStream mem(GetData(), GetSize());
wxImage image;
image.LoadFile(mem, wxIMAGE_FORMAT_BITMAP_TYPE);
return image;
}
// ============================================================================ // ============================================================================
// some common dnd related code // some common dnd related code
// ============================================================================ // ============================================================================

View File

@@ -73,6 +73,7 @@
static bool gs_wxClipboardIsOpen = false; static bool gs_wxClipboardIsOpen = false;
static int gs_htmlcfid = 0; static int gs_htmlcfid = 0;
static int gs_pngcfid = 0;
bool wxOpenClipboard() bool wxOpenClipboard()
{ {
@@ -136,6 +137,8 @@ bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
wxDataFormat::NativeFormat cf = dataFormat.GetFormatId(); wxDataFormat::NativeFormat cf = dataFormat.GetFormatId();
if (cf == wxDF_HTML) if (cf == wxDF_HTML)
cf = gs_htmlcfid; cf = gs_htmlcfid;
else if ( cf == wxDF_PNG )
cf = gs_pngcfid;
if ( ::IsClipboardFormatAvailable(cf) ) if ( ::IsClipboardFormatAvailable(cf) )
{ {
@@ -162,6 +165,15 @@ bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
#if !wxUSE_OLE_CLIPBOARD #if !wxUSE_OLE_CLIPBOARD
namespace
{
struct wxRawImageData
{
size_t m_size;
void* m_data;
};
}
bool wxSetClipboardData(wxDataFormat dataFormat, bool wxSetClipboardData(wxDataFormat dataFormat,
const void *data, const void *data,
int width, int height) int width, int height)
@@ -414,6 +426,16 @@ bool wxSetClipboardData(wxDataFormat dataFormat,
delete [] buf; delete [] buf;
break; break;
} }
case wxDF_PNG:
{
const wxRawImageData* imgData = reinterpret_cast<const wxRawImageData*>(data);
GlobalPtr hImage(imgData->m_size, GMEM_MOVEABLE | GMEM_DDESHARE);
memcpy(GlobalPtrLock(hImage).Get(), imgData->m_data, imgData->m_size);
handle = ::SetClipboardData(gs_pngcfid, hImage);
break;
}
} }
if ( handle == 0 ) if ( handle == 0 )
@@ -515,9 +537,11 @@ bool wxClipboard::Flush()
bool wxClipboard::Open() bool wxClipboard::Open()
{ {
// Get clipboard id for HTML format... // Get clipboard id for HTML and PNG formats...
if(!gs_htmlcfid) if(!gs_htmlcfid)
gs_htmlcfid = RegisterClipboardFormat(wxT("HTML Format")); gs_htmlcfid = RegisterClipboardFormat(wxT("HTML Format"));
if ( !gs_pngcfid )
gs_pngcfid = ::RegisterClipboardFormat(wxT("PNG"));
// OLE opens clipboard for us // OLE opens clipboard for us
m_isOpened = true; m_isOpened = true;
@@ -636,6 +660,16 @@ bool wxClipboard::AddData( wxDataObject *data )
} }
break; break;
case wxDF_PNG:
{
wxCustomDataObject* imageDataObject = reinterpret_cast<wxCustomDataObject*>(data);
wxRawImageData imgData;
imgData.m_size = imageDataObject->GetDataSize();
imgData.m_data = imageDataObject->GetData();
bRet = wxSetClipboardData(format, &imgData);
}
break;
#if wxUSE_METAFILE #if wxUSE_METAFILE
case wxDF_METAFILE: case wxDF_METAFILE:
{ {
@@ -768,6 +802,8 @@ bool wxClipboard::GetData( wxDataObject& data )
if (cf == wxDF_HTML) if (cf == wxDF_HTML)
cf = gs_htmlcfid; cf = gs_htmlcfid;
else if ( cf == wxDF_PNG )
cf = gs_pngcfid;
// if the format is not available, try the next one // if the format is not available, try the next one
// this test includes implicit / sythetic formats // this test includes implicit / sythetic formats
if ( !::IsClipboardFormatAvailable(cf) ) if ( !::IsClipboardFormatAvailable(cf) )

View File

@@ -64,15 +64,15 @@
namespace namespace
{ {
wxDataFormat HtmlFormatFixup(wxDataFormat format) wxDataFormat NonStandardFormatsFixup(wxDataFormat format)
{ {
// Since the HTML format is dynamically registered, the wxDF_HTML // Since the HTML and PNG formats are dynamically registered, the wxDF_HTML and wxDF_PNG
// format does not match the native constant in the way other formats do, // formats do not match the native constants in the way other formats do,
// so for the format checks below to work, we must change the native // so for the format checks below to work, we must change the native
// id to the wxDF_HTML constant. // id to the wxDF_HTML or wxDF_PNG constant.
// //
// But skip this for the standard constants which are never going to match // But skip this for the standard constants which are never going to match
// wxDF_HTML anyhow. // wxDF_HTML or wxDF_PNG anyhow.
if ( !format.IsStandard() ) if ( !format.IsStandard() )
{ {
wxChar szBuf[256]; wxChar szBuf[256];
@@ -80,6 +80,8 @@ wxDataFormat HtmlFormatFixup(wxDataFormat format)
{ {
if ( wxStrcmp(szBuf, wxT("HTML Format")) == 0 ) if ( wxStrcmp(szBuf, wxT("HTML Format")) == 0 )
format = wxDF_HTML; format = wxDF_HTML;
else if ( wxStrcmp(szBuf, wxT("PNG")) == 0 )
format = wxDF_PNG;
} }
} }
@@ -347,7 +349,7 @@ wxIDataObject::SaveSystemData(FORMATETC *pformatetc,
bool wxDataFormat::operator==(wxDataFormatId format) const bool wxDataFormat::operator==(wxDataFormatId format) const
{ {
return HtmlFormatFixup(*this).m_format == (NativeFormat)format; return NonStandardFormatsFixup(*this).m_format == (NativeFormat)format;
} }
bool wxDataFormat::operator!=(wxDataFormatId format) const bool wxDataFormat::operator!=(wxDataFormatId format) const
@@ -357,7 +359,7 @@ bool wxDataFormat::operator!=(wxDataFormatId format) const
bool wxDataFormat::operator==(const wxDataFormat& format) const bool wxDataFormat::operator==(const wxDataFormat& format) const
{ {
return HtmlFormatFixup(*this).m_format == HtmlFormatFixup(format).m_format; return NonStandardFormatsFixup(*this).m_format == NonStandardFormatsFixup(format).m_format;
} }
bool wxDataFormat::operator!=(const wxDataFormat& format) const bool wxDataFormat::operator!=(const wxDataFormat& format) const
@@ -367,7 +369,7 @@ bool wxDataFormat::operator!=(const wxDataFormat& format) const
bool wxDataFormat::operator==(NativeFormat format) const bool wxDataFormat::operator==(NativeFormat format) const
{ {
return HtmlFormatFixup(*this).m_format == format; return NonStandardFormatsFixup(*this).m_format == format;
} }
bool wxDataFormat::operator!=(NativeFormat format) const bool wxDataFormat::operator!=(NativeFormat format) const
@@ -422,10 +424,12 @@ wxIEnumFORMATETC::wxIEnumFORMATETC(const wxDataFormat *formats, ULONG nCount)
m_nCount = nCount; m_nCount = nCount;
m_formats = new CLIPFORMAT[nCount]; m_formats = new CLIPFORMAT[nCount];
for ( ULONG n = 0; n < nCount; n++ ) { for ( ULONG n = 0; n < nCount; n++ ) {
if (formats[n].GetFormatId() != wxDF_HTML) if ( formats[n].GetFormatId() == wxDF_HTML )
m_formats[n] = formats[n].GetFormatId();
else
m_formats[n] = ::RegisterClipboardFormat(wxT("HTML Format")); m_formats[n] = ::RegisterClipboardFormat(wxT("HTML Format"));
else if ( formats[n].GetFormatId() == wxDF_PNG )
m_formats[n] = ::RegisterClipboardFormat(wxT("PNG"));
else
m_formats[n] = formats[n].GetFormatId();
} }
} }
@@ -540,7 +544,7 @@ STDMETHODIMP wxIDataObject::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
// for the bitmaps and metafiles we use the handles instead of global memory // for the bitmaps and metafiles we use the handles instead of global memory
// to pass the data // to pass the data
wxDataFormat format = (wxDataFormat::NativeFormat)pformatetcIn->cfFormat; wxDataFormat format = (wxDataFormat::NativeFormat)pformatetcIn->cfFormat;
format = HtmlFormatFixup(format); format = NonStandardFormatsFixup(format);
// is this system data? // is this system data?
if ( GetSystemData(format, pmedium) ) if ( GetSystemData(format, pmedium) )
@@ -690,7 +694,7 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc,
{ {
wxDataFormat format = pformatetc->cfFormat; wxDataFormat format = pformatetc->cfFormat;
format = HtmlFormatFixup(format); format = NonStandardFormatsFixup(format);
// check if this format is supported // check if this format is supported
if ( !m_pDataObject->IsSupported(format, wxDataObject::Set) ) { if ( !m_pDataObject->IsSupported(format, wxDataObject::Set) ) {
@@ -737,6 +741,9 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc,
size = sizeof(METAFILEPICT); size = sizeof(METAFILEPICT);
break; break;
case wxDF_PNG:
wxFALLTHROUGH;
default: default:
size = ptr.GetSize(); size = ptr.GetSize();
@@ -816,7 +823,7 @@ STDMETHODIMP wxIDataObject::QueryGetData(FORMATETC *pformatetc)
// and now check the type of data requested // and now check the type of data requested
wxDataFormat format = pformatetc->cfFormat; wxDataFormat format = pformatetc->cfFormat;
format = HtmlFormatFixup(format); format = NonStandardFormatsFixup(format);
if ( m_pDataObject->IsSupportedFormat(format) ) { if ( m_pDataObject->IsSupportedFormat(format) ) {
wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::QueryGetData: %s ok"), wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::QueryGetData: %s ok"),

View File

@@ -26,6 +26,8 @@
#include "wx/mstream.h" #include "wx/mstream.h"
#include "wx/zstream.h" #include "wx/zstream.h"
#include "wx/wfstream.h" #include "wx/wfstream.h"
#include "wx/clipbrd.h"
#include "wx/dataobj.h"
#include "testimage.h" #include "testimage.h"
@@ -1942,6 +1944,32 @@ TEST_CASE("wxImage::RGBtoHSV", "[image][rgb][hsv]")
} }
} }
TEST_CASE("wxImage::Clipboard", "[image][clipboard]")
{
#if wxUSE_CLIPBOARD && wxUSE_DATAOBJ
wxInitAllImageHandlers();
wxImage imgOriginal;
REQUIRE(imgOriginal.LoadFile("horse.png") == true);
wxImageDataObject* dobj1 = new wxImageDataObject(imgOriginal);
{
wxClipboardLocker lockClip;
REQUIRE(wxTheClipboard->SetData(dobj1) == true);
}
wxImageDataObject dobj2;
{
wxClipboardLocker lockClip;
REQUIRE(wxTheClipboard->GetData(dobj2) == true);
}
wxImage imgRetrieved = dobj2.GetImage();
REQUIRE(imgRetrieved.IsOk());
CompareImage(*wxImage::FindHandler(wxBITMAP_TYPE_PNG), imgRetrieved, 0, &imgOriginal);
#endif // wxUSE_CLIPBOARD && wxUSE_DATAOBJ
}
/* /*
TODO: add lots of more tests to wxImage functions TODO: add lots of more tests to wxImage functions
*/ */