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 27 28 #include <tools/debug.hxx> 29 #ifndef __SGI_STL_SET 30 #include <set> 31 #endif 32 #include "xmloff/xmlnmspe.hxx" 33 #include <xmloff/xmltoken.hxx> 34 #include <xmloff/xmlprcon.hxx> 35 #include <com/sun/star/style/XStyle.hpp> 36 #include <com/sun/star/style/XAutoStyleFamily.hpp> 37 #include <com/sun/star/container/XNameContainer.hpp> 38 #include <com/sun/star/beans/XPropertySet.hpp> 39 #include <com/sun/star/beans/XPropertyState.hpp> 40 #include <com/sun/star/beans/XMultiPropertyStates.hpp> 41 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 42 #include <xmloff/xmlimp.hxx> 43 44 #ifndef _XMLOFF_PRSTYLEI_HXX 45 #include <xmloff/prstylei.hxx> 46 #endif 47 #include <xmloff/attrlist.hxx> 48 #include "xmloff/xmlerror.hxx" 49 50 using ::rtl::OUString; 51 using ::rtl::OUStringBuffer; 52 53 using namespace ::com::sun::star; 54 using namespace ::com::sun::star::uno; 55 using namespace ::com::sun::star::xml::sax; 56 using namespace ::com::sun::star::style; 57 using namespace ::com::sun::star::container; 58 using namespace ::com::sun::star::beans; 59 using namespace ::com::sun::star::lang; 60 using namespace ::xmloff::token; 61 62 63 void XMLPropStyleContext::SetAttribute( sal_uInt16 nPrefixKey, 64 const OUString& rLocalName, 65 const OUString& rValue ) 66 { 67 if( XML_NAMESPACE_STYLE == nPrefixKey && IsXMLToken( rLocalName, XML_FAMILY ) ) 68 { 69 DBG_ASSERT( GetFamily() == ((SvXMLStylesContext *)&mxStyles)->GetFamily( rValue ), "unexpected style family" ); 70 } 71 else 72 { 73 SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue ); 74 } 75 } 76 77 TYPEINIT1( XMLPropStyleContext, SvXMLStyleContext ); 78 79 XMLPropStyleContext::XMLPropStyleContext( SvXMLImport& rImport, 80 sal_uInt16 nPrfx, const OUString& rLName, 81 const Reference< XAttributeList > & xAttrList, 82 SvXMLStylesContext& rStyles, sal_uInt16 nFamily, 83 sal_Bool bDefault ) 84 : SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList, nFamily, bDefault ) 85 , msIsPhysical( RTL_CONSTASCII_USTRINGPARAM( "IsPhysical" ) ) 86 , msFollowStyle( RTL_CONSTASCII_USTRINGPARAM( "FollowStyle" ) ) 87 , mxStyles( &rStyles ) 88 { 89 } 90 91 XMLPropStyleContext::~XMLPropStyleContext() 92 { 93 } 94 95 SvXMLImportContext *XMLPropStyleContext::CreateChildContext( 96 sal_uInt16 nPrefix, 97 const OUString& rLocalName, 98 const Reference< XAttributeList > & xAttrList ) 99 { 100 SvXMLImportContext *pContext = 0; 101 102 sal_uInt32 nFamily = 0; 103 if( XML_NAMESPACE_STYLE == nPrefix ) 104 { 105 if( IsXMLToken( rLocalName, XML_GRAPHIC_PROPERTIES ) ) 106 nFamily = XML_TYPE_PROP_GRAPHIC; 107 else if( IsXMLToken( rLocalName, XML_DRAWING_PAGE_PROPERTIES ) ) 108 nFamily = XML_TYPE_PROP_DRAWING_PAGE; 109 else if( IsXMLToken( rLocalName, XML_TEXT_PROPERTIES ) ) 110 nFamily = XML_TYPE_PROP_TEXT; 111 else if( IsXMLToken( rLocalName, XML_PARAGRAPH_PROPERTIES ) ) 112 nFamily = XML_TYPE_PROP_PARAGRAPH; 113 else if( IsXMLToken( rLocalName, XML_RUBY_PROPERTIES ) ) 114 nFamily = XML_TYPE_PROP_RUBY; 115 else if( IsXMLToken( rLocalName, XML_SECTION_PROPERTIES ) ) 116 nFamily = XML_TYPE_PROP_SECTION; 117 else if( IsXMLToken( rLocalName, XML_TABLE_PROPERTIES ) ) 118 nFamily = XML_TYPE_PROP_TABLE; 119 else if( IsXMLToken( rLocalName, XML_TABLE_COLUMN_PROPERTIES ) ) 120 nFamily = XML_TYPE_PROP_TABLE_COLUMN; 121 else if( IsXMLToken( rLocalName, XML_TABLE_ROW_PROPERTIES ) ) 122 nFamily = XML_TYPE_PROP_TABLE_ROW; 123 else if( IsXMLToken( rLocalName, XML_TABLE_CELL_PROPERTIES ) ) 124 nFamily = XML_TYPE_PROP_TABLE_CELL; 125 else if( IsXMLToken( rLocalName, XML_CHART_PROPERTIES ) ) 126 nFamily = XML_TYPE_PROP_CHART; 127 } 128 if( nFamily ) 129 { 130 UniReference < SvXMLImportPropertyMapper > xImpPrMap = 131 ((SvXMLStylesContext *)&mxStyles)->GetImportPropertyMapper( 132 GetFamily() ); 133 if( xImpPrMap.is() ) 134 pContext = new SvXMLPropertySetContext( GetImport(), nPrefix, 135 rLocalName, xAttrList, 136 nFamily, 137 maProperties, 138 xImpPrMap ); 139 } 140 141 if( !pContext ) 142 pContext = SvXMLStyleContext::CreateChildContext( nPrefix, rLocalName, 143 xAttrList ); 144 145 return pContext; 146 } 147 148 void XMLPropStyleContext::FillPropertySet( 149 const Reference< XPropertySet > & rPropSet ) 150 { 151 UniReference < SvXMLImportPropertyMapper > xImpPrMap = 152 ((SvXMLStylesContext *)&mxStyles)->GetImportPropertyMapper( 153 GetFamily() ); 154 DBG_ASSERT( xImpPrMap.is(), "There is the import prop mapper" ); 155 if( xImpPrMap.is() ) 156 xImpPrMap->FillPropertySet( maProperties, rPropSet ); 157 } 158 159 void XMLPropStyleContext::SetDefaults() 160 { 161 } 162 163 Reference < XStyle > XMLPropStyleContext::Create() 164 { 165 Reference < XStyle > xNewStyle; 166 167 OUString sServiceName( 168 ((SvXMLStylesContext *)&mxStyles)->GetServiceName( GetFamily() ) ); 169 if( sServiceName.getLength() ) 170 { 171 Reference< XMultiServiceFactory > xFactory( GetImport().GetModel(), 172 UNO_QUERY ); 173 if( xFactory.is() ) 174 { 175 Reference < XInterface > xIfc = 176 xFactory->createInstance( sServiceName ); 177 if( xIfc.is() ) 178 xNewStyle = Reference < XStyle >( xIfc, UNO_QUERY ); 179 } 180 } 181 182 return xNewStyle; 183 } 184 185 typedef ::std::set < OUString, ::comphelper::UStringLess > PropertyNameSet; 186 187 void XMLPropStyleContext::CreateAndInsert( sal_Bool bOverwrite ) 188 { 189 if( ((SvXMLStylesContext *)&mxStyles)->IsAutomaticStyle() 190 && ( GetFamily() == XML_STYLE_FAMILY_TEXT_TEXT || GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH ) ) 191 { 192 Reference < XAutoStyleFamily > xAutoFamily = 193 ((SvXMLStylesContext *)&mxStyles)->GetAutoStyles( GetFamily() ); 194 if( !xAutoFamily.is() ) 195 return; 196 UniReference < SvXMLImportPropertyMapper > xImpPrMap = 197 ((SvXMLStylesContext *)&mxStyles)->GetImportPropertyMapper( GetFamily() ); 198 DBG_ASSERT( xImpPrMap.is(), "There is no import prop mapper" ); 199 if( xImpPrMap.is() ) 200 { 201 Sequence< PropertyValue > aValues; 202 xImpPrMap->FillPropertySequence( maProperties, aValues ); 203 204 sal_Int32 nLen = aValues.getLength(); 205 if( nLen ) 206 { 207 if( GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH ) 208 { 209 aValues.realloc( nLen + 2 ); 210 PropertyValue *pProps = aValues.getArray() + nLen; 211 pProps->Name = rtl::OUString::createFromAscii("ParaStyleName"); 212 OUString sParent( GetParentName() ); 213 if( sParent.getLength() ) 214 sParent = GetImport().GetStyleDisplayName( GetFamily(), sParent ); 215 else 216 sParent = rtl::OUString::createFromAscii("Standard"); 217 pProps->Value <<= sParent; 218 ++pProps; 219 pProps->Name = rtl::OUString::createFromAscii("ParaConditionalStyleName"); 220 pProps->Value <<= sParent; 221 } 222 223 Reference < XAutoStyle > xAutoStyle = xAutoFamily->insertStyle( aValues ); 224 if( xAutoStyle.is() ) 225 { 226 Sequence< OUString > aPropNames(1); 227 aPropNames[0] = GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH ? 228 rtl::OUString::createFromAscii("ParaAutoStyleName") : 229 rtl::OUString::createFromAscii("CharAutoStyleName"); 230 Sequence< Any > aAny = xAutoStyle->getPropertyValues( aPropNames ); 231 if( aAny.hasElements() ) 232 { 233 OUString aName; 234 aAny[0] >>= aName; 235 SetAutoName( aName ); 236 } 237 } 238 } 239 } 240 } 241 else 242 { 243 const OUString& rName = GetDisplayName(); 244 if( 0 == rName.getLength() || IsDefaultStyle() ) 245 return; 246 247 Reference < XNameContainer > xFamilies = 248 ((SvXMLStylesContext *)&mxStyles)->GetStylesContainer( GetFamily() ); 249 if( !xFamilies.is() ) 250 return; 251 252 sal_Bool bNew = sal_False; 253 if( xFamilies->hasByName( rName ) ) 254 { 255 Any aAny = xFamilies->getByName( rName ); 256 aAny >>= mxStyle; 257 } 258 else 259 { 260 mxStyle = Create(); 261 if( !mxStyle.is() ) 262 return; 263 264 Any aAny; 265 aAny <<= mxStyle; 266 xFamilies->insertByName( rName, aAny ); 267 bNew = sal_True; 268 } 269 270 Reference < XPropertySet > xPropSet( mxStyle, UNO_QUERY ); 271 Reference< XPropertySetInfo > xPropSetInfo = 272 xPropSet->getPropertySetInfo(); 273 if( !bNew && xPropSetInfo->hasPropertyByName( msIsPhysical ) ) 274 { 275 Any aAny = xPropSet->getPropertyValue( msIsPhysical ); 276 bNew = !*(sal_Bool *)aAny.getValue(); 277 } 278 SetNew( bNew ); 279 if( rName != GetName() ) 280 GetImport().AddStyleDisplayName( GetFamily(), GetName(), rName ); 281 282 if( bOverwrite || bNew ) 283 { 284 Reference< XPropertyState > xPropState( xPropSet, uno::UNO_QUERY ); 285 286 UniReference < XMLPropertySetMapper > xPrMap; 287 UniReference < SvXMLImportPropertyMapper > xImpPrMap = 288 ((SvXMLStylesContext *)&mxStyles)->GetImportPropertyMapper( 289 GetFamily() ); 290 DBG_ASSERT( xImpPrMap.is(), "There is the import prop mapper" ); 291 if( xImpPrMap.is() ) 292 xPrMap = xImpPrMap->getPropertySetMapper(); 293 if( xPrMap.is() ) 294 { 295 Reference < XMultiPropertyStates > xMultiStates( xPropSet, 296 UNO_QUERY ); 297 if( xMultiStates.is() ) 298 { 299 xMultiStates->setAllPropertiesToDefault(); 300 } 301 else 302 { 303 PropertyNameSet aNameSet; 304 sal_Int32 nCount = xPrMap->GetEntryCount(); 305 sal_Int32 i; 306 for( i = 0; i < nCount; i++ ) 307 { 308 const OUString& rPrName = xPrMap->GetEntryAPIName( i ); 309 if( xPropSetInfo->hasPropertyByName( rPrName ) ) 310 aNameSet.insert( rPrName ); 311 } 312 313 nCount = aNameSet.size(); 314 Sequence < OUString > aNames( nCount ); 315 OUString *pNames = aNames.getArray(); 316 PropertyNameSet::iterator aIter = aNameSet.begin(); 317 while( aIter != aNameSet.end() ) 318 *pNames++ = *aIter++; 319 320 Sequence < PropertyState > aStates( 321 xPropState->getPropertyStates( aNames ) ); 322 const PropertyState *pStates = aStates.getConstArray(); 323 pNames = aNames.getArray(); 324 325 for( i = 0; i < nCount; i++ ) 326 { 327 if( PropertyState_DIRECT_VALUE == *pStates++ ) 328 xPropState->setPropertyToDefault( pNames[i] ); 329 } 330 } 331 } 332 333 if (mxStyle.is()) 334 mxStyle->setParentStyle(OUString()); 335 336 FillPropertySet( xPropSet ); 337 } 338 else 339 { 340 SetValid( sal_False ); 341 } 342 } 343 } 344 345 void XMLPropStyleContext::Finish( sal_Bool bOverwrite ) 346 { 347 if( mxStyle.is() && (IsNew() || bOverwrite) ) 348 { 349 // The families cintaner must exist 350 Reference < XNameContainer > xFamilies = 351 ((SvXMLStylesContext *)&mxStyles)->GetStylesContainer( GetFamily() ); 352 DBG_ASSERT( xFamilies.is(), "Families lost" ); 353 if( !xFamilies.is() ) 354 return; 355 356 // connect parent 357 OUString sParent( GetParentName() ); 358 if( sParent.getLength() ) 359 sParent = GetImport().GetStyleDisplayName( GetFamily(), sParent ); 360 if( sParent.getLength() && !xFamilies->hasByName( sParent ) ) 361 sParent = OUString(); 362 363 if( sParent != mxStyle->getParentStyle() ) 364 { 365 // this may except if setting the parent style forms a 366 // circle in the style depencies; especially if the parent 367 // style is the same as the current style 368 try 369 { 370 mxStyle->setParentStyle( sParent ); 371 } 372 catch( uno::Exception e ) 373 { 374 // according to the API definition, I would expect a 375 // container::NoSuchElementException. But it throws an 376 // uno::RuntimeException instead. I catch 377 // uno::Exception in order to process both of them. 378 379 // We can't set the parent style. For a proper 380 // Error-Message, we should pass in the name of the 381 // style, as well as the desired parent style. 382 Sequence<OUString> aSequence(2); 383 384 // getName() throws no non-Runtime exception: 385 aSequence[0] = mxStyle->getName(); 386 aSequence[1] = sParent; 387 388 GetImport().SetError( 389 XMLERROR_FLAG_ERROR | XMLERROR_PARENT_STYLE_NOT_ALLOWED, 390 aSequence, e.Message, NULL ); 391 } 392 } 393 394 // connect follow 395 OUString sFollow( GetFollow() ); 396 if( sFollow.getLength() ) 397 sFollow = GetImport().GetStyleDisplayName( GetFamily(), sFollow ); 398 if( !sFollow.getLength() || !xFamilies->hasByName( sFollow ) ) 399 sFollow = mxStyle->getName(); 400 401 Reference < XPropertySet > xPropSet( mxStyle, UNO_QUERY ); 402 Reference< XPropertySetInfo > xPropSetInfo = 403 xPropSet->getPropertySetInfo(); 404 if( xPropSetInfo->hasPropertyByName( msFollowStyle ) ) 405 { 406 Any aAny = xPropSet->getPropertyValue( msFollowStyle ); 407 OUString sCurrFollow; 408 aAny >>= sCurrFollow; 409 if( sCurrFollow != sFollow ) 410 { 411 aAny <<= sFollow; 412 xPropSet->setPropertyValue( msFollowStyle, aAny ); 413 } 414 } 415 } 416 } 417 418 419