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 <com/sun/star/geometry/RealPoint2D.hpp>
21 #include <com/sun/star/text/XTextCursor.hpp>
22 #include <com/sun/star/util/DateTime.hpp>
23 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
24 #include <cppuhelper/implbase1.hxx>
25 #include <sax/tools/converter.hxx>
26 #include "XMLNumberStylesImport.hxx"
27 #include <xmloff/xmlstyle.hxx>
28 #include <xmloff/xmltoken.hxx>
29 #include <xmloff/xmlnmspe.hxx>
30 #include "ximppage.hxx"
31 #include "ximpshap.hxx"
32 #include "animimp.hxx"
33 #include "XMLStringBufferImportContext.hxx"
34 #include <xmloff/xmlictxt.hxx>
35 #include "ximpstyl.hxx"
36 #include <xmloff/prstylei.hxx>
37 #include "PropertySetMerger.hxx"
38 #include <osl/diagnose.h>
40 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
41 #include <xmloff/xmluconv.hxx>
43 using namespace ::com::sun::star
;
44 using namespace ::xmloff::token
;
45 using namespace ::com::sun::star::uno
;
46 using namespace ::com::sun::star::lang
;
47 using namespace ::com::sun::star::text
;
48 using namespace ::com::sun::star::util
;
49 using namespace ::com::sun::star::beans
;
50 using namespace ::com::sun::star::drawing
;
51 using namespace ::com::sun::star::container
;
52 using namespace ::com::sun::star::office
;
53 using namespace ::com::sun::star::xml::sax
;
54 using namespace ::com::sun::star::geometry
;
56 class DrawAnnotationContext
: public SvXMLImportContext
60 DrawAnnotationContext( SvXMLImport
& rImport
, sal_uInt16 nPrfx
, const OUString
& rLocalName
,const Reference
< xml::sax::XAttributeList
>& xAttrList
, const Reference
< XAnnotationAccess
>& xAnnotationAccess
);
62 virtual SvXMLImportContext
* CreateChildContext( sal_uInt16 nPrefix
, const OUString
& rLocalName
, const com::sun::star::uno::Reference
< com::sun::star::xml::sax::XAttributeList
>& xAttrList
) SAL_OVERRIDE
;
63 virtual void EndElement() SAL_OVERRIDE
;
66 Reference
< XAnnotation
> mxAnnotation
;
67 Reference
< XTextCursor
> mxCursor
;
69 OUStringBuffer maAuthorBuffer
;
70 OUStringBuffer maDateBuffer
;
73 DrawAnnotationContext::DrawAnnotationContext( SvXMLImport
& rImport
, sal_uInt16 nPrfx
, const OUString
& rLocalName
,const Reference
< xml::sax::XAttributeList
>& xAttrList
, const Reference
< XAnnotationAccess
>& xAnnotationAccess
)
74 : SvXMLImportContext( rImport
, nPrfx
, rLocalName
)
75 , mxAnnotation( xAnnotationAccess
->createAndInsertAnnotation() )
77 if( mxAnnotation
.is() )
79 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
81 RealPoint2D aPosition
;
84 for(sal_Int16 i
=0; i
< nAttrCount
; i
++)
86 OUString
sValue( xAttrList
->getValueByIndex( i
) );
87 OUString
sAttrName( xAttrList
->getNameByIndex( i
) );
89 switch( GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName
, &aLocalName
) )
91 case XML_NAMESPACE_SVG
:
92 if( IsXMLToken( aLocalName
, XML_X
) )
95 GetImport().GetMM100UnitConverter().convertMeasureToCore(
97 aPosition
.X
= static_cast<double>(x
) / 100.0;
99 else if( IsXMLToken( aLocalName
, XML_Y
) )
102 GetImport().GetMM100UnitConverter().convertMeasureToCore(
104 aPosition
.Y
= static_cast<double>(y
) / 100.0;
106 else if( IsXMLToken( aLocalName
, XML_WIDTH
) )
109 GetImport().GetMM100UnitConverter().convertMeasureToCore(
111 aSize
.Width
= static_cast<double>(w
) / 100.0;
113 else if( IsXMLToken( aLocalName
, XML_HEIGHT
) )
116 GetImport().GetMM100UnitConverter().convertMeasureToCore(
118 aSize
.Height
= static_cast<double>(h
) / 100.0;
126 mxAnnotation
->setPosition( aPosition
);
127 mxAnnotation
->setSize( aSize
);
131 SvXMLImportContext
* DrawAnnotationContext::CreateChildContext( sal_uInt16 nPrefix
, const OUString
& rLocalName
, const Reference
< XAttributeList
>& xAttrList
)
133 SvXMLImportContext
* pContext
= NULL
;
135 if( mxAnnotation
.is() )
137 if( XML_NAMESPACE_DC
== nPrefix
)
139 if( IsXMLToken( rLocalName
, XML_CREATOR
) )
140 pContext
= new XMLStringBufferImportContext(GetImport(), nPrefix
, rLocalName
, maAuthorBuffer
);
141 else if( IsXMLToken( rLocalName
, XML_DATE
) )
142 pContext
= new XMLStringBufferImportContext(GetImport(), nPrefix
, rLocalName
, maDateBuffer
);
146 // create text cursor on demand
149 uno::Reference
< text::XText
> xText( mxAnnotation
->getTextRange() );
152 rtl::Reference
< XMLTextImportHelper
> xTxtImport
= GetImport().GetTextImport();
153 mxCursor
= xText
->createTextCursor();
155 xTxtImport
->SetCursor( mxCursor
);
159 // if we have a text cursor, lets try to import some text
162 pContext
= GetImport().GetTextImport()->CreateTextChildContext( GetImport(), nPrefix
, rLocalName
, xAttrList
);
167 // call parent for content
169 pContext
= SvXMLImportContext::CreateChildContext( nPrefix
, rLocalName
, xAttrList
);
174 void DrawAnnotationContext::EndElement()
178 // delete addition newline
179 const OUString aEmpty
;
180 mxCursor
->gotoEnd( sal_False
);
181 mxCursor
->goLeft( 1, sal_True
);
182 mxCursor
->setString( aEmpty
);
185 GetImport().GetTextImport()->ResetCursor();
188 if( mxAnnotation
.is() )
190 mxAnnotation
->setAuthor( maAuthorBuffer
.makeStringAndClear() );
192 util::DateTime aDateTime
;
193 if (::sax::Converter::parseDateTime(aDateTime
, 0,
194 maDateBuffer
.makeStringAndClear()))
196 mxAnnotation
->setDateTime(aDateTime
);
201 TYPEINIT1( SdXMLGenericPageContext
, SvXMLImportContext
);
203 SdXMLGenericPageContext::SdXMLGenericPageContext(
204 SvXMLImport
& rImport
,
205 sal_uInt16 nPrfx
, const OUString
& rLocalName
,
206 const Reference
< xml::sax::XAttributeList
>& xAttrList
,
207 Reference
< drawing::XShapes
>& rShapes
)
208 : SvXMLImportContext( rImport
, nPrfx
, rLocalName
)
209 , mxShapes( rShapes
)
210 , mxAnnotationAccess( rShapes
, UNO_QUERY
)
212 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
214 for(sal_Int16 i
=0; i
< nAttrCount
; i
++)
216 OUString sAttrName
= xAttrList
->getNameByIndex( i
);
218 sal_uInt16 nPrefix
= GetSdImport().GetNamespaceMap().GetKeyByAttrName( sAttrName
, &aLocalName
);
219 if( (nPrefix
== XML_NAMESPACE_DRAW
) && IsXMLToken( aLocalName
, XML_NAV_ORDER
) )
221 msNavOrder
= xAttrList
->getValueByIndex( i
);
227 SdXMLGenericPageContext::~SdXMLGenericPageContext()
231 void SdXMLGenericPageContext::StartElement( const Reference
< ::com::sun::star::xml::sax::XAttributeList
>& )
233 GetImport().GetShapeImport()->pushGroupForSorting( mxShapes
);
235 if( GetImport().IsFormsSupported() )
236 GetImport().GetFormImport()->startPage( Reference
< drawing::XDrawPage
>::query( mxShapes
) );
239 SvXMLImportContext
* SdXMLGenericPageContext::CreateChildContext( sal_uInt16 nPrefix
,
240 const OUString
& rLocalName
,
241 const Reference
< xml::sax::XAttributeList
>& xAttrList
)
243 SvXMLImportContext
* pContext
= 0L;
245 if( nPrefix
== XML_NAMESPACE_PRESENTATION
&& IsXMLToken( rLocalName
, XML_ANIMATIONS
) )
247 pContext
= new XMLAnimationsContext( GetImport(), nPrefix
, rLocalName
, xAttrList
);
249 else if( nPrefix
== XML_NAMESPACE_OFFICE
&& IsXMLToken( rLocalName
, XML_FORMS
) )
251 if( GetImport().IsFormsSupported() )
252 pContext
= xmloff::OFormLayerXMLImport::createOfficeFormsContext( GetImport(), nPrefix
, rLocalName
);
254 else if( ((nPrefix
== XML_NAMESPACE_OFFICE
) || (nPrefix
== XML_NAMESPACE_OFFICE_EXT
)) && IsXMLToken( rLocalName
, XML_ANNOTATION
) )
256 if( mxAnnotationAccess
.is() )
257 pContext
= new DrawAnnotationContext( GetImport(), nPrefix
, rLocalName
, xAttrList
, mxAnnotationAccess
);
261 // call GroupChildContext function at common ShapeImport
262 pContext
= GetImport().GetShapeImport()->CreateGroupChildContext(
263 GetImport(), nPrefix
, rLocalName
, xAttrList
, mxShapes
);
266 // call parent when no own context was created
268 pContext
= SvXMLImportContext::CreateChildContext(nPrefix
, rLocalName
, xAttrList
);
273 void SdXMLGenericPageContext::EndElement()
275 GetImport().GetShapeImport()->popGroupAndSort();
277 if( GetImport().IsFormsSupported() )
278 GetImport().GetFormImport()->endPage();
280 if( !maUseHeaderDeclName
.isEmpty() || !maUseFooterDeclName
.isEmpty() || !maUseDateTimeDeclName
.isEmpty() )
284 Reference
<beans::XPropertySet
> xSet(mxShapes
, uno::UNO_QUERY_THROW
);
285 Reference
< beans::XPropertySetInfo
> xInfo( xSet
->getPropertySetInfo() );
287 if( !maUseHeaderDeclName
.isEmpty() )
289 const OUString
aStrHeaderTextProp( "HeaderText" );
290 if( xInfo
->hasPropertyByName( aStrHeaderTextProp
) )
291 xSet
->setPropertyValue( aStrHeaderTextProp
,
292 makeAny( GetSdImport().GetHeaderDecl( maUseHeaderDeclName
) ) );
295 if( !maUseFooterDeclName
.isEmpty() )
297 const OUString
aStrFooterTextProp( "FooterText" );
298 if( xInfo
->hasPropertyByName( aStrFooterTextProp
) )
299 xSet
->setPropertyValue( aStrFooterTextProp
,
300 makeAny( GetSdImport().GetFooterDecl( maUseFooterDeclName
) ) );
303 if( !maUseDateTimeDeclName
.isEmpty() )
305 const OUString
aStrDateTimeTextProp( "DateTimeText" );
306 if( xInfo
->hasPropertyByName( aStrDateTimeTextProp
) )
309 OUString aDateTimeFormat
;
310 const OUString
aText( GetSdImport().GetDateTimeDecl( maUseDateTimeDeclName
, bFixed
, aDateTimeFormat
) );
312 xSet
->setPropertyValue("IsDateTimeFixed",
317 xSet
->setPropertyValue( aStrDateTimeTextProp
, makeAny( aText
) );
319 else if( !aDateTimeFormat
.isEmpty() )
321 const SdXMLStylesContext
* pStyles
= dynamic_cast< const SdXMLStylesContext
* >( GetSdImport().GetShapeImport()->GetStylesContext() );
323 pStyles
= dynamic_cast< const SdXMLStylesContext
* >( GetSdImport().GetShapeImport()->GetAutoStylesContext() );
327 const SdXMLNumberFormatImportContext
* pSdNumStyle
=
328 dynamic_cast< const SdXMLNumberFormatImportContext
* >( pStyles
->FindStyleChildContext( XML_STYLE_FAMILY_DATA_STYLE
, aDateTimeFormat
, true ) );
332 xSet
->setPropertyValue("DateTimeFormat",
333 makeAny( pSdNumStyle
->GetDrawKey() ) );
340 catch(const uno::Exception
&)
342 OSL_FAIL("xmloff::SdXMLGenericPageContext::EndElement(), unexpected exception caught!");
346 SetNavigationOrder();
349 void SdXMLGenericPageContext::SetStyle( OUString
& rStyleName
)
351 // set PageProperties?
352 if(!rStyleName
.isEmpty())
356 const SvXMLImportContext
* pContext
= GetSdImport().GetShapeImport()->GetAutoStylesContext();
358 if( pContext
&& pContext
->ISA( SvXMLStyleContext
) )
360 const SdXMLStylesContext
* pStyles
= static_cast<const SdXMLStylesContext
*>(pContext
);
363 const SvXMLStyleContext
* pStyle
= pStyles
->FindStyleChildContext(
364 XML_STYLE_FAMILY_SD_DRAWINGPAGE_ID
, rStyleName
);
366 if(pStyle
&& pStyle
->ISA(XMLPropStyleContext
))
368 const XMLPropStyleContext
* pPropStyle
= static_cast<const XMLPropStyleContext
*>(pStyle
);
370 Reference
<beans::XPropertySet
> xPropSet1(mxShapes
, uno::UNO_QUERY
);
373 Reference
< beans::XPropertySet
> xPropSet( xPropSet1
);
374 Reference
< beans::XPropertySet
> xBackgroundSet
;
376 const OUString
aBackground("Background");
377 if( xPropSet1
->getPropertySetInfo()->hasPropertyByName( aBackground
) )
379 Reference
< beans::XPropertySetInfo
> xInfo( xPropSet1
->getPropertySetInfo() );
380 if( xInfo
.is() && xInfo
->hasPropertyByName( aBackground
) )
382 Reference
< lang::XMultiServiceFactory
> xServiceFact(GetSdImport().GetModel(), uno::UNO_QUERY
);
383 if(xServiceFact
.is())
385 xBackgroundSet
= Reference
< beans::XPropertySet
>::query(
386 xServiceFact
->createInstance(
387 OUString("com.sun.star.drawing.Background")));
391 if( xBackgroundSet
.is() )
392 xPropSet
= PropertySetMerger_CreateInstance( xPropSet1
, xBackgroundSet
);
397 const_cast<XMLPropStyleContext
*>(pPropStyle
)->FillPropertySet(xPropSet
);
399 if( xBackgroundSet
.is() )
400 xPropSet1
->setPropertyValue( aBackground
, uno::makeAny( xBackgroundSet
) );
407 catch (const uno::Exception
&)
409 OSL_FAIL( "SdXMLGenericPageContext::SetStyle(): uno::Exception caught!" );
414 void SdXMLGenericPageContext::SetLayout()
416 // set PresentationPageLayout?
417 if(GetSdImport().IsImpress() && !maPageLayoutName
.isEmpty())
419 sal_Int32 nType
= -1;
421 const SvXMLImportContext
* pContext
= GetSdImport().GetShapeImport()->GetStylesContext();
423 if( pContext
&& pContext
->ISA( SvXMLStyleContext
) )
425 const SdXMLStylesContext
* pStyles
= static_cast<const SdXMLStylesContext
*>(pContext
);
428 const SvXMLStyleContext
* pStyle
= pStyles
->FindStyleChildContext( XML_STYLE_FAMILY_SD_PRESENTATIONPAGELAYOUT_ID
, maPageLayoutName
);
430 if(pStyle
&& pStyle
->ISA(SdXMLPresentationPageLayoutContext
))
432 const SdXMLPresentationPageLayoutContext
* pLayout
= static_cast<const SdXMLPresentationPageLayoutContext
*>(pStyle
);
433 nType
= pLayout
->GetTypeId();
440 Reference
< container::XNameAccess
> xPageLayouts( GetSdImport().getPageLayouts() );
441 if( xPageLayouts
.is() )
443 if( xPageLayouts
->hasByName( maPageLayoutName
) )
444 xPageLayouts
->getByName( maPageLayoutName
) >>= nType
;
451 Reference
<beans::XPropertySet
> xPropSet(mxShapes
, uno::UNO_QUERY
);
454 OUString
aPropName("Layout");
455 Reference
< beans::XPropertySetInfo
> xInfo( xPropSet
->getPropertySetInfo() );
456 if( xInfo
.is() && xInfo
->hasPropertyByName( aPropName
) )
457 xPropSet
->setPropertyValue(aPropName
, uno::makeAny( (sal_Int16
)nType
) );
463 void SdXMLGenericPageContext::DeleteAllShapes()
465 // now delete all up-to-now contained shapes; they have been created
466 // when setting the presentation page layout.
467 while(mxShapes
->getCount())
469 Reference
< drawing::XShape
> xShape
;
470 uno::Any
aAny(mxShapes
->getByIndex(0L));
476 mxShapes
->remove(xShape
);
481 void SdXMLGenericPageContext::SetPageMaster( OUString
& rsPageMasterName
)
483 if( GetSdImport().GetShapeImport()->GetStylesContext() )
485 // look for PageMaster with this name
487 // #80012# GetStylesContext() replaced with GetAutoStylesContext()
488 const SvXMLStylesContext
* pAutoStyles
= GetSdImport().GetShapeImport()->GetAutoStylesContext();
490 const SvXMLStyleContext
* pStyle
= pAutoStyles
? pAutoStyles
->FindStyleChildContext(XML_STYLE_FAMILY_SD_PAGEMASTERCONEXT_ID
, rsPageMasterName
) : NULL
;
492 if(pStyle
&& pStyle
->ISA(SdXMLPageMasterContext
))
494 const SdXMLPageMasterContext
* pPageMaster
= static_cast<const SdXMLPageMasterContext
*>(pStyle
);
495 const SdXMLPageMasterStyleContext
* pPageMasterContext
= pPageMaster
->GetPageMasterStyle();
497 if(pPageMasterContext
)
499 Reference
< drawing::XDrawPage
> xMasterPage(GetLocalShapesContext(), uno::UNO_QUERY
);
502 // set sizes for this masterpage
503 Reference
<beans::XPropertySet
> xPropSet(xMasterPage
, uno::UNO_QUERY
);
508 aAny
<<= pPageMasterContext
->GetBorderBottom();
509 xPropSet
->setPropertyValue("BorderBottom", aAny
);
511 aAny
<<= pPageMasterContext
->GetBorderLeft();
512 xPropSet
->setPropertyValue("BorderLeft", aAny
);
514 aAny
<<= pPageMasterContext
->GetBorderRight();
515 xPropSet
->setPropertyValue("BorderRight", aAny
);
517 aAny
<<= pPageMasterContext
->GetBorderTop();
518 xPropSet
->setPropertyValue("BorderTop", aAny
);
520 aAny
<<= pPageMasterContext
->GetWidth();
521 xPropSet
->setPropertyValue("Width", aAny
);
523 aAny
<<= pPageMasterContext
->GetHeight();
524 xPropSet
->setPropertyValue("Height", aAny
);
526 aAny
<<= pPageMasterContext
->GetOrientation();
527 xPropSet
->setPropertyValue("Orientation", aAny
);
536 class XoNavigationOrderAccess
: public ::cppu::WeakImplHelper1
< XIndexAccess
>
539 XoNavigationOrderAccess( std::vector
< Reference
< XShape
> >& rShapes
);
542 virtual sal_Int32 SAL_CALL
getCount( ) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
543 virtual Any SAL_CALL
getByIndex( sal_Int32 Index
) throw (IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
, std::exception
) SAL_OVERRIDE
;
546 virtual Type SAL_CALL
getElementType( ) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
547 virtual sal_Bool SAL_CALL
hasElements( ) throw (RuntimeException
, std::exception
) SAL_OVERRIDE
;
550 std::vector
< Reference
< XShape
> > maShapes
;
553 XoNavigationOrderAccess::XoNavigationOrderAccess( std::vector
< Reference
< XShape
> >& rShapes
)
555 maShapes
.swap( rShapes
);
559 sal_Int32 SAL_CALL
XoNavigationOrderAccess::getCount( ) throw (RuntimeException
, std::exception
)
561 return static_cast< sal_Int32
>( maShapes
.size() );
564 Any SAL_CALL
XoNavigationOrderAccess::getByIndex( sal_Int32 Index
) throw (IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
, std::exception
)
566 if( (Index
< 0) || (Index
> getCount()) )
567 throw IndexOutOfBoundsException();
569 return Any( maShapes
[Index
] );
573 Type SAL_CALL
XoNavigationOrderAccess::getElementType( ) throw (RuntimeException
, std::exception
)
575 return cppu::UnoType
<XShape
>::get();
578 sal_Bool SAL_CALL
XoNavigationOrderAccess::hasElements( ) throw (RuntimeException
, std::exception
)
580 return maShapes
.empty() ? sal_False
: sal_True
;
583 void SdXMLGenericPageContext::SetNavigationOrder()
585 if( !msNavOrder
.isEmpty() ) try
588 const sal_uInt32 nCount
= static_cast< sal_uInt32
>( mxShapes
->getCount() );
589 std::vector
< Reference
< XShape
> > aShapes( nCount
);
591 ::comphelper::UnoInterfaceToUniqueIdentifierMapper
& rIdMapper
= GetSdImport().getInterfaceToIdentifierMapper();
592 SvXMLTokenEnumerator
aEnumerator( msNavOrder
);
594 for( nIndex
= 0; nIndex
< nCount
; ++nIndex
)
596 if( !aEnumerator
.getNextToken(sId
) )
599 aShapes
[nIndex
] = Reference
< XShape
>( rIdMapper
.getReference( sId
), UNO_QUERY
);
602 for( nIndex
= 0; nIndex
< nCount
; ++nIndex
)
604 if( !aShapes
[nIndex
].is() )
606 OSL_FAIL("xmloff::SdXMLGenericPageContext::SetNavigationOrder(), draw:nav-order attribute incomplete!");
612 Reference
< XPropertySet
> xSet( mxShapes
, UNO_QUERY_THROW
);
613 xSet
->setPropertyValue("NavigationOrder", Any( Reference
< XIndexAccess
>( new XoNavigationOrderAccess( aShapes
) ) ) );
615 catch(const uno::Exception
&)
617 OSL_FAIL("xmloff::SdXMLGenericPageContext::SetNavigationOrder(), unexpected exception caught while importing shape navigation order!");
621 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */