From c56fd7a30423f266f006f549bf585925e1b0131d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 20 Jul 2012 11:55:10 +0000 Subject: [PATCH] Use both URL-specific and plain text formats in wxGTK wxURLDataObject. Just as in wxMSW, it makes sense to put URLs on clipboard (or drag them) in both URL-specific and plain text formats to facilitate pasting (or dropping) them into other applications. So make wxURLDataObject in wxGTK a composite data object containing both its old data object and wxTextDataObject. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72161 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/gtk/dataobj2.h | 29 +++-------- src/gtk/dataobj.cpp | 101 ++++++++++++++++++++++++++++++++------ 2 files changed, 93 insertions(+), 37 deletions(-) diff --git a/include/wx/gtk/dataobj2.h b/include/wx/gtk/dataobj2.h index 4433cc933a..7629027b33 100644 --- a/include/wx/gtk/dataobj2.h +++ b/include/wx/gtk/dataobj2.h @@ -93,34 +93,19 @@ public: // wxURLDataObject is a specialization of wxDataObject for URLs // ---------------------------------------------------------------------------- -class WXDLLIMPEXP_CORE wxURLDataObject : public wxDataObjectSimple +class WXDLLIMPEXP_CORE wxURLDataObject : public wxDataObjectComposite { public: wxURLDataObject(const wxString& url = wxEmptyString); - wxString GetURL() const { return m_url; } - void SetURL(const wxString& url) { m_url = url; } - - virtual size_t GetDataSize() const; - virtual bool GetDataHere(void *buf) const; - virtual bool SetData(size_t len, const void *buf); - - // Must provide overloads to avoid hiding them (and warnings about it) - virtual size_t GetDataSize(const wxDataFormat&) const - { - return GetDataSize(); - } - virtual bool GetDataHere(const wxDataFormat&, void *buf) const - { - return GetDataHere(buf); - } - virtual bool SetData(const wxDataFormat&, size_t len, const void *buf) - { - return SetData(len, buf); - } + wxString GetURL() const; + void SetURL(const wxString& url); private: - wxString m_url; + class wxTextURIListDataObject* const m_dobjURIList; + wxTextDataObject* const m_dobjText; + + wxDECLARE_NO_COPY_CLASS(wxURLDataObject); }; diff --git a/src/gtk/dataobj.cpp b/src/gtk/dataobj.cpp index 55c81cfc77..db02431737 100644 --- a/src/gtk/dataobj.cpp +++ b/src/gtk/dataobj.cpp @@ -420,30 +420,101 @@ void wxBitmapDataObject::DoConvertToPng() // wxURLDataObject // ---------------------------------------------------------------------------- -wxURLDataObject::wxURLDataObject(const wxString& url) : - wxDataObjectSimple( wxDataFormat( g_fileAtom ) ) +class wxTextURIListDataObject : public wxDataObjectSimple { - m_url = url; -} +public: + wxTextURIListDataObject(const wxString& url) + : wxDataObjectSimple(wxDataFormat(g_fileAtom)), + m_url(url) + { + } + + const wxString& GetURL() const { return m_url; } + void SetURL(const wxString& url) { m_url = url; } + + + virtual size_t GetDataSize() const + { + // It is not totally clear whether we should include "\r\n" at the end + // of the string if there is only one URL or not, but not doing it + // doesn't seem to create any problems, so keep things simple. + return strlen(m_url.utf8_str()) + 1; + } + + virtual bool GetDataHere(void *buf) const + { + char* const dst = static_cast(buf); + + strcpy(dst, m_url.utf8_str()); + + return true; + } + + virtual bool SetData(size_t len, const void *buf) + { + const char* const src = static_cast(buf); + + // The string might be "\r\n"-terminated but this is not necessarily + // the case (e.g. when dragging an URL from Firefox, it isn't). + if ( len > 1 && src[len - 1] == '\n' ) + { + if ( len > 2 && src[len - 2] == '\r' ) + len--; + + len--; + } + + m_url = wxString::FromUTF8(src, len); -size_t wxURLDataObject::GetDataSize() const + return true; + } + + // Must provide overloads to avoid hiding them (and warnings about it) + virtual size_t GetDataSize(const wxDataFormat&) const + { + return GetDataSize(); + } + virtual bool GetDataHere(const wxDataFormat&, void *buf) const + { + return GetDataHere(buf); + } + virtual bool SetData(const wxDataFormat&, size_t len, const void *buf) + { + return SetData(len, buf); + } + +private: + wxString m_url; +}; + +wxURLDataObject::wxURLDataObject(const wxString& url) : + m_dobjURIList(new wxTextURIListDataObject(url)), + m_dobjText(new wxTextDataObject(url)) { - return strlen(m_url.utf8_str()) + 1; + // Use both URL-specific format and a plain text one to ensure that URLs + // can be pasted into any application. + Add(m_dobjURIList, true /* preferred */); + Add(m_dobjText); } -bool wxURLDataObject::GetDataHere(void *buf) const +void wxURLDataObject::SetURL(const wxString& url) { - strcpy(static_cast(buf), m_url.utf8_str()); - - return true; + m_dobjURIList->SetURL(url); + m_dobjText->SetText(url); } -bool wxURLDataObject::SetData(size_t len, const void *buf) +wxString wxURLDataObject::GetURL() const { - m_url = wxString::FromUTF8(static_cast(buf), len); - - return true; + if ( GetReceivedFormat() == g_fileAtom ) + { + // If we received the URL as an URI, use it. + return m_dobjURIList->GetURL(); + } + else // Otherwise we either got it as text or didn't get anything yet. + { + // In either case using the text format should be fine. + return m_dobjText->GetText(); + } } - #endif // wxUSE_DATAOBJ -- 2.45.2