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"
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
) )
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();
125 Reference
< XDrawPage
> xDrawPage
;
126 xDrawPages
->getByIndex( nPageNumber
- 1 ) >>= xDrawPage
;
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
;
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() );
174 xDrawPages
->getByIndex( 0 ) >>= xSlide
;
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 )
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
;
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
;
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
;
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
& )
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();
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
:
316 case NMSP_PPT
|XML_sldMasterId
:
317 maSlideMasterVector
.push_back( xAttribs
->getOptionalValue( NMSP_RELATIONSHIPS
|XML_id
) );
319 case NMSP_PPT
|XML_sldId
:
320 maSlidesVector
.push_back( xAttribs
->getOptionalValue( NMSP_RELATIONSHIPS
|XML_id
) );
322 case NMSP_PPT
|XML_notesMasterId
:
323 maNotesMasterVector
.push_back( xAttribs
->getOptionalValue(NMSP_RELATIONSHIPS
|XML_id
) );
325 case NMSP_PPT
|XML_sldSz
:
326 maSlideSize
= GetSize2D( xAttribs
);
328 case NMSP_PPT
|XML_notesSz
:
329 maNotesSize
= GetSize2D( xAttribs
);
331 case NMSP_PPT
|XML_custShowLst
:
332 xRet
.set( new CustomShowListContext( *this, maCustomShowList
) );
334 case NMSP_PPT
|XML_defaultTextStyle
:
335 xRet
.set( new TextListStyleContext( *this, *mpTextListStyle
) );
339 xRet
= getFastContextHandler();
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
);