diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2020-01-28 17:57:30 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2020-01-28 20:08:46 +0100 |
commit | 5d1a540963d1c5b952655414fc77367f67db968d (patch) | |
tree | 7103dd3645e03b9d4d130ae0ac0c7970e7caa2bf /dtrans | |
parent | 1565bcaff401366937c800d8f4617df2b4f68271 (diff) |
dtrans win32: implement support for pasting when the handle type is stream
Steps to reproduce the problem: select an image in Word on Windows,
copy, paste into Writer -> nothing happens. A workaround is to use paste
special, and select the metafile paste, not the bitmap one.
The root cause was that clipboard contents on Windows can have different
handle types and we only supported the memory and the metafile cases.
An alternative fix would be to handle this at a higher level, e.g.
TransferableDataHelper::GetBitmapEx() in vcl could fall back to EMF when
the bitmap formats fail, but that would not work for other applications
that only offer bitmap formats with a stream handle type.
Change-Id: Iccaaf33df949ee73185acbd55b61d00a12d210ee
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87649
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
Diffstat (limited to 'dtrans')
-rw-r--r-- | dtrans/source/win32/dtobj/DOTransferable.cxx | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/dtrans/source/win32/dtobj/DOTransferable.cxx b/dtrans/source/win32/dtobj/DOTransferable.cxx index afa705abfc56..c331b1d95b90 100644 --- a/dtrans/source/win32/dtobj/DOTransferable.cxx +++ b/dtrans/source/win32/dtobj/DOTransferable.cxx @@ -20,6 +20,7 @@ #include <sal/types.h> #include <rtl/process.h> #include <osl/diagnose.h> +#include <sal/log.hxx> #include "DOTransferable.hxx" #include "../misc/ImplHelper.hxx" @@ -59,6 +60,7 @@ namespace void clipDataToByteStream( CLIPFORMAT cf, STGMEDIUM stgmedium, CDOTransferable::ByteSequence_t& aByteSequence ) { CStgTransferHelper memTransferHelper; + LPSTREAM pStream = nullptr; switch( stgmedium.tymed ) { @@ -75,7 +77,7 @@ void clipDataToByteStream( CLIPFORMAT cf, STGMEDIUM stgmedium, CDOTransferable:: break; case TYMED_ISTREAM: - //TODO: Has to be implemented + pStream = stgmedium.pstm; break; default: @@ -83,6 +85,41 @@ void clipDataToByteStream( CLIPFORMAT cf, STGMEDIUM stgmedium, CDOTransferable:: break; } + if (pStream) + { + // We have a stream, read from it. + STATSTG aStat; + HRESULT hr = pStream->Stat(&aStat, STATFLAG_NONAME); + if (FAILED(hr)) + { + SAL_WARN("dtrans", "clipDataToByteStream: Stat() failed"); + return; + } + + size_t nMemSize = aStat.cbSize.QuadPart; + aByteSequence.realloc(nMemSize); + LARGE_INTEGER li; + li.QuadPart = 0; + hr = pStream->Seek(li, STREAM_SEEK_SET, NULL); + if (FAILED(hr)) + { + SAL_WARN("dtrans", "clipDataToByteStream: Seek() failed"); + } + + ULONG nRead = 0; + hr = pStream->Read(aByteSequence.getArray(), nMemSize, &nRead); + if (FAILED(hr)) + { + SAL_WARN("dtrans", "clipDataToByteStream: Read() failed"); + } + if (nRead < nMemSize) + { + SAL_WARN("dtrans", "clipDataToByteStream: Read() was partial"); + } + + return; + } + int nMemSize = memTransferHelper.memSize( cf ); aByteSequence.realloc( nMemSize ); memTransferHelper.read( aByteSequence.getArray( ), nMemSize ); @@ -393,6 +430,14 @@ CDOTransferable::ByteSequence_t CDOTransferable::getClipboardData( CFormatEtc& a hr = m_rDataObject->GetData( aTempFormat, &stgmedium ); } + if (FAILED(hr) && aFormatEtc.getTymed() == TYMED_HGLOBAL) + { + // Handle type is not memory, try stream. + CFormatEtc aTempFormat(aFormatEtc); + aTempFormat.setTymed(TYMED_ISTREAM); + hr = m_rDataObject->GetData(aTempFormat, &stgmedium); + } + if ( FAILED( hr ) ) { OSL_ASSERT( (hr != E_INVALIDARG) && |