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: styleexp.cxx,v $
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 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmloff.hxx"
33 #include <tools/debug.hxx>
34 #ifndef _SVSTDARR_STRINGSSORTDTOR_DECL
35 #define _SVSTDARR_STRINGSSORTDTOR
36 #include <svtools/svstdarr.hxx>
38 #include <xmloff/nmspmap.hxx>
39 #include "xmlnmspe.hxx"
40 #include <xmloff/xmltoken.hxx>
41 #ifndef _XMLOFF_XMLITMAP_HXX
42 //#include "xmlitmap.hxx"
44 #include <xmloff/xmluconv.hxx>
45 #include "xmlkywd.hxx"
46 #include <xmloff/attrlist.hxx>
47 #include <xmloff/xmlprmap.hxx>
48 #include <xmloff/xmlexppr.hxx>
49 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
50 #include <com/sun/star/frame/XModel.hpp>
51 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
52 #include <com/sun/star/style/XStyle.hpp>
53 #include <com/sun/star/container/XNameContainer.hpp>
54 #include <com/sun/star/beans/XPropertySet.hpp>
55 #include <com/sun/star/beans/XPropertyState.hpp>
56 #ifndef _COM_SUN_STAR_DOCUMENT_XEVENTSSUPPLIER_HPP
57 #include <com/sun/star/document/XEventsSupplier.hpp>
59 #include <com/sun/star/text/XChapterNumberingSupplier.hpp>
60 #include <xmloff/xmlaustp.hxx>
61 #ifndef _XMLOFF_STYLEEXP_HXX
62 #include <xmloff/styleexp.hxx>
64 #include <xmloff/xmlexp.hxx>
65 #include <xmloff/XMLEventExport.hxx>
67 using ::rtl::OUString
;
68 using ::rtl::OUStringBuffer
;
70 using namespace ::com::sun::star
;
71 using namespace ::com::sun::star::uno
;
72 using namespace ::com::sun::star::style
;
73 using namespace ::com::sun::star::container
;
74 using namespace ::com::sun::star::beans
;
75 using namespace ::com::sun::star::text
;
76 using namespace ::xmloff::token
;
78 using ::com::sun::star::document::XEventsSupplier
;
80 XMLStyleExport::XMLStyleExport(
82 const ::rtl::OUString
& rPoolStyleName
,
83 SvXMLAutoStylePoolP
*pAutoStyleP
) :
85 sIsPhysical( RTL_CONSTASCII_USTRINGPARAM( "IsPhysical" ) ),
86 sIsAutoUpdate( RTL_CONSTASCII_USTRINGPARAM( "IsAutoUpdate" ) ),
87 sFollowStyle( RTL_CONSTASCII_USTRINGPARAM( "FollowStyle" ) ),
88 sNumberingStyleName( RTL_CONSTASCII_USTRINGPARAM( "NumberingStyleName" ) ),
89 sOutlineLevel( RTL_CONSTASCII_USTRINGPARAM( "OutlineLevel" ) ),//#outline level,add by zhaojianwei
90 sPoolStyleName( rPoolStyleName
),
91 pAutoStylePool( pAutoStyleP
)
95 XMLStyleExport::~XMLStyleExport()
99 void XMLStyleExport::exportStyleAttributes( const Reference
< XStyle
>& )
103 void XMLStyleExport::exportStyleContent( const Reference
< XStyle
>& )
107 sal_Bool
XMLStyleExport::exportStyle(
108 const Reference
< XStyle
>& rStyle
,
109 const OUString
& rXMLFamily
,
110 const UniReference
< SvXMLExportPropertyMapper
>& rPropMapper
,
111 const Reference
< XNameAccess
>& xStyles
, //#outline level,add by zhaojianwei
112 const OUString
* pPrefix
)
114 Reference
< XPropertySet
> xPropSet( rStyle
, UNO_QUERY
);
115 Reference
< XPropertySetInfo
> xPropSetInfo
=
116 xPropSet
->getPropertySetInfo();
119 // Don't export styles that aren't existing really. This may be the
120 // case for StarOffice Writer's pool styles.
121 if( xPropSetInfo
->hasPropertyByName( sIsPhysical
) )
123 aAny
= xPropSet
->getPropertyValue( sIsPhysical
);
124 if( !*(sal_Bool
*)aAny
.getValue() )
129 GetExport().CheckAttrList();
136 sName
+= rStyle
->getName();
138 sal_Bool bEncoded
= sal_False
;
139 const OUString
sEncodedStyleName(GetExport().EncodeStyleName( sName
, &bEncoded
));
140 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_NAME
, sEncodedStyleName
);
143 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_DISPLAY_NAME
,
146 // style:family="..."
147 if( rXMLFamily
.getLength() > 0 )
148 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_FAMILY
, rXMLFamily
);
150 // style:parent-style-name="..."
151 OUString
sParentString(rStyle
->getParentStyle());
154 if(sParentString
.getLength())
158 sParent
+= sParentString
;
161 sParent
= sPoolStyleName
;
163 if( sParent
.getLength() )
164 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_PARENT_STYLE_NAME
,
165 GetExport().EncodeStyleName( sParent
) );
167 // style:next-style-name="..." (paragraph styles only)
168 if( xPropSetInfo
->hasPropertyByName( sFollowStyle
) )
170 aAny
= xPropSet
->getPropertyValue( sFollowStyle
);
173 if( sName
!= sNextName
)
175 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_NEXT_STYLE_NAME
,
176 GetExport().EncodeStyleName( sNextName
) );
180 // style:auto-update="..." (SW only)
181 if( xPropSetInfo
->hasPropertyByName( sIsAutoUpdate
) )
183 aAny
= xPropSet
->getPropertyValue( sIsAutoUpdate
);
184 if( *(sal_Bool
*)aAny
.getValue() )
185 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_AUTO_UPDATE
,
189 // style:default-outline-level"..." //#outline level, add by zhaojianwei.0802
190 sal_Int32 nOutlineLevel
= 0;
191 if( xPropSetInfo
->hasPropertyByName( sOutlineLevel
) )
193 Reference
< XPropertyState
> xPropState( xPropSet
, uno::UNO_QUERY
);
194 if( PropertyState_DIRECT_VALUE
== xPropState
->getPropertyState( sOutlineLevel
) )
196 aAny
= xPropSet
->getPropertyValue( sOutlineLevel
);
197 aAny
>>= nOutlineLevel
;
198 if( nOutlineLevel
> 0 )
201 sTmp
.append( static_cast<sal_Int32
>(nOutlineLevel
));
202 GetExport().AddAttribute( XML_NAMESPACE_STYLE
,
203 XML_DEFAULT_OUTLINE_LEVEL
,
204 sTmp
.makeStringAndClear() );
208 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_DEFAULT_OUTLINE_LEVEL
,
209 OUString( RTL_CONSTASCII_USTRINGPARAM( "" )));
214 // style:list-style-name="..." (SW paragarph styles only)
215 if( xPropSetInfo
->hasPropertyByName( sNumberingStyleName
) )
217 Reference
< XPropertyState
> xPropState( xPropSet
, uno::UNO_QUERY
);
218 if( PropertyState_DIRECT_VALUE
==
219 xPropState
->getPropertyState( sNumberingStyleName
) )
221 aAny
= xPropSet
->getPropertyValue( sNumberingStyleName
);
222 if( aAny
.hasValue() )
227 // --> OD 2006-09-21 #i69523#
228 // An direct set empty list style has to be written. Otherwise,
229 // this information is lost and causes an error, if the parent
230 // style has a list style set.
231 if ( !sListName
.getLength() )
233 GetExport().AddAttribute( XML_NAMESPACE_STYLE
,
235 sListName
/* empty string */);
239 // --> OD 2006-09-27 #i69627#
240 bool bSuppressListStyle( false );
242 if ( !GetExport().writeOutlineStyleAsNormalListStyle() )
244 Reference
< XChapterNumberingSupplier
> xCNSupplier
245 (GetExport().GetModel(), UNO_QUERY
);
247 OUString sOutlineName
;
248 if (xCNSupplier
.is())
250 Reference
< XIndexReplace
> xNumRule
251 ( xCNSupplier
->getChapterNumberingRules() );
252 DBG_ASSERT( xNumRule
.is(), "no chapter numbering rules" );
256 Reference
< XPropertySet
> xNumRulePropSet
257 (xNumRule
, UNO_QUERY
);
258 xNumRulePropSet
->getPropertyValue(
259 OUString(RTL_CONSTASCII_USTRINGPARAM("Name")) )
261 bSuppressListStyle
= ( sListName
== sOutlineName
);
267 if ( sListName
.getLength() && !bSuppressListStyle
)
270 GetExport().AddAttribute( XML_NAMESPACE_STYLE
,
272 GetExport().EncodeStyleName( sListName
) );
278 //#outline level, add by zhaojianwei.0802
279 else if( nOutlineLevel
> 0 )
282 bool bNoInheritedListStyle( true );
284 /////////////////////////////////////////////////
285 Reference
<XStyle
> xStyle( xPropState
, UNO_QUERY
);
286 while ( xStyle
.is() )
288 OUString
aParentStyle( xStyle
->getParentStyle() );
289 if ( aParentStyle
.getLength() == 0 ||
290 !xStyles
->hasByName( aParentStyle
) )
296 xPropState
= Reference
< XPropertyState
>( xStyles
->getByName( aParentStyle
), UNO_QUERY
);
297 if ( !xPropState
.is() )
301 if ( xPropState
->getPropertyState( sNumberingStyleName
) == PropertyState_DIRECT_VALUE
)
303 bNoInheritedListStyle
= false;
308 xStyle
= Reference
<XStyle
>( xPropState
, UNO_QUERY
);
312 /////////////////////////////////////////////////
313 if ( bNoInheritedListStyle
)
314 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_LIST_STYLE_NAME
,
315 OUString( RTL_CONSTASCII_USTRINGPARAM( "" )));
321 // style:pool-id="..." is not required any longer since we use
322 // english style names only
323 exportStyleAttributes( rStyle
);
325 // TODO: style:help-file-name="..." and style:help-id="..." can neither
326 // be modified by UI nor by API and that for, have not to be exported
331 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_STYLE
, XML_STYLE
,
332 sal_True
, sal_True
);
334 rPropMapper
->SetStyleName( sName
);
336 // <style:properties>
337 ::std::vector
< XMLPropertyState
> xPropStates
=
338 rPropMapper
->Filter( xPropSet
);
339 rPropMapper
->exportXML( GetExport(), xPropStates
,
340 XML_EXPORT_FLAG_IGN_WS
);
342 rPropMapper
->SetStyleName( OUString() );
344 exportStyleContent( rStyle
);
346 // <script:events>, if they are supported by this style
347 Reference
<XEventsSupplier
> xEventsSupp(rStyle
, UNO_QUERY
);
348 GetExport().GetEventExport().Export(xEventsSupp
);
353 sal_Bool
XMLStyleExport::exportDefaultStyle(
354 const Reference
< XPropertySet
>& xPropSet
,
355 const OUString
& rXMLFamily
,
356 const UniReference
< SvXMLExportPropertyMapper
>& rPropMapper
)
358 Reference
< XPropertySetInfo
> xPropSetInfo
=
359 xPropSet
->getPropertySetInfo();
363 // <style:default-style ...>
364 GetExport().CheckAttrList();
367 // style:family="..."
368 if( rXMLFamily
.getLength() > 0 )
369 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_FAMILY
,
372 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_STYLE
,
374 sal_True
, sal_True
);
375 // <style:properties>
376 //::std::vector< XMLPropertyState > xPropStates =
377 // rPropMapper->FilterDefaults( xPropSet );
378 ::std::vector
< XMLPropertyState
> xPropStates
=
379 rPropMapper
->FilterDefaults( xPropSet
);
380 rPropMapper
->exportXML( GetExport(), xPropStates
,
381 XML_EXPORT_FLAG_IGN_WS
);
382 // exportStyleContent( rStyle );
388 void XMLStyleExport::exportStyleFamily(
389 const sal_Char
*pFamily
,
390 const OUString
& rXMLFamily
,
391 const UniReference
< XMLPropertySetMapper
>& rPropMapper
,
392 sal_Bool bUsed
, sal_uInt16 nFamily
, const OUString
* pPrefix
)
394 const OUString
sFamily(OUString::createFromAscii(pFamily
));
395 UniReference
< SvXMLExportPropertyMapper
> xExpPropMapper
=
396 new SvXMLExportPropertyMapper( rPropMapper
);
397 exportStyleFamily( sFamily
, rXMLFamily
, xExpPropMapper
, bUsed
, nFamily
,
401 void XMLStyleExport::exportStyleFamily(
402 const OUString
& rFamily
, const OUString
& rXMLFamily
,
403 const UniReference
< XMLPropertySetMapper
>& rPropMapper
,
404 sal_Bool bUsed
, sal_uInt16 nFamily
, const OUString
* pPrefix
)
406 UniReference
< SvXMLExportPropertyMapper
> xExpPropMapper
=
407 new SvXMLExportPropertyMapper( rPropMapper
);
408 exportStyleFamily( rFamily
, rXMLFamily
, xExpPropMapper
, bUsed
, nFamily
,
413 void XMLStyleExport::exportStyleFamily(
414 const sal_Char
*pFamily
,
415 const OUString
& rXMLFamily
,
416 const UniReference
< SvXMLExportPropertyMapper
>& rPropMapper
,
417 sal_Bool bUsed
, sal_uInt16 nFamily
, const OUString
* pPrefix
)
419 const OUString
sFamily(OUString::createFromAscii(pFamily
));
420 exportStyleFamily( sFamily
, rXMLFamily
, rPropMapper
, bUsed
, nFamily
,
424 void XMLStyleExport::exportStyleFamily(
425 const OUString
& rFamily
, const OUString
& rXMLFamily
,
426 const UniReference
< SvXMLExportPropertyMapper
>& rPropMapper
,
427 sal_Bool bUsed
, sal_uInt16 nFamily
, const OUString
* pPrefix
)
429 DBG_ASSERT( GetExport().GetModel().is(), "There is the model?" );
430 Reference
< XStyleFamiliesSupplier
> xFamiliesSupp( GetExport().GetModel(), UNO_QUERY
);
431 if( !xFamiliesSupp
.is() )
432 return; // family not available in current model
434 Reference
< XNameAccess
> xStyleCont
;
436 Reference
< XNameAccess
> xFamilies( xFamiliesSupp
->getStyleFamilies() );
437 if( xFamilies
->hasByName( rFamily
) )
438 xFamilies
->getByName( rFamily
) >>= xStyleCont
;
440 if( !xStyleCont
.is() )
443 Reference
< XNameAccess
> xStyles( xStyleCont
, UNO_QUERY
);
444 // If next styles are supported and used styles should be exported only,
445 // the next style may be unused but has to be exported, too. In this case
446 // the names of all exported styles are remembered.
447 SvStringsSortDtor
*pExportedStyles
= 0;
448 sal_Bool bFirstStyle
= sal_True
;
450 const uno::Sequence
< ::rtl::OUString
> aSeq
= xStyles
->getElementNames();
451 const ::rtl::OUString
* pIter
= aSeq
.getConstArray();
452 const ::rtl::OUString
* pEnd
= pIter
+ aSeq
.getLength();
453 for(;pIter
!= pEnd
;++pIter
)
455 Reference
< XStyle
> xStyle
;
458 xStyles
->getByName( *pIter
) >>= xStyle
;
460 catch( lang::IndexOutOfBoundsException
)
462 // due to bugs in prior versions it is possible that
463 // a binary file is missing some critical styles.
464 // The only possible way to deal with this is to
465 // not export them here and remain silent.
469 DBG_ASSERT( xStyle
.is(), "Style not found for export!" );
472 if( !bUsed
|| xStyle
->isInUse() )
474 BOOL bExported
= exportStyle( xStyle
, rXMLFamily
, rPropMapper
,
476 if( bUsed
&& bFirstStyle
&& bExported
)
478 // If this is the first style, find out wether next styles
480 Reference
< XPropertySet
> xPropSet( xStyle
, UNO_QUERY
);
481 Reference
< XPropertySetInfo
> xPropSetInfo
=
482 xPropSet
->getPropertySetInfo();
484 if( xPropSetInfo
->hasPropertyByName( sFollowStyle
) )
485 pExportedStyles
= new SvStringsSortDtor
;
486 bFirstStyle
= sal_False
;
489 if( pExportedStyles
&& bExported
)
491 // If next styles are supported, remember this style's name.
492 String
*pTmp
= new String( xStyle
->getName() );
493 if( !pExportedStyles
->Insert( pTmp
) )
498 // if an auto style pool is given, remember this style's name as a
499 // style name that must not be used by automatic styles.
501 pAutoStylePool
->RegisterName( nFamily
, xStyle
->getName() );
505 if( pExportedStyles
)
507 // if next styles are supported, export all next styles that are
508 // unused and that for, haven't been exported in the first loop.
509 pIter
= aSeq
.getConstArray();
510 for(;pIter
!= pEnd
;++pIter
)
512 Reference
< XStyle
> xStyle
;
513 xStyles
->getByName( *pIter
) >>= xStyle
;
515 DBG_ASSERT( xStyle
.is(), "Style not found for export!" );
518 Reference
< XPropertySet
> xPropSet( xStyle
, UNO_QUERY
);
519 Reference
< XPropertySetInfo
> xPropSetInfo( xPropSet
->getPropertySetInfo() );
521 // styles that aren't existing realy are ignored.
522 if( xPropSetInfo
->hasPropertyByName( sIsPhysical
) )
524 Any
aAny( xPropSet
->getPropertyValue( sIsPhysical
) );
525 if( !*(sal_Bool
*)aAny
.getValue() )
529 if( !xStyle
->isInUse() )
532 if( !xPropSetInfo
->hasPropertyByName( sFollowStyle
) )
534 DBG_ASSERT( 0==sFollowStyle
.getLength(),
535 "no follow style???" );
540 xPropSet
->getPropertyValue( sFollowStyle
) >>= sNextName
;
541 String
sTmp( sNextName
);
542 // if the next style hasn't been exported by now, export it now
543 // and remember its name.
544 if( xStyle
->getName() != sNextName
&&
545 !pExportedStyles
->Seek_Entry( &sTmp
) )
547 xStyleCont
->getByName( sNextName
) >>= xStyle
;
548 DBG_ASSERT( xStyle
.is(), "Style not found for export!" );
550 if( xStyle
.is() && exportStyle( xStyle
, rXMLFamily
, rPropMapper
, xStyles
,pPrefix
) )
551 pExportedStyles
->Insert( new String( sTmp
) );
557 delete pExportedStyles
;