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: txtstyli.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 <com/sun/star/frame/XModel.hpp>
34 #include <com/sun/star/style/XStyle.hpp>
35 #include <com/sun/star/container/XNameContainer.hpp>
36 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 #include <com/sun/star/style/ParagraphStyleCategory.hpp>
38 #ifndef _COM_SUN_STAR_DOCUMENT_XEVENTSSUPPLIER_HPP
39 #include <com/sun/star/document/XEventsSupplier.hpp>
41 #include <com/sun/star/beans/XMultiPropertySet.hpp>
42 #include "xmlnmspe.hxx"
43 #include <xmloff/xmltoken.hxx>
44 #ifndef _XMLOFF_FAMILIES_HXX
45 #include <xmloff/families.hxx>
47 #include "XMLTextPropertySetContext.hxx"
48 #include <xmloff/xmltkmap.hxx>
49 #include <xmloff/xmlimp.hxx>
50 #include <xmloff/xmluconv.hxx>
52 #ifndef _XMLOFF_TXTPRMAP_HXX
53 #include <xmloff/txtprmap.hxx>
55 #ifndef _XMLOFF_TXTSTYLI_HXX
56 #include <xmloff/txtstyli.hxx>
58 #include <xmloff/attrlist.hxx>
59 #include <xmloff/XMLEventsImportContext.hxx>
60 #include <tools/debug.hxx>
68 using ::rtl::OUString
;
69 using ::rtl::OUStringBuffer
;
71 using namespace ::std
;
72 using namespace ::com::sun::star
;
73 using namespace ::com::sun::star::uno
;
74 using namespace ::com::sun::star::xml::sax
;
75 using namespace ::com::sun::star::style
;
76 using namespace ::com::sun::star::frame
;
77 using namespace ::com::sun::star::beans
;
78 using namespace ::com::sun::star::lang
;
79 using namespace ::com::sun::star::container
;
80 //using namespace ::com::sun::star::text;
81 using namespace ::xmloff::token
;
83 static __FAR_DATA SvXMLEnumMapEntry aCategoryMap
[] =
85 { XML_TEXT
, ParagraphStyleCategory::TEXT
},
86 { XML_CHAPTER
, ParagraphStyleCategory::CHAPTER
},
87 { XML_LIST
, ParagraphStyleCategory::LIST
},
88 { XML_INDEX
, ParagraphStyleCategory::INDEX
},
89 { XML_EXTRA
, ParagraphStyleCategory::EXTRA
},
90 { XML_HTML
, ParagraphStyleCategory::HTML
},
91 { XML_TOKEN_INVALID
, 0 }
94 void XMLTextStyleContext::SetAttribute( sal_uInt16 nPrefixKey
,
95 const OUString
& rLocalName
,
96 const OUString
& rValue
)
98 if( XML_NAMESPACE_STYLE
== nPrefixKey
)
100 // TODO: use a map here
101 if( IsXMLToken( rLocalName
, XML_AUTO_UPDATE
) )
103 if( IsXMLToken( rValue
, XML_TRUE
) )
104 bAutoUpdate
= sal_True
;
106 else if( IsXMLToken( rLocalName
, XML_LIST_STYLE_NAME
) )
108 sListStyleName
= rValue
;
109 // --> OD 2006-09-21 #i69523#
110 mbListStyleSet
= sal_True
;
113 else if( IsXMLToken( rLocalName
, XML_MASTER_PAGE_NAME
) )
115 sMasterPageName
= rValue
;
116 bHasMasterPageName
= sal_True
;
118 else if( IsXMLToken( rLocalName
, XML_DATA_STYLE_NAME
) )
120 sDataStyleName
= rValue
;
122 else if( IsXMLToken( rLocalName
, XML_CLASS
) )
124 sCategoryVal
= rValue
;
126 else if( IsXMLToken( rLocalName
, XML_DEFAULT_OUTLINE_LEVEL
) )
129 if( SvXMLUnitConverter::convertNumber( nTmp
, rValue
) &&
130 // nTmp > 0 && nTmp < 256 ) //#outline level, removed by zhaojianwei
131 0 <= nTmp
&& nTmp
<= 10 ) //<-end,add by zhaojianwei
132 nOutlineLevel
= static_cast< sal_Int8
>( nTmp
);
136 XMLPropStyleContext::SetAttribute( nPrefixKey
, rLocalName
, rValue
);
141 XMLPropStyleContext::SetAttribute( nPrefixKey
, rLocalName
, rValue
);
145 TYPEINIT1( XMLTextStyleContext
, XMLPropStyleContext
);
147 XMLTextStyleContext::XMLTextStyleContext( SvXMLImport
& rImport
,
148 sal_uInt16 nPrfx
, const OUString
& rLName
,
149 const Reference
< XAttributeList
> & xAttrList
,
150 SvXMLStylesContext
& rStyles
, sal_uInt16 nFamily
,
151 sal_Bool bDefaultStyle
)
152 : XMLPropStyleContext( rImport
, nPrfx
, rLName
, xAttrList
, rStyles
, nFamily
, bDefaultStyle
)
153 , sIsAutoUpdate( RTL_CONSTASCII_USTRINGPARAM( "IsAutoUpdate" ) )
154 , sCategory( RTL_CONSTASCII_USTRINGPARAM( "Category" ) )
155 , sNumberingStyleName( RTL_CONSTASCII_USTRINGPARAM( "NumberingStyleName" ) )
156 , sOutlineLevel(RTL_CONSTASCII_USTRINGPARAM( "OutlineLevel" ) )//#outline level,add by zhaojianwei
157 , sDropCapCharStyleName( RTL_CONSTASCII_USTRINGPARAM( "DropCapCharStyleName" ) )
158 , sPageDescName( RTL_CONSTASCII_USTRINGPARAM( "PageDescName" ) )
159 //, nOutlineLevel( 0 ) // removed by zhaojianwei
160 , nOutlineLevel( -1 ) //<-end, add by zhaojianwei
161 , bAutoUpdate( sal_False
)
162 , bHasMasterPageName( sal_False
)
163 , bHasCombinedCharactersLetter( sal_False
)
164 // --> OD 2006-09-21 #i69523#
165 , mbListStyleSet( sal_False
)
167 , pEventContext( NULL
)
171 XMLTextStyleContext::~XMLTextStyleContext()
175 SvXMLImportContext
*XMLTextStyleContext::CreateChildContext(
177 const OUString
& rLocalName
,
178 const Reference
< XAttributeList
> & xAttrList
)
180 SvXMLImportContext
*pContext
= 0;
182 if( XML_NAMESPACE_STYLE
== nPrefix
)
184 sal_uInt32 nFamily
= 0;
185 if( IsXMLToken( rLocalName
, XML_TEXT_PROPERTIES
) )
186 nFamily
= XML_TYPE_PROP_TEXT
;
187 else if( IsXMLToken( rLocalName
, XML_PARAGRAPH_PROPERTIES
) )
188 nFamily
= XML_TYPE_PROP_PARAGRAPH
;
189 else if( IsXMLToken( rLocalName
, XML_SECTION_PROPERTIES
) )
190 nFamily
= XML_TYPE_PROP_SECTION
;
191 else if( IsDefaultStyle() && IsXMLToken( rLocalName
, XML_TABLE_PROPERTIES
) )
192 nFamily
= XML_TYPE_PROP_TABLE
;
193 else if( IsDefaultStyle() && IsXMLToken( rLocalName
, XML_TABLE_ROW_PROPERTIES
) )
194 nFamily
= XML_TYPE_PROP_TABLE_ROW
;
197 UniReference
< SvXMLImportPropertyMapper
> xImpPrMap
=
198 GetStyles()->GetImportPropertyMapper( GetFamily() );
200 pContext
= new XMLTextPropertySetContext( GetImport(), nPrefix
,
201 rLocalName
, xAttrList
,
205 sDropCapTextStyleName
);
208 else if ( (XML_NAMESPACE_OFFICE
== nPrefix
) &&
209 IsXMLToken( rLocalName
, XML_EVENT_LISTENERS
) )
211 // create and remember events import context
212 // (for delayed processing of events)
213 pEventContext
= new XMLEventsImportContext( GetImport(), nPrefix
,
215 pEventContext
->AddRef();
216 pContext
= pEventContext
;
220 pContext
= XMLPropStyleContext::CreateChildContext( nPrefix
, rLocalName
,
226 void XMLTextStyleContext::CreateAndInsert( sal_Bool bOverwrite
)
228 XMLPropStyleContext::CreateAndInsert( bOverwrite
);
229 Reference
< XStyle
> xStyle
= GetStyle();
230 if( !xStyle
.is() || !(bOverwrite
|| IsNew()) )
233 Reference
< XPropertySet
> xPropSet( xStyle
, UNO_QUERY
);
234 Reference
< XPropertySetInfo
> xPropSetInfo
=
235 xPropSet
->getPropertySetInfo();
236 if( xPropSetInfo
->hasPropertyByName( sIsAutoUpdate
) )
239 sal_Bool bTmp
= bAutoUpdate
;
240 aAny
.setValue( &bTmp
, ::getBooleanCppuType() );
241 xPropSet
->setPropertyValue( sIsAutoUpdate
, aAny
);
244 sal_uInt16 nCategory
= ParagraphStyleCategory::TEXT
;
245 if( XML_STYLE_FAMILY_TEXT_PARAGRAPH
== GetFamily() &&
246 sCategoryVal
.getLength() && xStyle
->isUserDefined() &&
247 xPropSetInfo
->hasPropertyByName( sCategory
) &&
248 SvXMLUnitConverter::convertEnum( nCategory
, sCategoryVal
, aCategoryMap
) )
251 aAny
<<= (sal_Int16
)nCategory
;
252 xPropSet
->setPropertyValue( sCategory
, aAny
);
255 // tell the style about it's events (if applicable)
256 if (NULL
!= pEventContext
)
258 // set event suppplier and release reference to context
259 Reference
<document::XEventsSupplier
> xEventsSupplier(xStyle
,UNO_QUERY
);
260 pEventContext
->SetEvents(xEventsSupplier
);
261 pEventContext
->ReleaseRef();
264 // --> OD 2006-10-12 #i69629#
265 if ( nOutlineLevel
> 0 )
267 GetImport().GetTextImport()->AddOutlineStyleCandidate( nOutlineLevel
,
273 void XMLTextStyleContext::SetDefaults( )
275 if( ( GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH
) ||
276 ( GetFamily() == XML_STYLE_FAMILY_TABLE_TABLE
) ||
277 ( GetFamily() == XML_STYLE_FAMILY_TABLE_ROW
) )
279 Reference
< XMultiServiceFactory
> xFactory ( GetImport().GetModel(), UNO_QUERY
);
282 Reference
< XInterface
> xInt
= xFactory
->createInstance (
283 OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.text.Defaults" ) ) );
284 Reference
< XPropertySet
> xProperties ( xInt
, UNO_QUERY
);
285 if ( xProperties
.is() )
286 FillPropertySet ( xProperties
);
291 void XMLTextStyleContext::Finish( sal_Bool bOverwrite
)
293 XMLPropStyleContext::Finish( bOverwrite
);
295 Reference
< XStyle
> xStyle
= GetStyle();
296 // --> OD 2006-09-21 #i69523#
297 // consider set empty list style
298 // if ( !( sListStyleName.getLength() ||
299 if ( !( mbListStyleSet
||
300 nOutlineLevel
>= 0 || //#outline level,add by zhaojianwei
301 sDropCapTextStyleName
.getLength() ||
302 bHasMasterPageName
) ||
304 !( bOverwrite
|| IsNew() ) )
308 Reference
< XPropertySet
> xPropSet( xStyle
, UNO_QUERY
);
309 Reference
< XPropertySetInfo
> xPropSetInfo
=
310 xPropSet
->getPropertySetInfo();
312 //#outline level,add by zhaojianwei
313 if( xPropSetInfo
->hasPropertyByName( sOutlineLevel
))
316 if( nOutlineLevel
>= 0 )
318 aAny
<<= nOutlineLevel
;
319 xPropSet
->setPropertyValue( sOutlineLevel
, aAny
);
325 // --> OD 2006-09-21 #i69523#
326 // consider set empty list style
327 // if( sListStyleName.getLength() )
328 if ( mbListStyleSet
&&
329 xPropSetInfo
->hasPropertyByName( sNumberingStyleName
) )
331 // --> OD 2006-10-12 #i70223#
332 // Only for text document from version prior OOo 2.1 resp. SO 8 PU5:
333 // - Do not apply list style, if paragraph style has a default outline
334 // level > 0 and thus, will be assigned to the corresponding list
335 // level of the outline style.
336 bool bApplyListStyle( true );
337 if ( nOutlineLevel
> 0 )
339 // --> OD 2007-12-19 #152540#
340 if ( GetImport().IsTextDocInOOoFileFormat() )
342 bApplyListStyle
= false;
347 sal_Int32
nBuild( 0 );
348 // --> OD 2008-03-19 #i86058#
349 // check explicitly on certain versions
350 if ( GetImport().getBuildIds( nUPD
, nBuild
) &&
351 ( ( nUPD
== 641 ) || ( nUPD
== 645 ) || // prior OOo 2.0
352 ( nUPD
== 680 && nBuild
<= 9073 ) ) ) // OOo 2.0 - OOo 2.0.4
354 bApplyListStyle
= false;
361 if ( bApplyListStyle
)
363 if ( !sListStyleName
.getLength() )
366 aAny
<<= sListStyleName
/* empty string */;
367 xPropSet
->setPropertyValue( sNumberingStyleName
, aAny
);
371 // change list style name to display name
372 OUString
sDisplayListStyleName(
373 GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_TEXT_LIST
,
375 // The families container must exist
376 const Reference
< XNameContainer
>& rNumStyles
=
377 GetImport().GetTextImport()->GetNumberingStyles();
378 // if( rNumStyles.is() && rNumStyles->hasByName( sDisplayListStyleName ) &&
379 // xPropSetInfo->hasPropertyByName( sNumberingStyleName ) )
380 if ( rNumStyles
.is() &&
381 rNumStyles
->hasByName( sDisplayListStyleName
) )
384 aAny
<<= sDisplayListStyleName
;
385 xPropSet
->setPropertyValue( sNumberingStyleName
, aAny
);
393 if( sDropCapTextStyleName
.getLength() )
395 // change list style name to display name
396 OUString
sDisplayDropCapTextStyleName(
397 GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_TEXT_TEXT
,
398 sDropCapTextStyleName
) );
399 // The families cointaner must exist
400 const Reference
< XNameContainer
>& rTextStyles
=
401 GetImport().GetTextImport()->GetTextStyles();
402 if( rTextStyles
.is() &&
403 rTextStyles
->hasByName( sDisplayDropCapTextStyleName
) &&
404 xPropSetInfo
->hasPropertyByName( sDropCapCharStyleName
) )
407 aAny
<<= sDisplayDropCapTextStyleName
;
408 xPropSet
->setPropertyValue( sDropCapCharStyleName
, aAny
);
412 if( bHasMasterPageName
)
414 OUString
sDisplayName(
415 GetImport().GetStyleDisplayName(
416 XML_STYLE_FAMILY_MASTER_PAGE
, sMasterPageName
) );
417 // The families cointaner must exist
418 const Reference
< XNameContainer
>& rPageStyles
=
419 GetImport().GetTextImport()->GetPageStyles();
420 if( ( !sDisplayName
.getLength() ||
422 rPageStyles
->hasByName( sDisplayName
)) ) &&
423 xPropSetInfo
->hasPropertyByName( sPageDescName
) )
426 aAny
<<= sDisplayName
;
427 xPropSet
->setPropertyValue( sPageDescName
, aAny
);
432 void XMLTextStyleContext::FillPropertySet(
433 const Reference
<XPropertySet
> & rPropSet
)
435 // imitate the FillPropertySet of the super class, so we get a chance to
436 // catch the combined characters attribute
438 // imitate XMLPropStyleContext::FillPropertySet(...)
439 UniReference
< SvXMLImportPropertyMapper
> xImpPrMap
=
440 ((SvXMLStylesContext
*)GetStyles())->GetImportPropertyMapper(GetFamily());
441 DBG_ASSERT( xImpPrMap
.is(), "Where is the import prop mapper?" );
445 // imitate SvXMLImportPropertyMapper::FillPropertySet(...)
447 // The reason for this is that we have no other way to
448 // efficiently intercept the value of combined characters. To
449 // get that value, we could iterate through the map once more,
450 // but instead we chose to insert the code into this
451 // iteration. I haven't been able to come up with a much more
452 // intelligent solution.
455 struct _ContextID_Index_Pair aContextIDs
[] =
457 { CTF_COMBINED_CHARACTERS_FIELD
, -1 },
458 { CTF_KEEP_TOGETHER
, -1 },
459 { CTF_BORDER_MODEL
, -1 },
460 { CTF_TEXT_DISPLAY
, -1 },
461 { CTF_FONTFAMILYNAME
, -1 },
462 { CTF_FONTFAMILYNAME_CJK
, -1 },
463 { CTF_FONTFAMILYNAME_CTL
, -1 },
467 bool bAutomatic
= false;
468 if( ((SvXMLStylesContext
*)GetStyles())->IsAutomaticStyle() &&
469 ( GetFamily() == XML_STYLE_FAMILY_TEXT_TEXT
|| GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH
) )
472 if( GetAutoName().getLength() )
474 OUString sAutoProp
= ( GetFamily() == XML_STYLE_FAMILY_TEXT_TEXT
) ?
475 OUString( RTL_CONSTASCII_USTRINGPARAM("CharAutoStyleName") ):
476 OUString( RTL_CONSTASCII_USTRINGPARAM("ParaAutoStyleName") );
479 rPropSet
->setPropertyValue( sAutoProp
, makeAny(GetAutoName()) );
481 catch( const RuntimeException
& ) { throw; }
482 catch( const Exception
& )
489 xImpPrMap
->CheckSpecialContext( GetProperties(), rPropSet
, aContextIDs
);
491 xImpPrMap
->FillPropertySet( GetProperties(), rPropSet
, aContextIDs
);
493 // have we found a combined characters
494 sal_Int32 nIndex
= aContextIDs
[0].nIndex
;
497 Any
& rAny
= GetProperties()[nIndex
].maValue
;
498 sal_Bool bVal
= *(sal_Bool
*)rAny
.getValue();
499 bHasCombinedCharactersLetter
= bVal
;
502 // get property set info
503 Reference
< XPropertySetInfo
> xInfo
;
505 // keep-together: the application default is different from
506 // the file format default. Hence, if we always set this
507 // value; if we didn't find one, we'll set to false, the file
509 // border-model: same
510 if( IsDefaultStyle() && GetFamily() == XML_STYLE_FAMILY_TABLE_ROW
)
512 OUString sIsSplitAllowed
=
513 OUString( RTL_CONSTASCII_USTRINGPARAM( "IsSplitAllowed" ) );
514 DBG_ASSERT( rPropSet
->getPropertySetInfo()->hasPropertyByName( sIsSplitAllowed
),
515 "property missing?" );
516 rPropSet
->setPropertyValue( sIsSplitAllowed
,
517 (aContextIDs
[1].nIndex
== -1)
519 : GetProperties()[aContextIDs
[1].nIndex
].maValue
);
522 if( IsDefaultStyle() && GetFamily() == XML_STYLE_FAMILY_TABLE_TABLE
)
524 OUString
sCollapsingBorders(
525 OUString( RTL_CONSTASCII_USTRINGPARAM( "CollapsingBorders" ) ) );
526 DBG_ASSERT( rPropSet
->getPropertySetInfo()->hasPropertyByName( sCollapsingBorders
),
527 "property missing?" );
528 rPropSet
->setPropertyValue( sCollapsingBorders
,
529 (aContextIDs
[2].nIndex
== -1)
531 : GetProperties()[aContextIDs
[2].nIndex
].maValue
);
535 // check for StarBats and StarMath fonts
538 xInfo
.set(rPropSet
->getPropertySetInfo());
540 // iterate over aContextIDs entries 3..6
541 for ( sal_Int32 i
= 3; i
< 7; i
++ )
543 nIndex
= aContextIDs
[i
].nIndex
;
547 struct XMLPropertyState
& rState
= GetProperties()[nIndex
];
548 Any rAny
= rState
.maValue
;
549 sal_Int32 nMapperIndex
= rState
.mnIndex
;
551 // Now check for font name in rState and set corrected value,
555 if ( sFontName
.getLength() > 0 )
557 OUString
sStarBats( RTL_CONSTASCII_USTRINGPARAM("StarBats" ) );
558 OUString
sStarMath( RTL_CONSTASCII_USTRINGPARAM("StarMath" ) );
559 if ( sFontName
.equalsIgnoreAsciiCase( sStarBats
) ||
560 sFontName
.equalsIgnoreAsciiCase( sStarMath
) )
562 // construct new value
563 sFontName
= OUString(
564 RTL_CONSTASCII_USTRINGPARAM("StarSymbol") );
568 // get property set mapper
569 UniReference
<XMLPropertySetMapper
> rPropMapper
=
570 xImpPrMap
->getPropertySetMapper();
573 OUString
rPropertyName(
574 rPropMapper
->GetEntryAPIName(nMapperIndex
) );
576 xInfo
= rPropSet
->getPropertySetInfo();
577 if ( xInfo
->hasPropertyByName( rPropertyName
) )
579 rPropSet
->setPropertyValue( rPropertyName
, aAny
);
582 // else: "normal" style name -> no correction is necessary
584 // else: no style name found -> illegal value -> ignore