1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "ImagePreparer.hxx"
21 #include "Transmitter.hxx"
23 #include <comphelper/base64.hxx>
24 #include <comphelper/processfactory.hxx>
25 #include <osl/file.hxx>
26 #include <rtl/ustrbuf.hxx>
27 #include <sax/tools/converter.hxx>
28 #include <rtl/strbuf.hxx>
29 #include <sal/log.hxx>
30 #include <unotools/streamwrap.hxx>
32 #include <svl/itemset.hxx>
33 #include <sfx2/docfile.hxx>
35 #include <com/sun/star/beans/PropertyValue.hpp>
36 #include <com/sun/star/container/XNameAccess.hpp>
37 #include <com/sun/star/document/XFilter.hpp>
38 #include <com/sun/star/document/XImporter.hpp>
39 #include <com/sun/star/document/XExporter.hpp>
40 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
41 #include <com/sun/star/lang/XServiceName.hpp>
42 #include <com/sun/star/presentation/XSlideShowController.hpp>
43 #include <com/sun/star/presentation/XPresentationPage.hpp>
44 #include <com/sun/star/text/XTextRange.hpp>
47 using namespace ::osl
;
48 using namespace ::com::sun::star
;
49 using namespace ::com::sun::star::uno
;
51 ImagePreparer::ImagePreparer(
52 const uno::Reference
<presentation::XSlideShowController
>& rxController
,
53 Transmitter
*aTransmitter
)
54 : xController( rxController
),
55 pTransmitter( aTransmitter
)
57 SAL_INFO( "sdremote", "ImagePreparer - start" );
63 ImagePreparer::~ImagePreparer()
65 SAL_INFO( "sdremote", "ImagePreparer - stop" );
69 void ImagePreparer::Invoke()
71 sal_uInt32 aSlides
= xController
->getSlideCount();
72 SAL_INFO( "sdremote", "ImagePreparer " << xController
->isRunning() <<
73 " sending slide " << mnSendingSlide
<< " of " << aSlides
);
74 if ( xController
->isRunning() && // not stopped/disposed of.
75 mnSendingSlide
< aSlides
)
77 sendPreview( mnSendingSlide
);
78 sendNotes( mnSendingSlide
);
86 void ImagePreparer::sendPreview( sal_uInt32 aSlideNumber
)
89 uno::Sequence
<sal_Int8
> aImageData
= preparePreview( aSlideNumber
, 320, 240,
91 if ( !xController
->isRunning() )
94 OUStringBuffer aStrBuffer
;
95 ::comphelper::Base64::encode( aStrBuffer
, aImageData
);
97 OString aEncodedShortString
= OUStringToOString(
98 aStrBuffer
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
);
101 OStringBuffer aBuffer
;
103 aBuffer
.append( "slide_preview\n" );
105 aBuffer
.append( static_cast<sal_Int32
>(aSlideNumber
) );
106 aBuffer
.append( "\n" );
108 aBuffer
.append( aEncodedShortString
.getStr() );
109 aBuffer
.append( "\n\n" );
110 pTransmitter
->addMessage( aBuffer
.makeStringAndClear(),
111 Transmitter::PRIORITY_LOW
);
115 uno::Sequence
<sal_Int8
> ImagePreparer::preparePreview(
116 sal_uInt32 aSlideNumber
, sal_uInt32 aWidth
, sal_uInt32 aHeight
,
120 FileBase::createTempFile( nullptr, nullptr, &aFileURL
);
122 uno::Reference
< drawing::XGraphicExportFilter
> xFilter
=
123 drawing::GraphicExportFilter::create( ::comphelper::getProcessComponentContext() );
125 if ( !xController
->isRunning() )
126 return uno::Sequence
<sal_Int8
>();
128 uno::Reference
< lang::XComponent
> xSourceDoc(
129 xController
->getSlideByIndex( aSlideNumber
),
130 uno::UNO_QUERY_THROW
);
132 xFilter
->setSourceDocument( xSourceDoc
);
134 uno::Sequence
< beans::PropertyValue
> aFilterData(3);
136 aFilterData
[0].Name
= "PixelWidth";
137 aFilterData
[0].Value
<<= aWidth
;
139 aFilterData
[1].Name
= "PixelHeight";
140 aFilterData
[1].Value
<<= aHeight
;
142 aFilterData
[2].Name
= "ColorMode";
143 aFilterData
[2].Value
<<= sal_Int32(0); // 0: Color, 1: B&W
145 uno::Sequence
< beans::PropertyValue
> aProps(3);
147 aProps
[0].Name
= "MediaType";
148 aProps
[0].Value
<<= OUString( "image/png" );
150 aProps
[1].Name
= "URL";
151 aProps
[1].Value
<<= aFileURL
;
153 aProps
[2].Name
= "FilterData";
154 aProps
[2].Value
<<= aFilterData
;
156 xFilter
->filter( aProps
);
158 // FIXME: error handling.
160 File
aFile( aFileURL
);
164 aFile
.getSize( rSize
);
165 uno::Sequence
<sal_Int8
> aContents( rSize
);
167 aFile
.read( aContents
.getArray(), rSize
, aRead
);
169 File::remove( aFileURL
);
174 void ImagePreparer::sendNotes( sal_uInt32 aSlideNumber
)
177 OString aNotes
= prepareNotes( aSlideNumber
);
179 if ( aNotes
.isEmpty() )
182 if ( !xController
->isRunning() )
186 OStringBuffer aBuffer
;
188 aBuffer
.append( "slide_notes\n" );
190 aBuffer
.append( static_cast<sal_Int32
>(aSlideNumber
) );
191 aBuffer
.append( "\n" );
193 aBuffer
.append( "<html><body>" );
194 aBuffer
.append( aNotes
);
195 aBuffer
.append( "</body></html>" );
196 aBuffer
.append( "\n\n" );
197 pTransmitter
->addMessage( aBuffer
.makeStringAndClear(),
198 Transmitter::PRIORITY_LOW
);
201 // Code copied from sdremote/source/presenter/PresenterNotesView.cxx
202 OString
ImagePreparer::prepareNotes( sal_uInt32 aSlideNumber
)
206 if ( !xController
->isRunning() )
209 uno::Reference
<css::drawing::XDrawPage
> aNotesPage
;
210 uno::Reference
< drawing::XDrawPage
> xSourceDoc(
211 xController
->getSlideByIndex( aSlideNumber
),
212 uno::UNO_SET_THROW
);
213 uno::Reference
<presentation::XPresentationPage
> xPresentationPage(
214 xSourceDoc
, UNO_QUERY
);
215 if (xPresentationPage
.is())
216 aNotesPage
= xPresentationPage
->getNotesPage();
220 static const OUString
sNotesShapeName (
221 "com.sun.star.presentation.NotesShape" );
222 static const OUString
sTextShapeName (
223 "com.sun.star.drawing.TextShape" );
225 uno::Reference
<container::XIndexAccess
> xIndexAccess ( aNotesPage
, UNO_QUERY
);
226 if (xIndexAccess
.is())
229 // Iterate over all shapes and find the one that holds the text.
230 sal_Int32
nCount (xIndexAccess
->getCount());
231 for (sal_Int32 nIndex
=0; nIndex
<nCount
; ++nIndex
)
234 uno::Reference
<lang::XServiceName
> xServiceName (
235 xIndexAccess
->getByIndex(nIndex
), UNO_QUERY
);
236 if (xServiceName
.is()
237 && xServiceName
->getServiceName() == sNotesShapeName
)
239 uno::Reference
<text::XTextRange
> xText (xServiceName
, UNO_QUERY
);
242 aRet
.append(xText
->getString());
243 aRet
.append("<br/>");
248 uno::Reference
<drawing::XShapeDescriptor
> xShapeDescriptor (
249 xIndexAccess
->getByIndex(nIndex
), UNO_QUERY
);
250 if (xShapeDescriptor
.is())
252 OUString
sType (xShapeDescriptor
->getShapeType());
253 if (sType
== sNotesShapeName
|| sType
== sTextShapeName
)
255 uno::Reference
<text::XTextRange
> xText (
256 xIndexAccess
->getByIndex(nIndex
), UNO_QUERY
);
259 aRet
.append(xText
->getString());
260 aRet
.append("<br/>");
267 // Replace all newlines with <br\> tags
268 for ( sal_Int32 i
= 0; i
< aRet
.getLength(); i
++ )
270 if ( aRet
[i
] == '\n' )
273 aRet
.insert( i
+1, "br/>" );
276 return OUStringToOString(
277 aRet
.makeStringAndClear(), RTL_TEXTENCODING_UTF8
);
280 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */