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: prstylei.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"
35 #include <tools/debug.hxx>
39 #include "xmlnmspe.hxx"
40 #include <xmloff/xmltoken.hxx>
41 #include <xmloff/xmlprcon.hxx>
42 #include <com/sun/star/style/XStyle.hpp>
43 #include <com/sun/star/style/XAutoStyleFamily.hpp>
44 #include <com/sun/star/container/XNameContainer.hpp>
45 #include <com/sun/star/beans/XPropertySet.hpp>
46 #include <com/sun/star/beans/XPropertyState.hpp>
47 #include <com/sun/star/beans/XMultiPropertyStates.hpp>
48 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
49 #include <xmloff/xmlimp.hxx>
51 #ifndef _XMLOFF_PRSTYLEI_HXX
52 #include <xmloff/prstylei.hxx>
54 #include <xmloff/attrlist.hxx>
55 #include "xmlerror.hxx"
57 using ::rtl::OUString
;
58 using ::rtl::OUStringBuffer
;
60 using namespace ::com::sun::star
;
61 using namespace ::com::sun::star::uno
;
62 using namespace ::com::sun::star::xml::sax
;
63 using namespace ::com::sun::star::style
;
64 using namespace ::com::sun::star::container
;
65 using namespace ::com::sun::star::beans
;
66 using namespace ::com::sun::star::lang
;
67 using namespace ::xmloff::token
;
70 void XMLPropStyleContext::SetAttribute( sal_uInt16 nPrefixKey
,
71 const OUString
& rLocalName
,
72 const OUString
& rValue
)
74 if( XML_NAMESPACE_STYLE
== nPrefixKey
&& IsXMLToken( rLocalName
, XML_FAMILY
) )
76 DBG_ASSERT( GetFamily() == ((SvXMLStylesContext
*)&mxStyles
)->GetFamily( rValue
), "unexpected style family" );
80 SvXMLStyleContext::SetAttribute( nPrefixKey
, rLocalName
, rValue
);
84 TYPEINIT1( XMLPropStyleContext
, SvXMLStyleContext
);
86 XMLPropStyleContext::XMLPropStyleContext( SvXMLImport
& rImport
,
87 sal_uInt16 nPrfx
, const OUString
& rLName
,
88 const Reference
< XAttributeList
> & xAttrList
,
89 SvXMLStylesContext
& rStyles
, sal_uInt16 nFamily
,
91 : SvXMLStyleContext( rImport
, nPrfx
, rLName
, xAttrList
, nFamily
, bDefault
)
92 , msIsPhysical( RTL_CONSTASCII_USTRINGPARAM( "IsPhysical" ) )
93 , msFollowStyle( RTL_CONSTASCII_USTRINGPARAM( "FollowStyle" ) )
94 , mxStyles( &rStyles
)
98 XMLPropStyleContext::~XMLPropStyleContext()
102 SvXMLImportContext
*XMLPropStyleContext::CreateChildContext(
104 const OUString
& rLocalName
,
105 const Reference
< XAttributeList
> & xAttrList
)
107 SvXMLImportContext
*pContext
= 0;
109 sal_uInt32 nFamily
= 0;
110 if( XML_NAMESPACE_STYLE
== nPrefix
)
112 if( IsXMLToken( rLocalName
, XML_GRAPHIC_PROPERTIES
) )
113 nFamily
= XML_TYPE_PROP_GRAPHIC
;
114 else if( IsXMLToken( rLocalName
, XML_DRAWING_PAGE_PROPERTIES
) )
115 nFamily
= XML_TYPE_PROP_DRAWING_PAGE
;
116 else if( IsXMLToken( rLocalName
, XML_TEXT_PROPERTIES
) )
117 nFamily
= XML_TYPE_PROP_TEXT
;
118 else if( IsXMLToken( rLocalName
, XML_PARAGRAPH_PROPERTIES
) )
119 nFamily
= XML_TYPE_PROP_PARAGRAPH
;
120 else if( IsXMLToken( rLocalName
, XML_RUBY_PROPERTIES
) )
121 nFamily
= XML_TYPE_PROP_RUBY
;
122 else if( IsXMLToken( rLocalName
, XML_SECTION_PROPERTIES
) )
123 nFamily
= XML_TYPE_PROP_SECTION
;
124 else if( IsXMLToken( rLocalName
, XML_TABLE_PROPERTIES
) )
125 nFamily
= XML_TYPE_PROP_TABLE
;
126 else if( IsXMLToken( rLocalName
, XML_TABLE_COLUMN_PROPERTIES
) )
127 nFamily
= XML_TYPE_PROP_TABLE_COLUMN
;
128 else if( IsXMLToken( rLocalName
, XML_TABLE_ROW_PROPERTIES
) )
129 nFamily
= XML_TYPE_PROP_TABLE_ROW
;
130 else if( IsXMLToken( rLocalName
, XML_TABLE_CELL_PROPERTIES
) )
131 nFamily
= XML_TYPE_PROP_TABLE_CELL
;
132 else if( IsXMLToken( rLocalName
, XML_CHART_PROPERTIES
) )
133 nFamily
= XML_TYPE_PROP_CHART
;
137 UniReference
< SvXMLImportPropertyMapper
> xImpPrMap
=
138 ((SvXMLStylesContext
*)&mxStyles
)->GetImportPropertyMapper(
141 pContext
= new SvXMLPropertySetContext( GetImport(), nPrefix
,
142 rLocalName
, xAttrList
,
149 pContext
= SvXMLStyleContext::CreateChildContext( nPrefix
, rLocalName
,
155 void XMLPropStyleContext::FillPropertySet(
156 const Reference
< XPropertySet
> & rPropSet
)
158 UniReference
< SvXMLImportPropertyMapper
> xImpPrMap
=
159 ((SvXMLStylesContext
*)&mxStyles
)->GetImportPropertyMapper(
161 DBG_ASSERT( xImpPrMap
.is(), "There is the import prop mapper" );
163 xImpPrMap
->FillPropertySet( maProperties
, rPropSet
);
166 void XMLPropStyleContext::SetDefaults()
170 Reference
< XStyle
> XMLPropStyleContext::Create()
172 Reference
< XStyle
> xNewStyle
;
174 OUString
sServiceName(
175 ((SvXMLStylesContext
*)&mxStyles
)->GetServiceName( GetFamily() ) );
176 if( sServiceName
.getLength() )
178 Reference
< XMultiServiceFactory
> xFactory( GetImport().GetModel(),
182 Reference
< XInterface
> xIfc
=
183 xFactory
->createInstance( sServiceName
);
185 xNewStyle
= Reference
< XStyle
>( xIfc
, UNO_QUERY
);
192 typedef ::std::set
< OUString
, ::comphelper::UStringLess
> PropertyNameSet
;
194 void XMLPropStyleContext::CreateAndInsert( sal_Bool bOverwrite
)
196 if( ((SvXMLStylesContext
*)&mxStyles
)->IsAutomaticStyle()
197 && ( GetFamily() == XML_STYLE_FAMILY_TEXT_TEXT
|| GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH
) )
199 Reference
< XAutoStyleFamily
> xAutoFamily
=
200 ((SvXMLStylesContext
*)&mxStyles
)->GetAutoStyles( GetFamily() );
201 if( !xAutoFamily
.is() )
203 UniReference
< SvXMLImportPropertyMapper
> xImpPrMap
=
204 ((SvXMLStylesContext
*)&mxStyles
)->GetImportPropertyMapper( GetFamily() );
205 DBG_ASSERT( xImpPrMap
.is(), "There is no import prop mapper" );
208 Sequence
< PropertyValue
> aValues
;
209 xImpPrMap
->FillPropertySequence( maProperties
, aValues
);
211 sal_Int32 nLen
= aValues
.getLength();
214 if( GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH
)
216 aValues
.realloc( nLen
+ 2 );
217 PropertyValue
*pProps
= aValues
.getArray() + nLen
;
218 pProps
->Name
= rtl::OUString::createFromAscii("ParaStyleName");
219 OUString
sParent( GetParentName() );
220 if( sParent
.getLength() )
221 sParent
= GetImport().GetStyleDisplayName( GetFamily(), sParent
);
223 sParent
= rtl::OUString::createFromAscii("Standard");
224 pProps
->Value
<<= sParent
;
226 pProps
->Name
= rtl::OUString::createFromAscii("ParaConditionalStyleName");
227 pProps
->Value
<<= sParent
;
230 Reference
< XAutoStyle
> xAutoStyle
= xAutoFamily
->insertStyle( aValues
);
231 if( xAutoStyle
.is() )
233 Sequence
< OUString
> aPropNames(1);
234 aPropNames
[0] = GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH
?
235 rtl::OUString::createFromAscii("ParaAutoStyleName") :
236 rtl::OUString::createFromAscii("CharAutoStyleName");
237 Sequence
< Any
> aAny
= xAutoStyle
->getPropertyValues( aPropNames
);
238 if( aAny
.hasElements() )
242 SetAutoName( aName
);
250 const OUString
& rName
= GetDisplayName();
251 if( 0 == rName
.getLength() || IsDefaultStyle() )
254 Reference
< XNameContainer
> xFamilies
=
255 ((SvXMLStylesContext
*)&mxStyles
)->GetStylesContainer( GetFamily() );
256 if( !xFamilies
.is() )
259 sal_Bool bNew
= sal_False
;
260 if( xFamilies
->hasByName( rName
) )
262 Any aAny
= xFamilies
->getByName( rName
);
273 xFamilies
->insertByName( rName
, aAny
);
277 Reference
< XPropertySet
> xPropSet( mxStyle
, UNO_QUERY
);
278 Reference
< XPropertySetInfo
> xPropSetInfo
=
279 xPropSet
->getPropertySetInfo();
280 if( !bNew
&& xPropSetInfo
->hasPropertyByName( msIsPhysical
) )
282 Any aAny
= xPropSet
->getPropertyValue( msIsPhysical
);
283 bNew
= !*(sal_Bool
*)aAny
.getValue();
286 if( rName
!= GetName() )
287 GetImport().AddStyleDisplayName( GetFamily(), GetName(), rName
);
289 if( bOverwrite
|| bNew
)
291 Reference
< XPropertyState
> xPropState( xPropSet
, uno::UNO_QUERY
);
293 UniReference
< XMLPropertySetMapper
> xPrMap
;
294 UniReference
< SvXMLImportPropertyMapper
> xImpPrMap
=
295 ((SvXMLStylesContext
*)&mxStyles
)->GetImportPropertyMapper(
297 DBG_ASSERT( xImpPrMap
.is(), "There is the import prop mapper" );
299 xPrMap
= xImpPrMap
->getPropertySetMapper();
302 Reference
< XMultiPropertyStates
> xMultiStates( xPropSet
,
304 if( xMultiStates
.is() )
306 xMultiStates
->setAllPropertiesToDefault();
310 PropertyNameSet aNameSet
;
311 sal_Int32 nCount
= xPrMap
->GetEntryCount();
313 for( i
= 0; i
< nCount
; i
++ )
315 const OUString
& rPrName
= xPrMap
->GetEntryAPIName( i
);
316 if( xPropSetInfo
->hasPropertyByName( rPrName
) )
317 aNameSet
.insert( rPrName
);
320 nCount
= aNameSet
.size();
321 Sequence
< OUString
> aNames( nCount
);
322 OUString
*pNames
= aNames
.getArray();
323 PropertyNameSet::iterator aIter
= aNameSet
.begin();
324 while( aIter
!= aNameSet
.end() )
325 *pNames
++ = *aIter
++;
327 Sequence
< PropertyState
> aStates(
328 xPropState
->getPropertyStates( aNames
) );
329 const PropertyState
*pStates
= aStates
.getConstArray();
330 pNames
= aNames
.getArray();
332 for( i
= 0; i
< nCount
; i
++ )
334 if( PropertyState_DIRECT_VALUE
== *pStates
++ )
335 xPropState
->setPropertyToDefault( pNames
[i
] );
341 mxStyle
->setParentStyle(OUString());
343 FillPropertySet( xPropSet
);
347 SetValid( sal_False
);
352 void XMLPropStyleContext::Finish( sal_Bool bOverwrite
)
354 if( mxStyle
.is() && (IsNew() || bOverwrite
) )
356 // The families cintaner must exist
357 Reference
< XNameContainer
> xFamilies
=
358 ((SvXMLStylesContext
*)&mxStyles
)->GetStylesContainer( GetFamily() );
359 DBG_ASSERT( xFamilies
.is(), "Families lost" );
360 if( !xFamilies
.is() )
364 OUString
sParent( GetParentName() );
365 if( sParent
.getLength() )
366 sParent
= GetImport().GetStyleDisplayName( GetFamily(), sParent
);
367 if( sParent
.getLength() && !xFamilies
->hasByName( sParent
) )
368 sParent
= OUString();
370 if( sParent
!= mxStyle
->getParentStyle() )
372 // this may except if setting the parent style forms a
373 // circle in the style depencies; especially if the parent
374 // style is the same as the current style
377 mxStyle
->setParentStyle( sParent
);
379 catch( uno::Exception e
)
381 // according to the API definition, I would expect a
382 // container::NoSuchElementException. But it throws an
383 // uno::RuntimeException instead. I catch
384 // uno::Exception in order to process both of them.
386 // We can't set the parent style. For a proper
387 // Error-Message, we should pass in the name of the
388 // style, as well as the desired parent style.
389 Sequence
<OUString
> aSequence(2);
391 // getName() throws no non-Runtime exception:
392 aSequence
[0] = mxStyle
->getName();
393 aSequence
[1] = sParent
;
395 GetImport().SetError(
396 XMLERROR_FLAG_ERROR
| XMLERROR_PARENT_STYLE_NOT_ALLOWED
,
397 aSequence
, e
.Message
, NULL
);
402 OUString
sFollow( GetFollow() );
403 if( sFollow
.getLength() )
404 sFollow
= GetImport().GetStyleDisplayName( GetFamily(), sFollow
);
405 if( !sFollow
.getLength() || !xFamilies
->hasByName( sFollow
) )
406 sFollow
= mxStyle
->getName();
408 Reference
< XPropertySet
> xPropSet( mxStyle
, UNO_QUERY
);
409 Reference
< XPropertySetInfo
> xPropSetInfo
=
410 xPropSet
->getPropertySetInfo();
411 if( xPropSetInfo
->hasPropertyByName( msFollowStyle
) )
413 Any aAny
= xPropSet
->getPropertyValue( msFollowStyle
);
414 OUString sCurrFollow
;
415 aAny
>>= sCurrFollow
;
416 if( sCurrFollow
!= sFollow
)
419 xPropSet
->setPropertyValue( msFollowStyle
, aAny
);