/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include "ImagePreparer.hxx" #include "Transmitter.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::sd; using namespace ::osl; using namespace ::com::sun::star; using namespace ::com::sun::star::uno; ImagePreparer::ImagePreparer( uno::Reference _xController, Transmitter *aTransmitter ) : Timer("sd ImagePreparer"), xController(std::move( _xController )), pTransmitter( aTransmitter ) { SAL_INFO( "sdremote", "ImagePreparer - start" ); SetTimeout( 50 ); mnSendingSlide = 0; Start(); } ImagePreparer::~ImagePreparer() { SAL_INFO( "sdremote", "ImagePreparer - stop" ); Stop(); } void ImagePreparer::Invoke() { sal_uInt32 aSlides = xController->getSlideCount(); SAL_INFO( "sdremote", "ImagePreparer " << xController->isRunning() << " sending slide " << mnSendingSlide << " of " << aSlides ); if ( xController->isRunning() && // not stopped/disposed of. mnSendingSlide < aSlides ) { sendPreview( mnSendingSlide ); sendNotes( mnSendingSlide ); mnSendingSlide++; Start(); } else Stop(); } void ImagePreparer::sendPreview( sal_uInt32 aSlideNumber ) { sal_uInt64 aSize; uno::Sequence aImageData = preparePreview( aSlideNumber, 320, 240, aSize ); if ( !xController->isRunning() ) return; OUStringBuffer aStrBuffer; ::comphelper::Base64::encode( aStrBuffer, aImageData ); OString aEncodedShortString = OUStringToOString( aStrBuffer, RTL_TEXTENCODING_UTF8 ); // Start the writing OString aBuffer = "slide_preview\n" + OString::number(aSlideNumber) + "\n" + aEncodedShortString + "\n\n"; pTransmitter->addMessage( aBuffer, Transmitter::PRIORITY_LOW ); } uno::Sequence ImagePreparer::preparePreview( sal_uInt32 aSlideNumber, sal_uInt32 aWidth, sal_uInt32 aHeight, sal_uInt64 &rSize ) { OUString aFileURL; FileBase::createTempFile( nullptr, nullptr, &aFileURL ); uno::Reference< drawing::XGraphicExportFilter > xFilter = drawing::GraphicExportFilter::create( ::comphelper::getProcessComponentContext() ); if ( !xController->isRunning() ) return uno::Sequence(); uno::Reference< lang::XComponent > xSourceDoc( xController->getSlideByIndex( aSlideNumber ), uno::UNO_QUERY_THROW ); xFilter->setSourceDocument( xSourceDoc ); uno::Sequence< beans::PropertyValue > aFilterData{ comphelper::makePropertyValue(u"PixelWidth"_ustr, aWidth), comphelper::makePropertyValue(u"PixelHeight"_ustr, aHeight), comphelper::makePropertyValue(u"ColorMode"_ustr, sal_Int32(0)) // 0: Color, 1: B&W }; uno::Sequence< beans::PropertyValue > aProps{ comphelper::makePropertyValue(u"MediaType"_ustr, u"image/png"_ustr), comphelper::makePropertyValue(u"URL"_ustr, aFileURL), comphelper::makePropertyValue(u"FilterData"_ustr, aFilterData) }; xFilter->filter( aProps ); File aFile(aFileURL); if (aFile.open(0) != osl::File::E_None) return uno::Sequence(); sal_uInt64 aRead; rSize = 0; aFile.getSize( rSize ); uno::Sequence aContents( rSize ); aFile.read( aContents.getArray(), rSize, aRead ); if (aRead != rSize) aContents.realloc(aRead); aFile.close(); File::remove( aFileURL ); return aContents; } void ImagePreparer::sendNotes( sal_uInt32 aSlideNumber ) { OString aNotes = prepareNotes( aSlideNumber ); if ( aNotes.isEmpty() ) return; if ( !xController->isRunning() ) return; // Start the writing OString aBuffer = "slide_notes\n" + OString::number( static_cast(aSlideNumber) ) + "\n" "" + aNotes + "" "\n\n"; pTransmitter->addMessage( aBuffer, Transmitter::PRIORITY_LOW ); } // Code copied from sdremote/source/presenter/PresenterNotesView.cxx OString ImagePreparer::prepareNotes( sal_uInt32 aSlideNumber ) { OUStringBuffer aRet; if ( !xController->isRunning() ) return ""_ostr; uno::Reference aNotesPage; uno::Reference< drawing::XDrawPage > xSourceDoc( xController->getSlideByIndex( aSlideNumber ), uno::UNO_SET_THROW ); uno::Reference xPresentationPage( xSourceDoc, UNO_QUERY); if (xPresentationPage.is()) aNotesPage = xPresentationPage->getNotesPage(); else return ""_ostr; static constexpr OUString sNotesShapeName ( u"com.sun.star.presentation.NotesShape"_ustr ); static constexpr OUStringLiteral sTextShapeName ( u"com.sun.star.drawing.TextShape" ); if (aNotesPage.is()) { // Iterate over all shapes and find the one that holds the text. sal_Int32 nCount (aNotesPage->getCount()); for (sal_Int32 nIndex=0; nIndex xServiceName ( aNotesPage->getByIndex(nIndex), UNO_QUERY); if (xServiceName.is() && xServiceName->getServiceName() == sNotesShapeName) { uno::Reference xText (xServiceName, UNO_QUERY); if (xText.is()) { aRet.append(xText->getString() + "
"); } } else { uno::Reference xShapeDescriptor ( aNotesPage->getByIndex(nIndex), UNO_QUERY); if (xShapeDescriptor.is()) { OUString sType (xShapeDescriptor->getShapeType()); if (sType == sNotesShapeName || sType == sTextShapeName) { uno::Reference xText ( aNotesPage->getByIndex(nIndex), UNO_QUERY); if (xText.is()) { aRet.append(xText->getString() + "
"); } } } } } } // Replace all newlines with tags for ( sal_Int32 i = 0; i < aRet.getLength(); i++ ) { if ( aRet[i] == '\n' ) { aRet[i]= '<'; aRet.insert( i+1, "br/>" ); } } return OUStringToOString( aRet, RTL_TEXTENCODING_UTF8 ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */