LibreOffice Module sd (master) 1
ImagePreparer.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include "ImagePreparer.hxx"
21#include "Transmitter.hxx"
22
23#include <comphelper/base64.hxx>
26#include <osl/file.hxx>
27#include <rtl/ustrbuf.hxx>
28#include <sal/log.hxx>
29
30#include <com/sun/star/beans/PropertyValue.hpp>
31#include <com/sun/star/drawing/GraphicExportFilter.hpp>
32#include <com/sun/star/lang/XServiceName.hpp>
33#include <com/sun/star/presentation/XSlideShowController.hpp>
34#include <com/sun/star/presentation/XPresentationPage.hpp>
35#include <com/sun/star/text/XTextRange.hpp>
36#include <utility>
37
38using namespace ::sd;
39using namespace ::osl;
40using namespace ::com::sun::star;
41using namespace ::com::sun::star::uno;
42
43ImagePreparer::ImagePreparer(
44 uno::Reference<presentation::XSlideShowController> _xController,
45 Transmitter *aTransmitter )
46 : Timer("sd ImagePreparer"),
47 xController(std::move( _xController )),
48 pTransmitter( aTransmitter )
49{
50 SAL_INFO( "sdremote", "ImagePreparer - start" );
51 SetTimeout( 50 );
53 Start();
54}
55
57{
58 SAL_INFO( "sdremote", "ImagePreparer - stop" );
59 Stop();
60}
61
63{
64 sal_uInt32 aSlides = xController->getSlideCount();
65 SAL_INFO( "sdremote", "ImagePreparer " << xController->isRunning() <<
66 " sending slide " << mnSendingSlide << " of " << aSlides );
67 if ( xController->isRunning() && // not stopped/disposed of.
68 mnSendingSlide < aSlides )
69 {
73 Start();
74 }
75 else
76 Stop();
77}
78
79void ImagePreparer::sendPreview( sal_uInt32 aSlideNumber )
80{
81 sal_uInt64 aSize;
82 uno::Sequence<sal_Int8> aImageData = preparePreview( aSlideNumber, 320, 240,
83 aSize );
84 if ( !xController->isRunning() )
85 return;
86
87 OUStringBuffer aStrBuffer;
88 ::comphelper::Base64::encode( aStrBuffer, aImageData );
89
90 OString aEncodedShortString = OUStringToOString(
91 aStrBuffer, RTL_TEXTENCODING_UTF8 );
92
93 // Start the writing
94 OString aBuffer = "slide_preview\n" +
95 OString::number(aSlideNumber) +
96 "\n" + aEncodedShortString + "\n\n";
99
100}
101
102uno::Sequence<sal_Int8> ImagePreparer::preparePreview(
103 sal_uInt32 aSlideNumber, sal_uInt32 aWidth, sal_uInt32 aHeight,
104 sal_uInt64 &rSize )
105{
106 OUString aFileURL;
107 FileBase::createTempFile( nullptr, nullptr, &aFileURL );
108
109 uno::Reference< drawing::XGraphicExportFilter > xFilter =
110 drawing::GraphicExportFilter::create( ::comphelper::getProcessComponentContext() );
111
112 if ( !xController->isRunning() )
113 return uno::Sequence<sal_Int8>();
114
115 uno::Reference< lang::XComponent > xSourceDoc(
116 xController->getSlideByIndex( aSlideNumber ),
117 uno::UNO_QUERY_THROW );
118
119 xFilter->setSourceDocument( xSourceDoc );
120
121 uno::Sequence< beans::PropertyValue > aFilterData{
122 comphelper::makePropertyValue("PixelWidth", aWidth),
123 comphelper::makePropertyValue("PixelHeight", aHeight),
124 comphelper::makePropertyValue("ColorMode", sal_Int32(0)) // 0: Color, 1: B&W
125 };
126
127 uno::Sequence< beans::PropertyValue > aProps{
128 comphelper::makePropertyValue("MediaType", OUString( "image/png" )),
129 comphelper::makePropertyValue("URL", aFileURL),
130 comphelper::makePropertyValue("FilterData", aFilterData)
131 };
132
133 xFilter->filter( aProps );
134
135 File aFile(aFileURL);
136 if (aFile.open(0) != osl::File::E_None)
137 return uno::Sequence<sal_Int8>();
138
139 sal_uInt64 aRead;
140 rSize = 0;
141 aFile.getSize( rSize );
142 uno::Sequence<sal_Int8> aContents( rSize );
143
144 aFile.read( aContents.getArray(), rSize, aRead );
145 if (aRead != rSize)
146 aContents.realloc(aRead);
147
148 aFile.close();
149 File::remove( aFileURL );
150 return aContents;
151
152}
153
154void ImagePreparer::sendNotes( sal_uInt32 aSlideNumber )
155{
156
157 OString aNotes = prepareNotes( aSlideNumber );
158
159 if ( aNotes.isEmpty() )
160 return;
161
162 if ( !xController->isRunning() )
163 return;
164
165 // Start the writing
166 OString aBuffer =
167 "slide_notes\n" +
168 OString::number( static_cast<sal_Int32>(aSlideNumber) ) +
169 "\n"
170 "<html><body>" +
171 aNotes +
172 "</body></html>"
173 "\n\n";
176}
177
178// Code copied from sdremote/source/presenter/PresenterNotesView.cxx
179OString ImagePreparer::prepareNotes( sal_uInt32 aSlideNumber )
180{
181 OUStringBuffer aRet;
182
183 if ( !xController->isRunning() )
184 return "";
185
186 uno::Reference<css::drawing::XDrawPage> aNotesPage;
187 uno::Reference< drawing::XDrawPage > xSourceDoc(
188 xController->getSlideByIndex( aSlideNumber ),
189 uno::UNO_SET_THROW );
190 uno::Reference<presentation::XPresentationPage> xPresentationPage(
191 xSourceDoc, UNO_QUERY);
192 if (xPresentationPage.is())
193 aNotesPage = xPresentationPage->getNotesPage();
194 else
195 return "";
196
197 static constexpr OUStringLiteral sNotesShapeName (
198 u"com.sun.star.presentation.NotesShape" );
199 static constexpr OUStringLiteral sTextShapeName (
200 u"com.sun.star.drawing.TextShape" );
201
202 if (aNotesPage.is())
203 {
204
205 // Iterate over all shapes and find the one that holds the text.
206 sal_Int32 nCount (aNotesPage->getCount());
207 for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
208 {
209
210 uno::Reference<lang::XServiceName> xServiceName (
211 aNotesPage->getByIndex(nIndex), UNO_QUERY);
212 if (xServiceName.is()
213 && xServiceName->getServiceName() == sNotesShapeName)
214 {
215 uno::Reference<text::XTextRange> xText (xServiceName, UNO_QUERY);
216 if (xText.is())
217 {
218 aRet.append(xText->getString() + "<br/>");
219 }
220 }
221 else
222 {
223 uno::Reference<drawing::XShapeDescriptor> xShapeDescriptor (
224 aNotesPage->getByIndex(nIndex), UNO_QUERY);
225 if (xShapeDescriptor.is())
226 {
227 OUString sType (xShapeDescriptor->getShapeType());
228 if (sType == sNotesShapeName || sType == sTextShapeName)
229 {
230 uno::Reference<text::XTextRange> xText (
231 aNotesPage->getByIndex(nIndex), UNO_QUERY);
232 if (xText.is())
233 {
234 aRet.append(xText->getString() + "<br/>");
235 }
236 }
237 }
238 }
239 }
240 }
241 // Replace all newlines with <br> tags
242 for ( sal_Int32 i = 0; i < aRet.getLength(); i++ )
243 {
244 if ( aRet[i] == '\n' )
245 {
246 aRet[i]= '<';
247 aRet.insert( i+1, "br/>" );
248 }
249 }
250 return OUStringToOString( aRet, RTL_TEXTENCODING_UTF8 );
251}
252
253/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sType
void Stop()
void SetTimeout(sal_uInt64 nTimeoutMs)
virtual void Start(bool bStartTimer=true) override
static void encode(OUStringBuffer &aStrBuffer, const css::uno::Sequence< sal_Int8 > &aPass)
virtual void Invoke() override
void sendPreview(sal_uInt32 aSlideNumber)
virtual ~ImagePreparer() override
Transmitter * pTransmitter
void sendNotes(sal_uInt32 aSlideNumber)
css::uno::Sequence< sal_Int8 > preparePreview(sal_uInt32 aSlideNumber, sal_uInt32 aWidth, sal_uInt32 aHeight, sal_uInt64 &rSize)
sal_uInt32 mnSendingSlide
OString prepareNotes(sal_uInt32 aSlideNumber)
css::uno::Reference< css::presentation::XSlideShowController > xController
void addMessage(const OString &aMessage, const Priority aPriority)
Definition: Transmitter.cxx:68
int nCount
float u
sal_Int32 nIndex
#define SAL_INFO(area, stream)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
int i
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
Reference< XController > xController
std::unique_ptr< char[]> aBuffer