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 #include <tools/debug.hxx> 28 #include <xmloff/XMLShapeStyleContext.hxx> 29 #include "XMLShapePropertySetContext.hxx" 30 #include <xmloff/contextid.hxx> 31 #include <com/sun/star/drawing/XControlShape.hpp> 32 #include "com/sun/star/beans/XPropertySetInfo.hpp" 33 #include <com/sun/star/lang/IllegalArgumentException.hpp> 34 #include <com/sun/star/drawing/FillStyle.hpp> 35 #include <xmloff/xmlimp.hxx> 36 #include <xmloff/xmlnumi.hxx> 37 #include <xmloff/xmlnmspe.hxx> 38 #include <xmloff/xmltoken.hxx> 39 #include "xmloff/xmlerror.hxx" 40 #include <xmloff/maptype.hxx> 41 42 #include "sdpropls.hxx" 43 44 using ::rtl::OUString; 45 using ::rtl::OUStringBuffer; 46 47 using namespace ::com::sun::star; 48 using namespace ::com::sun::star::uno; 49 using namespace ::com::sun::star::beans; 50 using namespace ::com::sun::star::drawing; 51 using ::xmloff::token::IsXMLToken; 52 using ::xmloff::token::XML_TEXT_PROPERTIES; 53 using ::xmloff::token::XML_GRAPHIC_PROPERTIES; 54 using ::xmloff::token::XML_PARAGRAPH_PROPERTIES; 55 56 ////////////////////////////////////////////////////////////////////////////// 57 58 TYPEINIT1( XMLShapeStyleContext, XMLPropStyleContext ); 59 60 XMLShapeStyleContext::XMLShapeStyleContext( 61 SvXMLImport& rImport, 62 sal_uInt16 nPrfx, 63 const OUString& rLName, 64 const uno::Reference< xml::sax::XAttributeList >& xAttrList, 65 SvXMLStylesContext& rStyles, 66 sal_uInt16 nFamily) 67 : XMLPropStyleContext(rImport, nPrfx, rLName, xAttrList, rStyles, nFamily ), 68 m_bIsNumRuleAlreadyConverted( sal_False ), 69 m_bIsFillStyleAlreadyConverted( sal_False ) //UUUU 70 { 71 } 72 73 XMLShapeStyleContext::~XMLShapeStyleContext() 74 { 75 } 76 77 void XMLShapeStyleContext::SetAttribute( sal_uInt16 nPrefixKey, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue ) 78 { 79 if ((0 == m_sControlDataStyleName.getLength()) && (::xmloff::token::GetXMLToken(::xmloff::token::XML_DATA_STYLE_NAME) == rLocalName)) 80 { 81 m_sControlDataStyleName = rValue; 82 } 83 else if( (XML_NAMESPACE_STYLE == nPrefixKey) && IsXMLToken( rLocalName, ::xmloff::token::XML_LIST_STYLE_NAME ) ) 84 { 85 m_sListStyleName = rValue; 86 } 87 else 88 { 89 XMLPropStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue ); 90 91 if( (XML_NAMESPACE_STYLE == nPrefixKey) && 92 ( IsXMLToken( rLocalName, ::xmloff::token::XML_NAME ) || IsXMLToken( rLocalName, ::xmloff::token::XML_DISPLAY_NAME ) ) ) 93 { 94 if( GetName().getLength() && GetDisplayName().getLength() && GetName() != GetDisplayName() ) 95 { 96 const_cast< SvXMLImport&>( GetImport() ). 97 AddStyleDisplayName( GetFamily(), GetName(), GetDisplayName() ); 98 } 99 } 100 } 101 } 102 103 SvXMLImportContext *XMLShapeStyleContext::CreateChildContext( 104 sal_uInt16 nPrefix, 105 const OUString& rLocalName, 106 const Reference< xml::sax::XAttributeList > & xAttrList ) 107 { 108 SvXMLImportContext *pContext = 0; 109 110 if( XML_NAMESPACE_STYLE == nPrefix ) 111 { 112 sal_uInt32 nFamily = 0; 113 if( IsXMLToken( rLocalName, XML_TEXT_PROPERTIES ) ) 114 nFamily = XML_TYPE_PROP_TEXT; 115 else if( IsXMLToken( rLocalName, XML_PARAGRAPH_PROPERTIES ) ) 116 nFamily = XML_TYPE_PROP_PARAGRAPH; 117 else if( IsXMLToken( rLocalName, XML_GRAPHIC_PROPERTIES ) ) 118 nFamily = XML_TYPE_PROP_GRAPHIC; 119 if( nFamily ) 120 { 121 UniReference < SvXMLImportPropertyMapper > xImpPrMap = 122 GetStyles()->GetImportPropertyMapper( GetFamily() ); 123 if( xImpPrMap.is() ) 124 pContext = new XMLShapePropertySetContext( GetImport(), nPrefix, 125 rLocalName, xAttrList, 126 nFamily, 127 GetProperties(), 128 xImpPrMap ); 129 } 130 } 131 132 if( !pContext ) 133 pContext = XMLPropStyleContext::CreateChildContext( nPrefix, rLocalName, 134 xAttrList ); 135 136 return pContext; 137 } 138 139 void XMLShapeStyleContext::FillPropertySet( const Reference< beans::XPropertySet > & rPropSet ) 140 { 141 if( !m_bIsNumRuleAlreadyConverted ) 142 { 143 m_bIsNumRuleAlreadyConverted = sal_True; 144 145 // for compatibility to beta files, search for CTF_SD_NUMBERINGRULES_NAME to 146 // import numbering rules from the style:properties element 147 const UniReference< XMLPropertySetMapper >&rMapper = GetStyles()->GetImportPropertyMapper( GetFamily() )->getPropertySetMapper(); 148 149 ::std::vector< XMLPropertyState > &rProperties = GetProperties(); 150 ::std::vector< XMLPropertyState >::iterator end( rProperties.end() ); 151 ::std::vector< XMLPropertyState >::iterator property; 152 153 // first, look for the old format, where we had a text:list-style-name 154 // attribute in the style:properties element 155 for( property = rProperties.begin(); property != end; property++ ) 156 { 157 // find properties with context 158 if( (property->mnIndex != -1) && (rMapper->GetEntryContextId( property->mnIndex ) == CTF_SD_NUMBERINGRULES_NAME) ) 159 break; 160 } 161 162 // if we did not find an old list-style-name in the properties, and we need one 163 // because we got a style:list-style attribute in the style-style element 164 // we generate one 165 if( (property == end) && ( 0 != m_sListStyleName.getLength() ) ) 166 { 167 sal_Int32 nIndex = rMapper->FindEntryIndex( CTF_SD_NUMBERINGRULES_NAME ); 168 DBG_ASSERT( -1 != nIndex, "can't find numbering rules property entry, can't set numbering rule!" ); 169 170 XMLPropertyState aNewState( nIndex ); 171 rProperties.push_back( aNewState ); 172 end = rProperties.end(); 173 property = end - 1; 174 } 175 176 // so, if we have an old or a new list style name, we set its value to 177 // a numbering rule 178 if( property != end ) 179 { 180 if( 0 == m_sListStyleName.getLength() ) 181 { 182 property->maValue >>= m_sListStyleName; 183 } 184 185 const SvxXMLListStyleContext *pListStyle = GetImport().GetTextImport()->FindAutoListStyle( m_sListStyleName ); 186 187 DBG_ASSERT( pListStyle, "list-style not found for shape style" ); 188 if( pListStyle ) 189 { 190 uno::Reference< container::XIndexReplace > xNumRule( pListStyle->CreateNumRule( GetImport().GetModel() ) ); 191 pListStyle->FillUnoNumRule(xNumRule, NULL /* const SvI18NMap * ??? */ ); 192 property->maValue <<= xNumRule; 193 } 194 else 195 { 196 property->mnIndex = -1; 197 } 198 } 199 } 200 201 if(!m_bIsFillStyleAlreadyConverted && GetProperties().size()) 202 { 203 const UniReference< XMLPropertySetMapper >&rMapper = GetStyles()->GetImportPropertyMapper(GetFamily())->getPropertySetMapper(); 204 ::std::vector< XMLPropertyState >& rProperties = GetProperties(); 205 ::std::vector< XMLPropertyState >::iterator a; 206 FillStyle eFS(FillStyle_NONE); 207 static ::rtl::OUString s_FillStyle(RTL_CONSTASCII_USTRINGPARAM("FillStyle")); 208 209 // try to find a FillStyle entry and a value from it 210 for(a = rProperties.begin(); a != rProperties.end(); a++) 211 { 212 if(a->mnIndex != -1) 213 { 214 const OUString& rPropName = rMapper->GetEntryAPIName(a->mnIndex); 215 216 if(rPropName == s_FillStyle) 217 { 218 if(a->maValue >>= eFS) 219 { 220 // okay, type was good, eFS is set 221 } 222 else 223 { 224 // also try an int (see XFillStyleItem::PutValue) 225 sal_Int32 nFS = 0; 226 227 if(a->maValue >>= nFS) 228 { 229 eFS = (FillStyle)nFS; 230 } 231 } 232 233 // exit loop, we found out what we needed to know 234 break; 235 } 236 } 237 } 238 239 if(FillStyle_NONE != eFS) 240 { 241 //UUUU a FillStyle was found, thus the new [XATTR_FILL_FIRST .. XATTR_FILL_LAST] 242 // description for the Fill definitions is used. All formally used props based 243 // on RES_BACKGROUND need to be deleted to get no conflicts between the two 244 // sets of properties; old files will keep these and adapt accordingly 245 static ::rtl::OUString s_BackColorRGB(RTL_CONSTASCII_USTRINGPARAM("BackColorRGB")); 246 static ::rtl::OUString s_BackTransparent(RTL_CONSTASCII_USTRINGPARAM("BackTransparent")); 247 static ::rtl::OUString s_BackColorTransparency(RTL_CONSTASCII_USTRINGPARAM("BackColorTransparency")); 248 static ::rtl::OUString s_BackGraphicURL(RTL_CONSTASCII_USTRINGPARAM("BackGraphicURL")); 249 static ::rtl::OUString s_BackGraphicFilter(RTL_CONSTASCII_USTRINGPARAM("BackGraphicFilter")); 250 static ::rtl::OUString s_BackGraphicLocation(RTL_CONSTASCII_USTRINGPARAM("BackGraphicLocation")); 251 static ::rtl::OUString s_BackGraphicTransparency(RTL_CONSTASCII_USTRINGPARAM("BackGraphicTransparency")); 252 253 for(a = rProperties.begin(); a != rProperties.end(); a++) 254 { 255 if(a->mnIndex != -1) 256 { 257 const OUString& rPropName = rMapper->GetEntryAPIName(a->mnIndex); 258 259 if(s_BackColorRGB == rPropName 260 || s_BackTransparent == rPropName 261 || s_BackColorTransparency == rPropName 262 || s_BackGraphicURL == rPropName 263 || s_BackGraphicFilter == rPropName 264 || s_BackGraphicLocation == rPropName 265 || s_BackGraphicTransparency== rPropName) 266 { 267 // mark entry as inactive 268 a->mnIndex = -1; 269 } 270 } 271 } 272 } 273 274 m_bIsFillStyleAlreadyConverted = sal_True; 275 } 276 277 struct _ContextID_Index_Pair aContextIDs[] = 278 { 279 { CTF_DASHNAME , -1 }, 280 { CTF_LINESTARTNAME , -1 }, 281 { CTF_LINEENDNAME , -1 }, 282 { CTF_FILLGRADIENTNAME, -1 }, 283 { CTF_FILLTRANSNAME , -1 }, 284 { CTF_FILLHATCHNAME , -1 }, 285 { CTF_FILLBITMAPNAME , -1 }, 286 { CTF_SD_OLE_VIS_AREA_IMPORT_LEFT, -1 }, 287 { CTF_SD_OLE_VIS_AREA_IMPORT_TOP, -1 }, 288 { CTF_SD_OLE_VIS_AREA_IMPORT_WIDTH, -1 }, 289 { CTF_SD_OLE_VIS_AREA_IMPORT_HEIGHT, -1 }, 290 { -1, -1 } 291 }; 292 static sal_uInt16 aFamilies[] = 293 { 294 XML_STYLE_FAMILY_SD_STROKE_DASH_ID, 295 XML_STYLE_FAMILY_SD_MARKER_ID, 296 XML_STYLE_FAMILY_SD_MARKER_ID, 297 XML_STYLE_FAMILY_SD_GRADIENT_ID, 298 XML_STYLE_FAMILY_SD_GRADIENT_ID, 299 XML_STYLE_FAMILY_SD_HATCH_ID, 300 XML_STYLE_FAMILY_SD_FILL_IMAGE_ID 301 }; 302 303 UniReference < SvXMLImportPropertyMapper > xImpPrMap = 304 GetStyles()->GetImportPropertyMapper( GetFamily() ); 305 DBG_ASSERT( xImpPrMap.is(), "There is the import prop mapper" ); 306 if( xImpPrMap.is() ) 307 xImpPrMap->FillPropertySet( GetProperties(), rPropSet, aContextIDs ); 308 309 Reference< XPropertySetInfo > xInfo; 310 // get property set mapper 311 UniReference<XMLPropertySetMapper> xPropMapper( xImpPrMap->getPropertySetMapper() ); 312 313 for( sal_uInt16 i=0; aContextIDs[i].nContextID != -1; i++ ) 314 { 315 sal_Int32 nIndex = aContextIDs[i].nIndex; 316 if( nIndex != -1 ) switch( aContextIDs[i].nContextID ) 317 { 318 case CTF_DASHNAME: 319 case CTF_LINESTARTNAME: 320 case CTF_LINEENDNAME: 321 case CTF_FILLGRADIENTNAME: 322 case CTF_FILLTRANSNAME: 323 case CTF_FILLHATCHNAME: 324 case CTF_FILLBITMAPNAME: 325 { 326 struct XMLPropertyState& rState = GetProperties()[nIndex]; 327 OUString sStyleName; 328 rState.maValue >>= sStyleName; 329 sStyleName = GetImport().GetStyleDisplayName( aFamilies[i], sStyleName ); 330 try 331 { 332 333 // set property 334 const OUString& rPropertyName = xPropMapper->GetEntryAPIName(rState.mnIndex); 335 if( !xInfo.is() ) 336 xInfo = rPropSet->getPropertySetInfo(); 337 if ( xInfo->hasPropertyByName( rPropertyName ) ) 338 { 339 rPropSet->setPropertyValue( rPropertyName, Any( sStyleName ) ); 340 } 341 } 342 catch ( ::com::sun::star::lang::IllegalArgumentException& e ) 343 { 344 Sequence<OUString> aSeq(1); 345 aSeq[0] = sStyleName; 346 GetImport().SetError( 347 XMLERROR_STYLE_PROP_VALUE | XMLERROR_FLAG_WARNING, 348 aSeq, e.Message, NULL ); 349 } 350 break; 351 } 352 case CTF_SD_OLE_VIS_AREA_IMPORT_LEFT: 353 case CTF_SD_OLE_VIS_AREA_IMPORT_TOP: 354 case CTF_SD_OLE_VIS_AREA_IMPORT_WIDTH: 355 case CTF_SD_OLE_VIS_AREA_IMPORT_HEIGHT: 356 { 357 struct XMLPropertyState& rState = GetProperties()[nIndex]; 358 const OUString& rPropertyName = xPropMapper->GetEntryAPIName(rState.mnIndex); 359 try 360 { 361 if( !xInfo.is() ) 362 xInfo = rPropSet->getPropertySetInfo(); 363 if ( xInfo->hasPropertyByName( rPropertyName ) ) 364 { 365 rPropSet->setPropertyValue( rPropertyName, rState.maValue ); 366 } 367 } 368 catch ( ::com::sun::star::lang::IllegalArgumentException& e ) 369 { 370 Sequence<OUString> aSeq; 371 GetImport().SetError( 372 XMLERROR_STYLE_PROP_VALUE | XMLERROR_FLAG_WARNING, 373 aSeq, e.Message, NULL ); 374 } 375 break; 376 } 377 } 378 } 379 380 if (m_sControlDataStyleName.getLength()) 381 { // we had a data-style-name attribute 382 383 // set the formatting on the control model of the control shape 384 uno::Reference< drawing::XControlShape > xControlShape(rPropSet, uno::UNO_QUERY); 385 DBG_ASSERT(xControlShape.is(), "XMLShapeStyleContext::FillPropertySet: data style for a non-control shape!"); 386 if (xControlShape.is()) 387 { 388 uno::Reference< beans::XPropertySet > xControlModel(xControlShape->getControl(), uno::UNO_QUERY); 389 DBG_ASSERT(xControlModel.is(), "XMLShapeStyleContext::FillPropertySet: no control model for the shape!"); 390 if (xControlModel.is()) 391 { 392 GetImport().GetFormImport()->applyControlNumberStyle(xControlModel, m_sControlDataStyleName); 393 } 394 } 395 } 396 } 397 398 void XMLShapeStyleContext::Finish( sal_Bool /*bOverwrite*/ ) 399 { 400 } 401 402