merge the formfield patch from ooo-build
[ooovba.git] / oox / source / ppt / presentationfragmenthandler.cxx
blobfd7b466907d07c25549fe2959cc9dcc9e7794224
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: presentationfragmenthandler.cxx,v $
10 * $Revision: 1.5.14.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "comphelper/anytostring.hxx"
32 #include "cppuhelper/exc_hlp.hxx"
34 #include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
35 #include <com/sun/star/drawing/XDrawPages.hpp>
36 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
37 #include <com/sun/star/drawing/XMasterPageTarget.hpp>
38 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
39 #include <com/sun/star/style/XStyle.hpp>
40 #include <com/sun/star/presentation/XPresentationPage.hpp>
41 #include <com/sun/star/task/XStatusIndicator.hpp>
43 #include "oox/drawingml/theme.hxx"
44 #include "oox/drawingml/drawingmltypes.hxx"
45 #include "oox/drawingml/themefragmenthandler.hxx"
46 #include "oox/drawingml/textliststylecontext.hxx"
47 #include "oox/ppt/pptshape.hxx"
48 #include "oox/ppt/presentationfragmenthandler.hxx"
49 #include "oox/ppt/slidefragmenthandler.hxx"
50 #include "oox/ppt/layoutfragmenthandler.hxx"
51 #include "oox/ppt/pptimport.hxx"
52 #include "oox/core/namespaces.hxx"
53 #include "tokens.hxx"
55 using rtl::OUString;
56 using namespace ::com::sun::star;
57 using namespace ::oox::core;
58 using namespace ::oox::drawingml;
59 using namespace ::com::sun::star::uno;
60 using namespace ::com::sun::star::beans;
61 using namespace ::com::sun::star::drawing;
62 using namespace ::com::sun::star::presentation;
63 using namespace ::com::sun::star::xml::sax;
65 namespace oox { namespace ppt {
67 PresentationFragmentHandler::PresentationFragmentHandler( XmlFilterBase& rFilter, const OUString& rFragmentPath ) throw()
68 : FragmentHandler( rFilter, rFragmentPath )
69 , mpTextListStyle( new TextListStyle )
71 TextParagraphPropertiesVector& rParagraphDefaulsVector( mpTextListStyle->getListStyle() );
72 TextParagraphPropertiesVector::iterator aParagraphDefaultIter( rParagraphDefaulsVector.begin() );
73 while( aParagraphDefaultIter != rParagraphDefaulsVector.end() )
75 // ppt is having zero bottom margin per default, whereas OOo is 0,5cm,
76 // so this attribute needs to be set always
77 (*aParagraphDefaultIter++)->getParaBottomMargin() = TextSpacing( 0 );
81 PresentationFragmentHandler::~PresentationFragmentHandler() throw()
85 void PresentationFragmentHandler::startDocument() throw (SAXException, RuntimeException)
89 void ResolveTextFields( XmlFilterBase& rFilter )
91 const oox::core::TextFieldStack& rTextFields = rFilter.getTextFieldStack();
92 if ( rTextFields.size() )
94 Reference< frame::XModel > xModel( rFilter.getModel() );
95 oox::core::TextFieldStack::const_iterator aIter( rTextFields.begin() );
96 while( aIter != rTextFields.end() )
98 const OUString sURL = CREATE_OUSTRING( "URL" );
99 Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW );
100 Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_QUERY_THROW );
102 const oox::core::TextField& rTextField( *aIter++ );
103 Reference< XPropertySet > xPropSet( rTextField.xTextField, UNO_QUERY );
104 Reference< XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
105 if ( xPropSetInfo->hasPropertyByName( sURL ) )
107 rtl::OUString aURL;
108 if ( xPropSet->getPropertyValue( sURL ) >>= aURL )
110 const OUString sSlide = CREATE_OUSTRING( "#Slide " );
111 const OUString sNotes = CREATE_OUSTRING( "#Notes " );
112 sal_Bool bNotes = sal_False;
113 sal_Int32 nPageNumber = 0;
114 if ( aURL.match( sSlide ) )
115 nPageNumber = aURL.copy( sSlide.getLength() ).toInt32();
116 else if ( aURL.match( sNotes ) )
118 nPageNumber = aURL.copy( sNotes.getLength() ).toInt32();
119 bNotes = sal_True;
121 if ( nPageNumber )
125 Reference< XDrawPage > xDrawPage;
126 xDrawPages->getByIndex( nPageNumber - 1 ) >>= xDrawPage;
127 if ( bNotes )
129 Reference< ::com::sun::star::presentation::XPresentationPage > xPresentationPage( xDrawPage, UNO_QUERY_THROW );
130 xDrawPage = xPresentationPage->getNotesPage();
132 Reference< container::XNamed > xNamed( xDrawPage, UNO_QUERY_THROW );
133 aURL = CREATE_OUSTRING( "#" ).concat( xNamed->getName() );
134 xPropSet->setPropertyValue( sURL, Any( aURL ) );
135 Reference< text::XTextContent > xContent( rTextField.xTextField, UNO_QUERY);
136 Reference< text::XTextRange > xTextRange( rTextField.xTextCursor, UNO_QUERY );
137 rTextField.xText->insertTextContent( xTextRange, xContent, sal_True );
139 catch( uno::Exception& )
149 void PresentationFragmentHandler::endDocument() throw (SAXException, RuntimeException)
151 // todo: localized progress bar text
152 const Reference< task::XStatusIndicator >& rxStatusIndicator( getFilter().getStatusIndicator() );
153 if ( rxStatusIndicator.is() )
154 rxStatusIndicator->start( rtl::OUString(), 10000 );
158 PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );
160 Reference< frame::XModel > xModel( rFilter.getModel() );
161 Reference< drawing::XDrawPage > xSlide;
162 sal_uInt32 nSlide;
164 // importing slide pages and its corresponding notes page
165 Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW );
166 Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_QUERY_THROW );
168 for( nSlide = 0; nSlide < maSlidesVector.size(); nSlide++ )
170 if ( rxStatusIndicator.is() )
171 rxStatusIndicator->setValue( ( nSlide * 10000 ) / maSlidesVector.size() );
173 if( nSlide == 0 )
174 xDrawPages->getByIndex( 0 ) >>= xSlide;
175 else
176 xSlide = xDrawPages->insertNewByIndex( nSlide );
178 OUString aSlideFragmentPath = getFragmentPathFromRelId( maSlidesVector[ nSlide ] );
179 if( aSlideFragmentPath.getLength() > 0 )
181 SlidePersistPtr pMasterPersistPtr;
182 SlidePersistPtr pSlidePersistPtr( new SlidePersist( rFilter, sal_False, sal_False, xSlide,
183 ShapePtr( new PPTShape( Slide, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) );
185 FragmentHandlerRef xSlideFragmentHandler( new SlideFragmentHandler( rFilter, aSlideFragmentPath, pSlidePersistPtr, Slide ) );
187 // importing the corresponding masterpage/layout
188 OUString aLayoutFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATIONSTYPE( "slideLayout" ) );
189 if ( aLayoutFragmentPath.getLength() > 0 )
191 // importing layout
192 RelationsRef xLayoutRelations = rFilter.importRelations( aLayoutFragmentPath );
193 OUString aMasterFragmentPath = xLayoutRelations->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATIONSTYPE( "slideMaster" ) );
194 if( aMasterFragmentPath.getLength() )
196 // check if the corresponding masterpage+layout has already been imported
197 std::vector< SlidePersistPtr >& rMasterPages( rFilter.getMasterPages() );
198 std::vector< SlidePersistPtr >::iterator aIter( rMasterPages.begin() );
199 while( aIter != rMasterPages.end() )
201 if ( ( (*aIter)->getPath() == aMasterFragmentPath ) && ( (*aIter)->getLayoutPath() == aLayoutFragmentPath ) )
203 pMasterPersistPtr = *aIter;
204 break;
206 aIter++;
208 if ( aIter == rMasterPages.end() )
209 { // masterpersist not found, we have to load it
210 Reference< drawing::XDrawPage > xMasterPage;
211 Reference< drawing::XMasterPagesSupplier > xMPS( xModel, uno::UNO_QUERY_THROW );
212 Reference< drawing::XDrawPages > xMasterPages( xMPS->getMasterPages(), uno::UNO_QUERY_THROW );
214 if( !(rFilter.getMasterPages().size() ))
215 xMasterPages->getByIndex( 0 ) >>= xMasterPage;
216 else
217 xMasterPage = xMasterPages->insertNewByIndex( xMasterPages->getCount() );
219 pMasterPersistPtr = SlidePersistPtr( new SlidePersist( rFilter, sal_True, sal_False, xMasterPage,
220 ShapePtr( new PPTShape( Master, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) );
221 pMasterPersistPtr->setLayoutPath( aLayoutFragmentPath );
222 rFilter.getMasterPages().push_back( pMasterPersistPtr );
223 rFilter.setActualSlidePersist( pMasterPersistPtr );
224 FragmentHandlerRef xMasterFragmentHandler( new SlideFragmentHandler( rFilter, aMasterFragmentPath, pMasterPersistPtr, Master ) );
226 // set the correct theme
227 OUString aThemeFragmentPath = xMasterFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATIONSTYPE( "theme" ) );
228 if( aThemeFragmentPath.getLength() > 0 )
230 std::map< OUString, oox::drawingml::ThemePtr >& rThemes( rFilter.getThemes() );
231 std::map< OUString, oox::drawingml::ThemePtr >::iterator aIter2( rThemes.find( aThemeFragmentPath ) );
232 if( aIter2 == rThemes.end() )
234 oox::drawingml::ThemePtr pThemePtr( new oox::drawingml::Theme() );
235 pMasterPersistPtr->setTheme( pThemePtr );
236 rFilter.importFragment( new ThemeFragmentHandler( rFilter, aThemeFragmentPath, *pThemePtr ) );
237 rThemes[ aThemeFragmentPath ] = pThemePtr;
239 else
241 pMasterPersistPtr->setTheme( (*aIter2).second );
244 importSlide( xMasterFragmentHandler, pMasterPersistPtr );
245 rFilter.importFragment( new LayoutFragmentHandler( rFilter, aLayoutFragmentPath, pMasterPersistPtr ) );
246 pMasterPersistPtr->createBackground( rFilter );
247 pMasterPersistPtr->createXShapes( rFilter );
252 // importing slide page
253 pSlidePersistPtr->setMasterPersist( pMasterPersistPtr );
254 pSlidePersistPtr->setTheme( pMasterPersistPtr->getTheme() );
255 Reference< drawing::XMasterPageTarget > xMasterPageTarget( pSlidePersistPtr->getPage(), UNO_QUERY );
256 if( xMasterPageTarget.is() )
257 xMasterPageTarget->setMasterPage( pMasterPersistPtr->getPage() );
258 rFilter.getDrawPages().push_back( pSlidePersistPtr );
259 rFilter.setActualSlidePersist( pSlidePersistPtr );
260 importSlide( xSlideFragmentHandler, pSlidePersistPtr );
261 pSlidePersistPtr->createBackground( rFilter );
262 pSlidePersistPtr->createXShapes( rFilter );
264 // now importing the notes page
265 OUString aNotesFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATIONSTYPE( "notesSlide" ) );
266 if( aNotesFragmentPath.getLength() > 0 )
268 Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
269 if ( xPresentationPage.is() )
271 Reference< XDrawPage > xNotesPage( xPresentationPage->getNotesPage() );
272 if ( xNotesPage.is() )
274 SlidePersistPtr pNotesPersistPtr( new SlidePersist( rFilter, sal_False, sal_True, xNotesPage,
275 ShapePtr( new PPTShape( Slide, "com.sun.star.drawing.GroupShape" ) ), mpTextListStyle ) );
276 FragmentHandlerRef xNotesFragmentHandler( new SlideFragmentHandler( getFilter(), aNotesFragmentPath, pNotesPersistPtr, Slide ) );
277 rFilter.getNotesPages().push_back( pNotesPersistPtr );
278 rFilter.setActualSlidePersist( pNotesPersistPtr );
279 importSlide( xNotesFragmentHandler, pNotesPersistPtr );
280 pNotesPersistPtr->createBackground( rFilter );
281 pNotesPersistPtr->createXShapes( rFilter );
287 ResolveTextFields( rFilter );
289 catch( uno::Exception& )
291 OSL_ENSURE( false,
292 (rtl::OString("oox::ppt::PresentationFragmentHandler::EndDocument(), "
293 "exception caught: ") +
294 rtl::OUStringToOString(
295 comphelper::anyToString( cppu::getCaughtException() ),
296 RTL_TEXTENCODING_UTF8 )).getStr() );
300 // todo error handling;
301 if ( rxStatusIndicator.is() )
302 rxStatusIndicator->end();
305 // CT_Presentation
306 Reference< XFastContextHandler > PresentationFragmentHandler::createFastChildContext( sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
308 Reference< XFastContextHandler > xRet;
309 switch( aElementToken )
311 case NMSP_PPT|XML_presentation:
312 case NMSP_PPT|XML_sldMasterIdLst:
313 case NMSP_PPT|XML_notesMasterIdLst:
314 case NMSP_PPT|XML_sldIdLst:
315 break;
316 case NMSP_PPT|XML_sldMasterId:
317 maSlideMasterVector.push_back( xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_id ) );
318 break;
319 case NMSP_PPT|XML_sldId:
320 maSlidesVector.push_back( xAttribs->getOptionalValue( NMSP_RELATIONSHIPS|XML_id ) );
321 break;
322 case NMSP_PPT|XML_notesMasterId:
323 maNotesMasterVector.push_back( xAttribs->getOptionalValue(NMSP_RELATIONSHIPS|XML_id ) );
324 break;
325 case NMSP_PPT|XML_sldSz:
326 maSlideSize = GetSize2D( xAttribs );
327 break;
328 case NMSP_PPT|XML_notesSz:
329 maNotesSize = GetSize2D( xAttribs );
330 break;
331 case NMSP_PPT|XML_custShowLst:
332 xRet.set( new CustomShowListContext( *this, maCustomShowList ) );
333 break;
334 case NMSP_PPT|XML_defaultTextStyle:
335 xRet.set( new TextListStyleContext( *this, *mpTextListStyle ) );
336 break;
338 if ( !xRet.is() )
339 xRet = getFastContextHandler();
340 return xRet;
343 bool PresentationFragmentHandler::importSlide( const FragmentHandlerRef& rxSlideFragmentHandler,
344 const SlidePersistPtr pSlidePersistPtr )
346 Reference< drawing::XDrawPage > xSlide( pSlidePersistPtr->getPage() );
347 SlidePersistPtr pMasterPersistPtr( pSlidePersistPtr->getMasterPersist() );
348 if ( pMasterPersistPtr.get() )
350 const OUString sLayout = CREATE_OUSTRING( "Layout" );
351 uno::Reference< beans::XPropertySet > xSet( xSlide, uno::UNO_QUERY_THROW );
352 xSet->setPropertyValue( sLayout, Any( pMasterPersistPtr->getLayoutFromValueToken() ) );
354 while( xSlide->getCount() )
356 Reference< drawing::XShape > xShape;
357 xSlide->getByIndex(0) >>= xShape;
358 xSlide->remove( xShape );
361 Reference< XPropertySet > xPropertySet( xSlide, UNO_QUERY );
362 if ( xPropertySet.is() )
364 static const OUString sWidth = CREATE_OUSTRING( "Width" );
365 static const OUString sHeight = CREATE_OUSTRING( "Height" );
366 awt::Size& rPageSize( pSlidePersistPtr->isNotesPage() ? maNotesSize : maSlideSize );
367 xPropertySet->setPropertyValue( sWidth, Any( rPageSize.Width ) );
368 xPropertySet->setPropertyValue( sHeight, Any( rPageSize.Height ) );
370 oox::ppt::HeaderFooter aHeaderFooter( pSlidePersistPtr->getHeaderFooter() );
371 if ( !pSlidePersistPtr->isMasterPage() )
372 aHeaderFooter.mbSlideNumber = aHeaderFooter.mbHeader = aHeaderFooter.mbFooter = aHeaderFooter.mbDateTime = sal_False;
375 static const OUString sIsHeaderVisible = CREATE_OUSTRING( "IsHeaderVisible" );
376 static const OUString sIsFooterVisible = CREATE_OUSTRING( "IsFooterVisible" );
377 static const OUString sIsDateTimeVisible = CREATE_OUSTRING( "IsDateTimeVisible" );
378 static const OUString sIsPageNumberVisible = CREATE_OUSTRING( "IsPageNumberVisible" );
380 if ( pSlidePersistPtr->isNotesPage() )
381 xPropertySet->setPropertyValue( sIsHeaderVisible, Any( aHeaderFooter.mbHeader ) );
382 xPropertySet->setPropertyValue( sIsFooterVisible, Any( aHeaderFooter.mbFooter ) );
383 xPropertySet->setPropertyValue( sIsDateTimeVisible, Any( aHeaderFooter.mbDateTime ) );
384 xPropertySet->setPropertyValue( sIsPageNumberVisible, Any( aHeaderFooter.mbSlideNumber ) );
386 catch( uno::Exception& )
390 pSlidePersistPtr->setPath( rxSlideFragmentHandler->getFragmentPath() );
391 return getFilter().importFragment( rxSlideFragmentHandler );