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 <comphelper/propertyvalue.hxx>
26 #include <osl/file.hxx>
27 #include <rtl/ustrbuf.hxx>
28 #include <sal/log.hxx>
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>
39 using namespace ::osl
;
40 using namespace ::com::sun::star
;
41 using namespace ::com::sun::star::uno
;
43 ImagePreparer::ImagePreparer(
44 uno::Reference
<presentation::XSlideShowController
> _xController
,
45 Transmitter
*aTransmitter
)
46 : Timer("sd ImagePreparer"),
47 xController(std::move( _xController
)),
48 pTransmitter( aTransmitter
)
50 SAL_INFO( "sdremote", "ImagePreparer - start" );
56 ImagePreparer::~ImagePreparer()
58 SAL_INFO( "sdremote", "ImagePreparer - stop" );
62 void ImagePreparer::Invoke()
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
)
70 sendPreview( mnSendingSlide
);
71 sendNotes( mnSendingSlide
);
79 void ImagePreparer::sendPreview( sal_uInt32 aSlideNumber
)
82 uno::Sequence
<sal_Int8
> aImageData
= preparePreview( aSlideNumber
, 320, 240,
84 if ( !xController
->isRunning() )
87 OUStringBuffer aStrBuffer
;
88 ::comphelper::Base64::encode( aStrBuffer
, aImageData
);
90 OString aEncodedShortString
= OUStringToOString(
91 aStrBuffer
, RTL_TEXTENCODING_UTF8
);
94 OString aBuffer
= "slide_preview\n" +
95 OString::number(aSlideNumber
) +
96 "\n" + aEncodedShortString
+ "\n\n";
97 pTransmitter
->addMessage( aBuffer
,
98 Transmitter::PRIORITY_LOW
);
102 uno::Sequence
<sal_Int8
> ImagePreparer::preparePreview(
103 sal_uInt32 aSlideNumber
, sal_uInt32 aWidth
, sal_uInt32 aHeight
,
107 FileBase::createTempFile( nullptr, nullptr, &aFileURL
);
109 uno::Reference
< drawing::XGraphicExportFilter
> xFilter
=
110 drawing::GraphicExportFilter::create( ::comphelper::getProcessComponentContext() );
112 if ( !xController
->isRunning() )
113 return uno::Sequence
<sal_Int8
>();
115 uno::Reference
< lang::XComponent
> xSourceDoc(
116 xController
->getSlideByIndex( aSlideNumber
),
117 uno::UNO_QUERY_THROW
);
119 xFilter
->setSourceDocument( xSourceDoc
);
121 uno::Sequence
< beans::PropertyValue
> aFilterData
{
122 comphelper::makePropertyValue(u
"PixelWidth"_ustr
, aWidth
),
123 comphelper::makePropertyValue(u
"PixelHeight"_ustr
, aHeight
),
124 comphelper::makePropertyValue(u
"ColorMode"_ustr
, sal_Int32(0)) // 0: Color, 1: B&W
127 uno::Sequence
< beans::PropertyValue
> aProps
{
128 comphelper::makePropertyValue(u
"MediaType"_ustr
, u
"image/png"_ustr
),
129 comphelper::makePropertyValue(u
"URL"_ustr
, aFileURL
),
130 comphelper::makePropertyValue(u
"FilterData"_ustr
, aFilterData
)
133 xFilter
->filter( aProps
);
135 File
aFile(aFileURL
);
136 if (aFile
.open(0) != osl::File::E_None
)
137 return uno::Sequence
<sal_Int8
>();
141 aFile
.getSize( rSize
);
142 uno::Sequence
<sal_Int8
> aContents( rSize
);
144 aFile
.read( aContents
.getArray(), rSize
, aRead
);
146 aContents
.realloc(aRead
);
149 File::remove( aFileURL
);
154 void ImagePreparer::sendNotes( sal_uInt32 aSlideNumber
)
157 OString aNotes
= prepareNotes( aSlideNumber
);
159 if ( aNotes
.isEmpty() )
162 if ( !xController
->isRunning() )
168 OString::number( static_cast<sal_Int32
>(aSlideNumber
) ) +
174 pTransmitter
->addMessage( aBuffer
,
175 Transmitter::PRIORITY_LOW
);
178 // Code copied from sdremote/source/presenter/PresenterNotesView.cxx
179 OString
ImagePreparer::prepareNotes( sal_uInt32 aSlideNumber
)
183 if ( !xController
->isRunning() )
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();
197 static constexpr OUString
sNotesShapeName (
198 u
"com.sun.star.presentation.NotesShape"_ustr
);
199 static constexpr OUStringLiteral
sTextShapeName (
200 u
"com.sun.star.drawing.TextShape" );
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
)
210 uno::Reference
<lang::XServiceName
> xServiceName (
211 aNotesPage
->getByIndex(nIndex
), UNO_QUERY
);
212 if (xServiceName
.is()
213 && xServiceName
->getServiceName() == sNotesShapeName
)
215 uno::Reference
<text::XTextRange
> xText (xServiceName
, UNO_QUERY
);
218 aRet
.append(xText
->getString() + "<br/>");
223 uno::Reference
<drawing::XShapeDescriptor
> xShapeDescriptor (
224 aNotesPage
->getByIndex(nIndex
), UNO_QUERY
);
225 if (xShapeDescriptor
.is())
227 OUString
sType (xShapeDescriptor
->getShapeType());
228 if (sType
== sNotesShapeName
|| sType
== sTextShapeName
)
230 uno::Reference
<text::XTextRange
> xText (
231 aNotesPage
->getByIndex(nIndex
), UNO_QUERY
);
234 aRet
.append(xText
->getString() + "<br/>");
241 // Replace all newlines with <br\> tags
242 for ( sal_Int32 i
= 0; i
< aRet
.getLength(); i
++ )
244 if ( aRet
[i
] == '\n' )
247 aRet
.insert( i
+1, "br/>" );
250 return OUStringToOString( aRet
, RTL_TEXTENCODING_UTF8
);
253 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */