Looking for help for clipboard in Math

Michael Stahl mstahl at redhat.com
Mon Jun 8 05:19:25 PDT 2015


On 06.06.2015 22:03, Regina Henschel wrote:
> Hi Michael,
> 
> thank-you for looking at my problems.
> 
> Michael Stahl schrieb:
>> On 05.06.2015 01:44, Regina Henschel wrote:
>>> Hi all,
>>>
>>> I struggle with the clipboard. My goal is to import MathML in module
>>> Math from clipboard, similar as it is imported from file. But I'm stuck.
>>> Therefore some questions:
> [skipped a lot of text]
> 
> Helpful comments. Looking around I think, the connection to the OS is 
> done in /main/dtrans/source/win32/
> 
> I have found the table m_TranslTable, which refers the SOT_FORMATSTR_IDs 
> from exchange.cxx. I'll try what happens, when I add the MathML format 
> there too. I had already added it in exchange.cxx, but that was not 
> enough to be recognized. [I need some time for that. I will report back, 
> when I have finished.]

that sounds plausible.

>>> (5)
>>> I try to use SmViewShell::InsertFrom(SfxMedium &rMedium). It seems to
>>> work, but when the process arrives at SmXMLImport::endDocument(void),
>>> the node tree is empty.  Any tips, what I might have missed?
>>
>> how do you prepare the SfxMedium?  i'm not sure if it requires an actual
>> file, or if it can read from an input stream (XInputStream); it probably
>> can't read from a Sequence<sal_Int8> buffer directly...
>>
>> there is a SfxMedium::setStreamToLoadFrom() which looks promising.
> 
> I have used:
> 
> TransferableDataHelper aDataHelper( 
> TransferableDataHelper::CreateFromSystemClipboard(GetEditWindow()) );
> uno::Reference < io::XInputStream > xStrm;
> aDataHelper.GetInputStream( nId, xStrm );
> SfxMedium* pClipboardMedium = new SfxMedium();
> SfxMedium aClipboardMedium = *pClipboardMedium;

this is probably not a good idea: the aClipboardMedium is now a copy of
pClipboardMedium (using the copy-constructor), so any modification to
aClipboardMedium will not be visible if you use pClipboardMedium.

if you need a pointer, better do it the other way around, and use "&
aClipbardMedium" when needed.

> aClipboardMedium.setStreamToLoadFrom( xStrm, sal_True /*bIsReadOnly*/ );
> InsertFrom(aClipboardMedium);

oh, nice, the TransferableDataHelper can already get you a stream.

> When I then proof it with
> 
> SvStream* pStream = aClipboardMedium.GetInStream();
> ...
> sal_uLong nBytesRead = pStream->Read( aBuffer, nBufferSize );
> printf("%s \n", aBuffer);
> 
> I can see, that the stream contains the expected MathML-source in case 
> the clipboard viewer lists the clipboard format "application/mathml+xml".

ok, so we can read the data.

do you re-wind the stream with Seek() after this debug output?  perhaps
the import filter reads from the current position, which is going to be
in the middle or at the end of the stream after this.

> In addition I have set the filter by
> 
> const SfxFilter* pMathFilter = SfxFilter::GetFilterByName( 
> String::CreateFromAscii(MATHML_XML) );
> aClipboardMedium.SetFilter(pMathFilter);
> 
> so that
> 
> if ( rFltName.EqualsAscii(MATHML_XML) )
> 
> in InsertFrom becomes true

it looks like SmXMLImportWrapper is using the usual xmloff XML-parsing
stuff.

so i would try to check if the root element of the MathML document is
being recognized; set a breakpoint or add a SAL_DEBUG output in the
right CreateChildContext() method...

this is apparently SmXMLImport::CreateContext() - which should create a
SmXMLDocContext_Impl, since there's not going to be a "office" namespace.

most of the work is going on in the CreateChildContext() and
EndElement() overrides in various child classes of SmXMLImportContext;
basically xmloff maintains a stack of contexts, one for each currently
open XML element; it then calls StartElement() / CreateChildContext() /
EndElement() etc. on the context that is on top of the stack.

this means it's quite annoying to step through the import with a
debugger, since a lot of it is various abstraction layers that are not
very interesting but you still have to step through them; it's best to
set breakpoints in the "interesting" places and only start stepping into
the lower layers as a last resort if you have no idea why the
interesting place is not reached.

>> you can create an input stream from the buffer via SvMemoryStream and
>> then wrap that in utl::OInputStreamWrapper.
> 
> You mean, it will be possible to use the "Unicode-Text"? That would 
> help, when copying from Websites. But first I need to solve the problem, 
> that I get no node-tree, and the problem to detect the clipboard correctly.

no, i meant how to convert the clipboard Sequence<sal_Int8> to an input
stream, but i missed that TransferableDataHelper::GetInputStream()
already does this for you :)



More information about the LibreOffice mailing list