The interaction with the clipboard is randomly successful. Below code adds different formats to clipboard:
std::pair<wxGridCellCoords, wxGridCellCoords> AddSelToClipbrd(const WorksheetBase* ws)
{
//some code
wxString HTMLStr = GenerateHTMLTable(ws, TL, BR);
wxString XMLStr = xml::GenerateXMLString(ws, TL, BR);
wxString TabStr = GenerateTabString(ws, TL, BR);
wxDataObjectComposite* dataobj = new wxDataObjectComposite();
dataobj->Add(new xml::XMLDataObject(XMLStr), true);
dataobj->Add(new wxTextDataObject(TabStr));
dataobj->Add(new wxHTMLDataObject(HTMLStr));
if (wxTheClipboard->Open())
{
wxTheClipboard->SetData(dataobj);
wxTheClipboard->Flush();
wxTheClipboard->Close();
}
}
The XMLDataFormat is implemented as follows:
export struct XMLDataFormat : public wxDataFormat
{
XMLDataFormat() : wxDataFormat("XMLDataFormat") {}
};
export class XMLDataObject : public wxDataObjectSimple
{
public:
XMLDataObject(const wxString& xmlstring = wxEmptyString) :
wxDataObjectSimple(), m_XMLString{ xmlstring }
{
SetFormat(XMLDataFormat());
}
size_t GetLength() const
{
std::string s = (const char*)m_XMLString.mb_str(wxConvUTF8);
return s.length() + 1;
}
wxString GetXML() const {
return m_XMLString;
}
void SetXML(const wxString& xml) {
m_XMLString = xml;
}
// Must provide overloads to avoid hiding them (and warnings about it)
size_t GetDataSize() const {
return GetLength();
}
bool GetDataHere(void* buf) const
{
std::string s = (const char*)m_XMLString.mb_str(wxConvUTF8);
memcpy(buf, s.c_str(), s.length() + 1);
return true;
}
bool SetData(size_t len, const void* buf) {
m_XMLString = wxString::FromUTF8((const char*)buf, len + 1);
return true;
}
size_t GetDataSize(const wxDataFormat&) const {
return GetDataSize();
}
bool GetDataHere(const wxDataFormat&, void* buf) const {
return GetDataHere(buf);
}
bool SetData(const wxDataFormat&, size_t len, const void* buf)
{
return SetData(len, buf);
}
private:
wxString m_XMLString;
};
To get the XML data from the clipboard:
wxString GetXMLData()
{
if (!wxTheClipboard->Open())
return wxEmptyString;
if (!wxTheClipboard->IsSupported(XMLDataFormat()))
return wxEmptyString;
XMLDataObject xmlObj;
wxTheClipboard->GetData(xmlObj);
wxTheClipboard->Close();
return xmlObj.GetXML();
}
The problem seems to be that GetXMLData returns empty string but this is random; so I run the application and it gives error and then quit the application and run it again (same copy/paste) and it pastes (always tested with the same data).
Any ideas appreciated.
It seems the error comes from implementation of XMLDataObject
. Therefore, instead of deriving from wxDataObjectSimple
now it is changed to wxTextDataObject
and so far it works stable.
So the new implementation is as simple as the following:
export struct XMLDataFormat : public wxDataFormat
{
XMLDataFormat() : wxDataFormat("XMLDataFormat") {}
};
export class XMLDataObject : public wxTextDataObject
{
public:
XMLDataObject(const std::string& UTF8 = "") :
wxTextDataObject(UTF8)
{
SetFormat(XMLDataFormat());
}
};