1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmloff.hxx"
26 #include <tools/debug.hxx>
27 #ifndef _SVSTDARR_STRINGSSORTDTOR_DECL
28 #define _SVSTDARR_STRINGSSORTDTOR
29 #include <svl/svstdarr.hxx>
30 #endif
31 #include <xmloff/nmspmap.hxx>
32 #include "xmloff/xmlnmspe.hxx"
33 #include <xmloff/xmltoken.hxx>
34 #ifndef _XMLOFF_XMLITMAP_HXX
35 //#include "xmlitmap.hxx"
36 #endif
37 #include <xmloff/xmluconv.hxx>
38 #include <xmloff/attrlist.hxx>
39 #include <xmloff/xmlprmap.hxx>
40 #include <xmloff/xmlexppr.hxx>
41 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
42 #include <com/sun/star/frame/XModel.hpp>
43 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
44 #include <com/sun/star/style/XStyle.hpp>
45 #include <com/sun/star/container/XNameContainer.hpp>
46 #include <com/sun/star/beans/XPropertySet.hpp>
47 #include <com/sun/star/beans/XPropertyState.hpp>
48 #ifndef _COM_SUN_STAR_DOCUMENT_XEVENTSSUPPLIER_HPP
49 #include <com/sun/star/document/XEventsSupplier.hpp>
50 #endif
51 #include <com/sun/star/text/XChapterNumberingSupplier.hpp>
52 #include <xmloff/xmlaustp.hxx>
53 #ifndef _XMLOFF_STYLEEXP_HXX
54 #include <xmloff/styleexp.hxx>
55 #endif
56 #include <xmloff/xmlexp.hxx>
57 #include <xmloff/XMLEventExport.hxx>
58
59 using ::rtl::OUString;
60 using ::rtl::OUStringBuffer;
61
62 using namespace ::com::sun::star;
63 using namespace ::com::sun::star::uno;
64 using namespace ::com::sun::star::style;
65 using namespace ::com::sun::star::container;
66 using namespace ::com::sun::star::beans;
67 using namespace ::com::sun::star::text;
68 using namespace ::xmloff::token;
69
70 using ::com::sun::star::document::XEventsSupplier;
71
XMLStyleExport(SvXMLExport & rExp,const::rtl::OUString & rPoolStyleName,SvXMLAutoStylePoolP * pAutoStyleP)72 XMLStyleExport::XMLStyleExport(
73 SvXMLExport& rExp,
74 const ::rtl::OUString& rPoolStyleName,
75 SvXMLAutoStylePoolP *pAutoStyleP ) :
76 rExport( rExp ),
77 sIsPhysical( RTL_CONSTASCII_USTRINGPARAM( "IsPhysical" ) ),
78 sIsAutoUpdate( RTL_CONSTASCII_USTRINGPARAM( "IsAutoUpdate" ) ),
79 sFollowStyle( RTL_CONSTASCII_USTRINGPARAM( "FollowStyle" ) ),
80 sNumberingStyleName( RTL_CONSTASCII_USTRINGPARAM( "NumberingStyleName" ) ),
81 sOutlineLevel( RTL_CONSTASCII_USTRINGPARAM( "OutlineLevel" ) ),//#outline level,add by zhaojianwei
82 sPoolStyleName( rPoolStyleName ),
83 pAutoStylePool( pAutoStyleP )
84 {
85 }
86
~XMLStyleExport()87 XMLStyleExport::~XMLStyleExport()
88 {
89 }
90
exportStyleAttributes(const Reference<XStyle> &)91 void XMLStyleExport::exportStyleAttributes( const Reference< XStyle >& )
92 {
93 }
94
exportStyleContent(const Reference<XStyle> &)95 void XMLStyleExport::exportStyleContent( const Reference< XStyle >& )
96 {
97 }
98
exportStyle(const Reference<XStyle> & rStyle,const OUString & rXMLFamily,const UniReference<SvXMLExportPropertyMapper> & rPropMapper,const Reference<XNameAccess> & xStyles,const OUString * pPrefix)99 sal_Bool XMLStyleExport::exportStyle(
100 const Reference< XStyle >& rStyle,
101 const OUString& rXMLFamily,
102 const UniReference < SvXMLExportPropertyMapper >& rPropMapper,
103 const Reference< XNameAccess >& xStyles, //#outline level,add by zhaojianwei
104 const OUString* pPrefix )
105 {
106 Reference< XPropertySet > xPropSet( rStyle, UNO_QUERY );
107 Reference< XPropertySetInfo > xPropSetInfo =
108 xPropSet->getPropertySetInfo();
109 Any aAny;
110
111 // Don't export styles that aren't existing really. This may be the
112 // case for StarOffice Writer's pool styles.
113 if( xPropSetInfo->hasPropertyByName( sIsPhysical ) )
114 {
115 aAny = xPropSet->getPropertyValue( sIsPhysical );
116 if( !*(sal_Bool *)aAny.getValue() )
117 return sal_False;
118 }
119
120 // <style:style ...>
121 GetExport().CheckAttrList();
122
123 // style:name="..."
124 OUString sName;
125
126 if(pPrefix)
127 sName = *pPrefix;
128 sName += rStyle->getName();
129
130 sal_Bool bEncoded = sal_False;
131 const OUString sEncodedStyleName(GetExport().EncodeStyleName( sName, &bEncoded ));
132 GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NAME, sEncodedStyleName );
133
134 if( bEncoded )
135 GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_DISPLAY_NAME,
136 sName);
137
138 // style:family="..."
139 if( rXMLFamily.getLength() > 0 )
140 GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_FAMILY, rXMLFamily);
141
142 // style:parent-style-name="..."
143 OUString sParentString(rStyle->getParentStyle());
144 OUString sParent;
145
146 if(sParentString.getLength())
147 {
148 if(pPrefix)
149 sParent = *pPrefix;
150 sParent += sParentString;
151 }
152 else
153 sParent = sPoolStyleName;
154
155 if( sParent.getLength() )
156 GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_PARENT_STYLE_NAME,
157 GetExport().EncodeStyleName( sParent ) );
158
159 // style:next-style-name="..." (paragraph styles only)
160 if( xPropSetInfo->hasPropertyByName( sFollowStyle ) )
161 {
162 aAny = xPropSet->getPropertyValue( sFollowStyle );
163 OUString sNextName;
164 aAny >>= sNextName;
165 if( sName != sNextName )
166 {
167 GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NEXT_STYLE_NAME,
168 GetExport().EncodeStyleName( sNextName ) );
169 }
170 }
171
172 // style:auto-update="..." (SW only)
173 if( xPropSetInfo->hasPropertyByName( sIsAutoUpdate ) )
174 {
175 aAny = xPropSet->getPropertyValue( sIsAutoUpdate );
176 if( *(sal_Bool *)aAny.getValue() )
177 GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_AUTO_UPDATE,
178 XML_TRUE );
179 }
180
181 // style:default-outline-level"..." //#outline level, add by zhaojianwei.0802
182 sal_Int32 nOutlineLevel = 0;
183 if( xPropSetInfo->hasPropertyByName( sOutlineLevel ) )
184 {
185 Reference< XPropertyState > xPropState( xPropSet, uno::UNO_QUERY );
186 if( PropertyState_DIRECT_VALUE == xPropState->getPropertyState( sOutlineLevel ) )
187 {
188 aAny = xPropSet->getPropertyValue( sOutlineLevel );
189 aAny >>= nOutlineLevel;
190 if( nOutlineLevel > 0 )
191 {
192 OUStringBuffer sTmp;
193 sTmp.append( static_cast<sal_Int32>(nOutlineLevel));
194 GetExport().AddAttribute( XML_NAMESPACE_STYLE,
195 XML_DEFAULT_OUTLINE_LEVEL,
196 sTmp.makeStringAndClear() );
197 }
198 else
199 {
200 // --> OD 2009-12-29 #i104889#
201 // empty value for style:default-outline-level does exist
202 // since ODF 1.2. Thus, suppress its export for former versions.
203 if ( ( GetExport().getExportFlags() & EXPORT_OASIS ) != 0 &&
204 GetExport().getDefaultVersion() >= SvtSaveOptions::ODFVER_012 )
205 // <--
206 {
207 GetExport().AddAttribute( XML_NAMESPACE_STYLE,
208 XML_DEFAULT_OUTLINE_LEVEL,
209 OUString( RTL_CONSTASCII_USTRINGPARAM( "" )));
210 }
211 }
212 }
213 }//<-end,zhaojianwei
214
215 // style:list-style-name="..." (SW paragarph styles only)
216 if( xPropSetInfo->hasPropertyByName( sNumberingStyleName ) )
217 {
218 Reference< XPropertyState > xPropState( xPropSet, uno::UNO_QUERY );
219 if( PropertyState_DIRECT_VALUE ==
220 xPropState->getPropertyState( sNumberingStyleName ) )
221 {
222 aAny = xPropSet->getPropertyValue( sNumberingStyleName );
223 if( aAny.hasValue() )
224 {
225 OUString sListName;
226 aAny >>= sListName;
227
228 // --> OD 2006-09-21 #i69523#
229 // An direct set empty list style has to be written. Otherwise,
230 // this information is lost and causes an error, if the parent
231 // style has a list style set.
232 if ( !sListName.getLength() )
233 {
234 GetExport().AddAttribute( XML_NAMESPACE_STYLE,
235 XML_LIST_STYLE_NAME,
236 sListName /* empty string */);
237 }
238 else
239 {
240 // --> OD 2006-09-27 #i69627#
241 bool bSuppressListStyle( false );
242 {
243 if ( !GetExport().writeOutlineStyleAsNormalListStyle() )
244 {
245 Reference< XChapterNumberingSupplier > xCNSupplier
246 (GetExport().GetModel(), UNO_QUERY);
247
248 OUString sOutlineName;
249 if (xCNSupplier.is())
250 {
251 Reference< XIndexReplace > xNumRule
252 ( xCNSupplier->getChapterNumberingRules() );
253 DBG_ASSERT( xNumRule.is(), "no chapter numbering rules" );
254
255 if (xNumRule.is())
256 {
257 Reference< XPropertySet > xNumRulePropSet
258 (xNumRule, UNO_QUERY);
259 xNumRulePropSet->getPropertyValue(
260 OUString(RTL_CONSTASCII_USTRINGPARAM("Name")) )
261 >>= sOutlineName;
262 bSuppressListStyle = ( sListName == sOutlineName );
263 }
264 }
265 }
266 }
267
268 if ( sListName.getLength() && !bSuppressListStyle )
269 // <--
270 {
271 GetExport().AddAttribute( XML_NAMESPACE_STYLE,
272 XML_LIST_STYLE_NAME,
273 GetExport().EncodeStyleName( sListName ) );
274 }
275 }
276 // <--
277 }
278 }
279 //#outline level, add by zhaojianwei.0802
280 else if( nOutlineLevel > 0 )
281 {
282
283 bool bNoInheritedListStyle( true );
284
285 /////////////////////////////////////////////////
286 Reference<XStyle> xStyle( xPropState, UNO_QUERY );
287 while ( xStyle.is() )
288 {
289 OUString aParentStyle( xStyle->getParentStyle() );
290 if ( aParentStyle.getLength() == 0 ||
291 !xStyles->hasByName( aParentStyle ) )
292 {
293 break;
294 }
295 else
296 {
297 xPropState = Reference< XPropertyState >( xStyles->getByName( aParentStyle ), UNO_QUERY );
298 if ( !xPropState.is() )
299 {
300 break;
301 }
302 if ( xPropState->getPropertyState( sNumberingStyleName ) == PropertyState_DIRECT_VALUE )
303 {
304 bNoInheritedListStyle = false;
305 break;
306 }
307 else
308 {
309 xStyle = Reference<XStyle>( xPropState, UNO_QUERY );
310 }
311 }
312 }
313 /////////////////////////////////////////////////
314 if ( bNoInheritedListStyle )
315 GetExport().AddAttribute( XML_NAMESPACE_STYLE,
316 XML_LIST_STYLE_NAME,
317 OUString( RTL_CONSTASCII_USTRINGPARAM( "" )));
318 }
319 //<-end,zhaojianwei
320 }
321
322
323 // style:pool-id="..." is not required any longer since we use
324 // english style names only
325 exportStyleAttributes( rStyle );
326
327 // TODO: style:help-file-name="..." and style:help-id="..." can neither
328 // be modified by UI nor by API and that for, have not to be exported
329 // currently.
330
331 {
332 // <style:style>
333 SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE, XML_STYLE,
334 sal_True, sal_True );
335
336 rPropMapper->SetStyleName( sName );
337
338 // <style:properties>
339 ::std::vector< XMLPropertyState > xPropStates =
340 rPropMapper->Filter( xPropSet );
341 rPropMapper->exportXML( GetExport(), xPropStates,
342 XML_EXPORT_FLAG_IGN_WS );
343
344 rPropMapper->SetStyleName( OUString() );
345
346 exportStyleContent( rStyle );
347
348 // <script:events>, if they are supported by this style
349 Reference<XEventsSupplier> xEventsSupp(rStyle, UNO_QUERY);
350 GetExport().GetEventExport().Export(xEventsSupp);
351 }
352 return sal_True;
353 }
354
exportDefaultStyle(const Reference<XPropertySet> & xPropSet,const OUString & rXMLFamily,const UniReference<SvXMLExportPropertyMapper> & rPropMapper)355 sal_Bool XMLStyleExport::exportDefaultStyle(
356 const Reference< XPropertySet >& xPropSet,
357 const OUString& rXMLFamily,
358 const UniReference < SvXMLExportPropertyMapper >& rPropMapper )
359 {
360 Reference< XPropertySetInfo > xPropSetInfo =
361 xPropSet->getPropertySetInfo();
362
363 Any aAny;
364
365 // <style:default-style ...>
366 GetExport().CheckAttrList();
367
368 {
369 // style:family="..."
370 if( rXMLFamily.getLength() > 0 )
371 GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_FAMILY,
372 rXMLFamily );
373 // <style:style>
374 SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE,
375 XML_DEFAULT_STYLE,
376 sal_True, sal_True );
377 // <style:properties>
378 //::std::vector< XMLPropertyState > xPropStates =
379 // rPropMapper->FilterDefaults( xPropSet );
380 ::std::vector< XMLPropertyState > xPropStates =
381 rPropMapper->FilterDefaults( xPropSet );
382 rPropMapper->exportXML( GetExport(), xPropStates,
383 XML_EXPORT_FLAG_IGN_WS );
384 // exportStyleContent( rStyle );
385 }
386 return sal_True;
387 }
388
389 #if 0
390 void XMLStyleExport::exportStyleFamily(
391 const sal_Char *pFamily,
392 const OUString& rXMLFamily,
393 const UniReference < XMLPropertySetMapper >& rPropMapper,
394 sal_Bool bUsed, sal_uInt16 nFamily, const OUString* pPrefix)
395 {
396 const OUString sFamily(OUString::createFromAscii(pFamily ));
397 UniReference < SvXMLExportPropertyMapper > xExpPropMapper =
398 new SvXMLExportPropertyMapper( rPropMapper );
399 exportStyleFamily( sFamily, rXMLFamily, xExpPropMapper, bUsed, nFamily,
400 pPrefix);
401 }
402
403 void XMLStyleExport::exportStyleFamily(
404 const OUString& rFamily, const OUString& rXMLFamily,
405 const UniReference < XMLPropertySetMapper >& rPropMapper,
406 sal_Bool bUsed, sal_uInt16 nFamily, const OUString* pPrefix)
407 {
408 UniReference < SvXMLExportPropertyMapper > xExpPropMapper =
409 new SvXMLExportPropertyMapper( rPropMapper );
410 exportStyleFamily( rFamily, rXMLFamily, xExpPropMapper, bUsed, nFamily,
411 pPrefix);
412 }
413 #endif
414
exportStyleFamily(const sal_Char * pFamily,const OUString & rXMLFamily,const UniReference<SvXMLExportPropertyMapper> & rPropMapper,sal_Bool bUsed,sal_uInt16 nFamily,const OUString * pPrefix)415 void XMLStyleExport::exportStyleFamily(
416 const sal_Char *pFamily,
417 const OUString& rXMLFamily,
418 const UniReference < SvXMLExportPropertyMapper >& rPropMapper,
419 sal_Bool bUsed, sal_uInt16 nFamily, const OUString* pPrefix)
420 {
421 const OUString sFamily(OUString::createFromAscii(pFamily ));
422 exportStyleFamily( sFamily, rXMLFamily, rPropMapper, bUsed, nFamily,
423 pPrefix);
424 }
425
exportStyleFamily(const OUString & rFamily,const OUString & rXMLFamily,const UniReference<SvXMLExportPropertyMapper> & rPropMapper,sal_Bool bUsed,sal_uInt16 nFamily,const OUString * pPrefix)426 void XMLStyleExport::exportStyleFamily(
427 const OUString& rFamily, const OUString& rXMLFamily,
428 const UniReference < SvXMLExportPropertyMapper >& rPropMapper,
429 sal_Bool bUsed, sal_uInt16 nFamily, const OUString* pPrefix)
430 {
431 DBG_ASSERT( GetExport().GetModel().is(), "There is the model?" );
432 Reference< XStyleFamiliesSupplier > xFamiliesSupp( GetExport().GetModel(), UNO_QUERY );
433 if( !xFamiliesSupp.is() )
434 return; // family not available in current model
435
436 Reference< XNameAccess > xStyleCont;
437
438 Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
439 if( xFamilies->hasByName( rFamily ) )
440 xFamilies->getByName( rFamily ) >>= xStyleCont;
441
442 if( !xStyleCont.is() )
443 return;
444
445 Reference< XNameAccess > xStyles( xStyleCont, UNO_QUERY );
446 // If next styles are supported and used styles should be exported only,
447 // the next style may be unused but has to be exported, too. In this case
448 // the names of all exported styles are remembered.
449 SvStringsSortDtor *pExportedStyles = 0;
450 sal_Bool bFirstStyle = sal_True;
451
452 const uno::Sequence< ::rtl::OUString> aSeq = xStyles->getElementNames();
453 const ::rtl::OUString* pIter = aSeq.getConstArray();
454 const ::rtl::OUString* pEnd = pIter + aSeq.getLength();
455 for(;pIter != pEnd;++pIter)
456 {
457 Reference< XStyle > xStyle;
458 try
459 {
460 xStyles->getByName( *pIter ) >>= xStyle;
461 }
462 catch( lang::IndexOutOfBoundsException )
463 {
464 // due to bugs in prior versions it is possible that
465 // a binary file is missing some critical styles.
466 // The only possible way to deal with this is to
467 // not export them here and remain silent.
468 continue;
469 }
470
471 DBG_ASSERT( xStyle.is(), "Style not found for export!" );
472 if( xStyle.is() )
473 {
474 if( !bUsed || xStyle->isInUse() )
475 {
476 sal_Bool bExported = exportStyle( xStyle, rXMLFamily, rPropMapper,
477 xStyles,pPrefix );
478 if( bUsed && bFirstStyle && bExported )
479 {
480 // If this is the first style, find out whether next styles
481 // are supported.
482 Reference< XPropertySet > xPropSet( xStyle, UNO_QUERY );
483 Reference< XPropertySetInfo > xPropSetInfo =
484 xPropSet->getPropertySetInfo();
485
486 if( xPropSetInfo->hasPropertyByName( sFollowStyle ) )
487 pExportedStyles = new SvStringsSortDtor;
488 bFirstStyle = sal_False;
489 }
490
491 if( pExportedStyles && bExported )
492 {
493 // If next styles are supported, remember this style's name.
494 String *pTmp = new String( xStyle->getName() );
495 if( !pExportedStyles->Insert( pTmp ) )
496 delete pTmp;
497 }
498 }
499
500 // if an auto style pool is given, remember this style's name as a
501 // style name that must not be used by automatic styles.
502 if( pAutoStylePool )
503 pAutoStylePool->RegisterName( nFamily, xStyle->getName() );
504 }
505 }
506
507 if( pExportedStyles )
508 {
509 // if next styles are supported, export all next styles that are
510 // unused and that for, haven't been exported in the first loop.
511 pIter = aSeq.getConstArray();
512 for(;pIter != pEnd;++pIter)
513 {
514 Reference< XStyle > xStyle;
515 xStyles->getByName( *pIter ) >>= xStyle;
516
517 DBG_ASSERT( xStyle.is(), "Style not found for export!" );
518 if( xStyle.is() )
519 {
520 Reference< XPropertySet > xPropSet( xStyle, UNO_QUERY );
521 Reference< XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
522
523 // styles that aren't existing really are ignored.
524 if( xPropSetInfo->hasPropertyByName( sIsPhysical ) )
525 {
526 Any aAny( xPropSet->getPropertyValue( sIsPhysical ) );
527 if( !*(sal_Bool *)aAny.getValue() )
528 continue;
529 }
530
531 if( !xStyle->isInUse() )
532 continue;
533
534 if( !xPropSetInfo->hasPropertyByName( sFollowStyle ) )
535 {
536 DBG_ASSERT( 0==sFollowStyle.getLength(),
537 "no follow style???" );
538 continue;
539 }
540
541 OUString sNextName;
542 xPropSet->getPropertyValue( sFollowStyle ) >>= sNextName;
543 String sTmp( sNextName );
544 // if the next style hasn't been exported by now, export it now
545 // and remember its name.
546 if( xStyle->getName() != sNextName &&
547 !pExportedStyles->Seek_Entry( &sTmp ) )
548 {
549 xStyleCont->getByName( sNextName ) >>= xStyle;
550 DBG_ASSERT( xStyle.is(), "Style not found for export!" );
551
552 if( xStyle.is() && exportStyle( xStyle, rXMLFamily, rPropMapper, xStyles,pPrefix ) )
553 pExportedStyles->Insert( new String( sTmp ) );
554 }
555 }
556 }
557 }
558
559 delete pExportedStyles;
560 }
561
562
563