Line data Source code
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 "comphelper/anytostring.hxx"
21 : #include "cppuhelper/exc_hlp.hxx"
22 :
23 : #include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
24 : #include <com/sun/star/drawing/XDrawPages.hpp>
25 : #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
26 : #include <com/sun/star/drawing/XMasterPageTarget.hpp>
27 : #include <com/sun/star/xml/dom/XDocument.hpp>
28 : #include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
29 : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
30 : #include <com/sun/star/style/XStyle.hpp>
31 : #include <com/sun/star/presentation/XPresentationPage.hpp>
32 : #include <com/sun/star/task/XStatusIndicator.hpp>
33 :
34 : #include "oox/drawingml/theme.hxx"
35 : #include "oox/drawingml/drawingmltypes.hxx"
36 : #include "oox/drawingml/themefragmenthandler.hxx"
37 : #include "oox/drawingml/textliststylecontext.hxx"
38 : #include "oox/ppt/pptshape.hxx"
39 : #include "oox/ppt/presentationfragmenthandler.hxx"
40 : #include "oox/ppt/slidefragmenthandler.hxx"
41 : #include "oox/ppt/layoutfragmenthandler.hxx"
42 : #include "oox/ppt/pptimport.hxx"
43 :
44 : using rtl::OUString;
45 : using namespace ::com::sun::star;
46 : using namespace ::oox::core;
47 : using namespace ::oox::drawingml;
48 : using namespace ::com::sun::star::uno;
49 : using namespace ::com::sun::star::beans;
50 : using namespace ::com::sun::star::drawing;
51 : using namespace ::com::sun::star::presentation;
52 : using namespace ::com::sun::star::xml::sax;
53 :
54 : namespace oox { namespace ppt {
55 :
56 4 : PresentationFragmentHandler::PresentationFragmentHandler( XmlFilterBase& rFilter, const OUString& rFragmentPath ) throw()
57 : : FragmentHandler2( rFilter, rFragmentPath )
58 4 : , mpTextListStyle( new TextListStyle )
59 : {
60 4 : TextParagraphPropertiesVector& rParagraphDefaulsVector( mpTextListStyle->getListStyle() );
61 4 : TextParagraphPropertiesVector::iterator aParagraphDefaultIter( rParagraphDefaulsVector.begin() );
62 44 : while( aParagraphDefaultIter != rParagraphDefaulsVector.end() )
63 : {
64 : // ppt is having zero bottom margin per default, whereas OOo is 0,5cm,
65 : // so this attribute needs to be set always
66 36 : (*aParagraphDefaultIter++)->getParaBottomMargin() = TextSpacing( 0 );
67 : }
68 4 : }
69 :
70 8 : PresentationFragmentHandler::~PresentationFragmentHandler() throw()
71 : {
72 8 : }
73 :
74 4 : void ResolveTextFields( XmlFilterBase& rFilter )
75 : {
76 4 : const oox::core::TextFieldStack& rTextFields = rFilter.getTextFieldStack();
77 4 : if ( rTextFields.size() )
78 : {
79 0 : Reference< frame::XModel > xModel( rFilter.getModel() );
80 0 : oox::core::TextFieldStack::const_iterator aIter( rTextFields.begin() );
81 0 : while( aIter != rTextFields.end() )
82 : {
83 0 : const OUString sURL = CREATE_OUSTRING( "URL" );
84 0 : Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW );
85 0 : Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_QUERY_THROW );
86 :
87 0 : const oox::core::TextField& rTextField( *aIter++ );
88 0 : Reference< XPropertySet > xPropSet( rTextField.xTextField, UNO_QUERY );
89 0 : Reference< XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
90 0 : if ( xPropSetInfo->hasPropertyByName( sURL ) )
91 : {
92 0 : rtl::OUString aURL;
93 0 : if ( xPropSet->getPropertyValue( sURL ) >>= aURL )
94 : {
95 0 : const OUString sSlide = CREATE_OUSTRING( "#Slide " );
96 0 : const OUString sNotes = CREATE_OUSTRING( "#Notes " );
97 0 : sal_Bool bNotes = sal_False;
98 0 : sal_Int32 nPageNumber = 0;
99 0 : if ( aURL.match( sSlide ) )
100 0 : nPageNumber = aURL.copy( sSlide.getLength() ).toInt32();
101 0 : else if ( aURL.match( sNotes ) )
102 : {
103 0 : nPageNumber = aURL.copy( sNotes.getLength() ).toInt32();
104 0 : bNotes = sal_True;
105 : }
106 0 : if ( nPageNumber )
107 : {
108 : try
109 : {
110 0 : Reference< XDrawPage > xDrawPage;
111 0 : xDrawPages->getByIndex( nPageNumber - 1 ) >>= xDrawPage;
112 0 : if ( bNotes )
113 : {
114 0 : Reference< ::com::sun::star::presentation::XPresentationPage > xPresentationPage( xDrawPage, UNO_QUERY_THROW );
115 0 : xDrawPage = xPresentationPage->getNotesPage();
116 : }
117 0 : Reference< container::XNamed > xNamed( xDrawPage, UNO_QUERY_THROW );
118 0 : aURL = CREATE_OUSTRING( "#" ).concat( xNamed->getName() );
119 0 : xPropSet->setPropertyValue( sURL, Any( aURL ) );
120 0 : Reference< text::XTextContent > xContent( rTextField.xTextField, UNO_QUERY);
121 0 : Reference< text::XTextRange > xTextRange( rTextField.xTextCursor, UNO_QUERY );
122 0 : rTextField.xText->insertTextContent( xTextRange, xContent, sal_True );
123 : }
124 0 : catch( uno::Exception& )
125 : {
126 : }
127 0 : }
128 0 : }
129 : }
130 0 : }
131 : }
132 4 : }
133 :
134 4 : void PresentationFragmentHandler::finalizeImport()
135 : {
136 : // todo: localized progress bar text
137 4 : const Reference< task::XStatusIndicator >& rxStatusIndicator( getFilter().getStatusIndicator() );
138 4 : if ( rxStatusIndicator.is() )
139 0 : rxStatusIndicator->start( rtl::OUString(), 10000 );
140 :
141 : try
142 : {
143 4 : PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );
144 :
145 8 : Reference< frame::XModel > xModel( rFilter.getModel() );
146 4 : Reference< drawing::XDrawPage > xSlide;
147 : sal_uInt32 nSlide;
148 :
149 : // importing slide pages and its corresponding notes page
150 4 : Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW );
151 4 : Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_QUERY_THROW );
152 :
153 8 : for( nSlide = 0; nSlide < maSlidesVector.size(); nSlide++ )
154 : {
155 4 : if ( rxStatusIndicator.is() )
156 0 : rxStatusIndicator->setValue( ( nSlide * 10000 ) / maSlidesVector.size() );
157 :
158 4 : if( nSlide == 0 )
159 4 : xDrawPages->getByIndex( 0 ) >>= xSlide;
160 : else
161 0 : xSlide = xDrawPages->insertNewByIndex( nSlide );
162 :
163 4 : OUString aSlideFragmentPath = getFragmentPathFromRelId( maSlidesVector[ nSlide ] );
164 4 : if( !aSlideFragmentPath.isEmpty() )
165 : {
166 4 : rtl::OUString aMasterFragmentPath;
167 4 : SlidePersistPtr pMasterPersistPtr;
168 : SlidePersistPtr pSlidePersistPtr( new SlidePersist( rFilter, sal_False, sal_False, xSlide,
169 4 : ShapePtr( new PPTShape( Slide, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) );
170 :
171 4 : FragmentHandlerRef xSlideFragmentHandler( new SlideFragmentHandler( rFilter, aSlideFragmentPath, pSlidePersistPtr, Slide ) );
172 :
173 : // importing the corresponding masterpage/layout
174 4 : OUString aLayoutFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "slideLayout" ) );
175 4 : if ( !aLayoutFragmentPath.isEmpty() )
176 : {
177 : // importing layout
178 4 : RelationsRef xLayoutRelations = rFilter.importRelations( aLayoutFragmentPath );
179 4 : aMasterFragmentPath = xLayoutRelations->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "slideMaster" ) );
180 4 : if( !aMasterFragmentPath.isEmpty() )
181 : {
182 : // check if the corresponding masterpage+layout has already been imported
183 4 : std::vector< SlidePersistPtr >& rMasterPages( rFilter.getMasterPages() );
184 4 : std::vector< SlidePersistPtr >::iterator aIter( rMasterPages.begin() );
185 8 : while( aIter != rMasterPages.end() )
186 : {
187 0 : if ( ( (*aIter)->getPath() == aMasterFragmentPath ) && ( (*aIter)->getLayoutPath() == aLayoutFragmentPath ) )
188 : {
189 0 : pMasterPersistPtr = *aIter;
190 0 : break;
191 : }
192 0 : ++aIter;
193 : }
194 :
195 4 : if ( !pMasterPersistPtr.get() )
196 : { // masterpersist not found, we have to load it
197 4 : Reference< drawing::XDrawPage > xMasterPage;
198 4 : Reference< drawing::XMasterPagesSupplier > xMPS( xModel, uno::UNO_QUERY_THROW );
199 4 : Reference< drawing::XDrawPages > xMasterPages( xMPS->getMasterPages(), uno::UNO_QUERY_THROW );
200 :
201 4 : if( !(rFilter.getMasterPages().size() ))
202 4 : xMasterPages->getByIndex( 0 ) >>= xMasterPage;
203 : else
204 0 : xMasterPage = xMasterPages->insertNewByIndex( xMasterPages->getCount() );
205 :
206 : pMasterPersistPtr = SlidePersistPtr( new SlidePersist( rFilter, sal_True, sal_False, xMasterPage,
207 4 : ShapePtr( new PPTShape( Master, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) );
208 4 : pMasterPersistPtr->setLayoutPath( aLayoutFragmentPath );
209 4 : rFilter.getMasterPages().push_back( pMasterPersistPtr );
210 4 : rFilter.setActualSlidePersist( pMasterPersistPtr );
211 4 : FragmentHandlerRef xMasterFragmentHandler( new SlideFragmentHandler( rFilter, aMasterFragmentPath, pMasterPersistPtr, Master ) );
212 :
213 : // set the correct theme
214 4 : OUString aThemeFragmentPath = xMasterFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "theme" ) );
215 4 : if( !aThemeFragmentPath.isEmpty() )
216 : {
217 4 : std::map< OUString, oox::drawingml::ThemePtr >& rThemes( rFilter.getThemes() );
218 4 : std::map< OUString, oox::drawingml::ThemePtr >::iterator aIter2( rThemes.find( aThemeFragmentPath ) );
219 4 : if( aIter2 == rThemes.end() )
220 : {
221 4 : oox::drawingml::ThemePtr pThemePtr( new oox::drawingml::Theme() );
222 4 : pMasterPersistPtr->setTheme( pThemePtr );
223 : Reference<xml::dom::XDocument> xDoc=
224 4 : rFilter.importFragment(aThemeFragmentPath);
225 :
226 : rFilter.importFragment(
227 : new ThemeFragmentHandler(
228 4 : rFilter, aThemeFragmentPath, *pThemePtr ),
229 : Reference<xml::sax::XFastSAXSerializable>(
230 : xDoc,
231 8 : UNO_QUERY_THROW));
232 4 : rThemes[ aThemeFragmentPath ] = pThemePtr;
233 4 : pThemePtr->setFragment(xDoc);
234 : }
235 : else
236 : {
237 0 : pMasterPersistPtr->setTheme( (*aIter2).second );
238 : }
239 : }
240 4 : importSlide( xMasterFragmentHandler, pMasterPersistPtr );
241 4 : rFilter.importFragment( new LayoutFragmentHandler( rFilter, aLayoutFragmentPath, pMasterPersistPtr ) );
242 4 : pMasterPersistPtr->createBackground( rFilter );
243 4 : pMasterPersistPtr->createXShapes( rFilter );
244 : }
245 4 : }
246 : }
247 :
248 : // importing slide page
249 4 : if (pMasterPersistPtr.get()) {
250 4 : pSlidePersistPtr->setMasterPersist( pMasterPersistPtr );
251 4 : pSlidePersistPtr->setTheme( pMasterPersistPtr->getTheme() );
252 4 : Reference< drawing::XMasterPageTarget > xMasterPageTarget( pSlidePersistPtr->getPage(), UNO_QUERY );
253 4 : if( xMasterPageTarget.is() )
254 4 : xMasterPageTarget->setMasterPage( pMasterPersistPtr->getPage() );
255 : }
256 4 : rFilter.getDrawPages().push_back( pSlidePersistPtr );
257 4 : rFilter.setActualSlidePersist( pSlidePersistPtr );
258 4 : importSlide( xSlideFragmentHandler, pSlidePersistPtr );
259 4 : pSlidePersistPtr->createBackground( rFilter );
260 4 : pSlidePersistPtr->createXShapes( rFilter );
261 :
262 : // now importing the notes page
263 4 : OUString aNotesFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "notesSlide" ) );
264 4 : if( !aNotesFragmentPath.isEmpty() )
265 : {
266 1 : Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
267 1 : if ( xPresentationPage.is() )
268 : {
269 1 : Reference< XDrawPage > xNotesPage( xPresentationPage->getNotesPage() );
270 1 : if ( xNotesPage.is() )
271 : {
272 : SlidePersistPtr pNotesPersistPtr( new SlidePersist( rFilter, sal_False, sal_True, xNotesPage,
273 1 : ShapePtr( new PPTShape( Slide, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) );
274 1 : FragmentHandlerRef xNotesFragmentHandler( new SlideFragmentHandler( getFilter(), aNotesFragmentPath, pNotesPersistPtr, Slide ) );
275 1 : rFilter.getNotesPages().push_back( pNotesPersistPtr );
276 1 : rFilter.setActualSlidePersist( pNotesPersistPtr );
277 1 : importSlide( xNotesFragmentHandler, pNotesPersistPtr );
278 1 : pNotesPersistPtr->createBackground( rFilter );
279 1 : pNotesPersistPtr->createXShapes( rFilter );
280 1 : }
281 1 : }
282 4 : }
283 : }
284 4 : }
285 4 : ResolveTextFields( rFilter );
286 : }
287 0 : catch( uno::Exception& )
288 : {
289 : OSL_FAIL( OString(rtl::OString("oox::ppt::PresentationFragmentHandler::EndDocument(), "
290 : "exception caught: ") +
291 : rtl::OUStringToOString(
292 : comphelper::anyToString( cppu::getCaughtException() ),
293 : RTL_TEXTENCODING_UTF8 )).getStr() );
294 :
295 : }
296 :
297 : // todo error handling;
298 4 : if ( rxStatusIndicator.is() )
299 0 : rxStatusIndicator->end();
300 4 : }
301 :
302 : // CT_Presentation
303 37 : ::oox::core::ContextHandlerRef PresentationFragmentHandler::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
304 : {
305 37 : switch( aElementToken )
306 : {
307 : case PPT_TOKEN( presentation ):
308 : case PPT_TOKEN( sldMasterIdLst ):
309 : case PPT_TOKEN( notesMasterIdLst ):
310 : case PPT_TOKEN( sldIdLst ):
311 14 : return this;
312 : case PPT_TOKEN( sldMasterId ):
313 4 : maSlideMasterVector.push_back( rAttribs.getString( R_TOKEN( id ), OUString() ) );
314 4 : return this;
315 : case PPT_TOKEN( sldId ):
316 4 : maSlidesVector.push_back( rAttribs.getString( R_TOKEN( id ), OUString() ) );
317 4 : return this;
318 : case PPT_TOKEN( notesMasterId ):
319 2 : maNotesMasterVector.push_back( rAttribs.getString( R_TOKEN( id ), OUString() ) );
320 2 : return this;
321 : case PPT_TOKEN( sldSz ):
322 4 : maSlideSize = GetSize2D( rAttribs.getFastAttributeList() );
323 4 : return this;
324 : case PPT_TOKEN( notesSz ):
325 4 : maNotesSize = GetSize2D( rAttribs.getFastAttributeList() );
326 4 : return this;
327 : case PPT_TOKEN( custShowLst ):
328 0 : return new CustomShowListContext( *this, maCustomShowList );
329 : case PPT_TOKEN( defaultTextStyle ):
330 3 : return new TextListStyleContext( *this, *mpTextListStyle );
331 : }
332 2 : return this;
333 : }
334 :
335 9 : bool PresentationFragmentHandler::importSlide( const FragmentHandlerRef& rxSlideFragmentHandler,
336 : const SlidePersistPtr pSlidePersistPtr )
337 : {
338 9 : Reference< drawing::XDrawPage > xSlide( pSlidePersistPtr->getPage() );
339 9 : SlidePersistPtr pMasterPersistPtr( pSlidePersistPtr->getMasterPersist() );
340 9 : if ( pMasterPersistPtr.get() )
341 : {
342 4 : const OUString sLayout = CREATE_OUSTRING( "Layout" );
343 4 : uno::Reference< beans::XPropertySet > xSet( xSlide, uno::UNO_QUERY_THROW );
344 4 : xSet->setPropertyValue( sLayout, Any( pMasterPersistPtr->getLayoutFromValueToken() ) );
345 : }
346 46 : while( xSlide->getCount() )
347 : {
348 28 : Reference< drawing::XShape > xShape;
349 28 : xSlide->getByIndex(0) >>= xShape;
350 28 : xSlide->remove( xShape );
351 28 : }
352 :
353 9 : Reference< XPropertySet > xPropertySet( xSlide, UNO_QUERY );
354 9 : if ( xPropertySet.is() )
355 : {
356 9 : awt::Size& rPageSize( pSlidePersistPtr->isNotesPage() ? maNotesSize : maSlideSize );
357 9 : xPropertySet->setPropertyValue( "Width", Any( rPageSize.Width ) );
358 9 : xPropertySet->setPropertyValue( "Height", Any( rPageSize.Height ) );
359 :
360 9 : oox::ppt::HeaderFooter aHeaderFooter( pSlidePersistPtr->getHeaderFooter() );
361 9 : if ( !pSlidePersistPtr->isMasterPage() )
362 5 : aHeaderFooter.mbSlideNumber = aHeaderFooter.mbHeader = aHeaderFooter.mbFooter = aHeaderFooter.mbDateTime = sal_False;
363 : try
364 : {
365 9 : if ( pSlidePersistPtr->isNotesPage() )
366 2 : xPropertySet->setPropertyValue( "sIsHeaderVisible", Any( aHeaderFooter.mbHeader ) );
367 12 : xPropertySet->setPropertyValue( "IsFooterVisible", Any( aHeaderFooter.mbFooter ) );
368 4 : xPropertySet->setPropertyValue( "IsDateTimeVisible", Any( aHeaderFooter.mbDateTime ) );
369 4 : xPropertySet->setPropertyValue( "IsPageNumberVisible", Any( aHeaderFooter.mbSlideNumber ) );
370 : }
371 5 : catch( uno::Exception& )
372 : {
373 : }
374 : }
375 9 : pSlidePersistPtr->setPath( rxSlideFragmentHandler->getFragmentPath() );
376 9 : return getFilter().importFragment( rxSlideFragmentHandler );
377 : }
378 :
379 51 : } }
380 :
381 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|