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(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 //UUUU need to filter out old fill definitions when the new ones are used. The new 202 // ones are used when a FillStyle is defined 203 if(!m_bIsFillStyleAlreadyConverted && GetProperties().size()) 204 { 205 static ::rtl::OUString s_FillStyle(RTL_CONSTASCII_USTRINGPARAM("FillStyle")); 206 207 if(doNewDrawingLayerFillStyleDefinitionsExist(s_FillStyle)) 208 { 209 deactivateOldFillStyleDefinitions(getStandardSet()); 210 } 211 212 m_bIsFillStyleAlreadyConverted = true; 213 } 214 215 struct _ContextID_Index_Pair aContextIDs[] = 216 { 217 { CTF_DASHNAME , -1 }, 218 { CTF_LINESTARTNAME , -1 }, 219 { CTF_LINEENDNAME , -1 }, 220 { CTF_FILLGRADIENTNAME, -1 }, 221 { CTF_FILLTRANSNAME , -1 }, 222 { CTF_FILLHATCHNAME , -1 }, 223 { CTF_FILLBITMAPNAME , -1 }, 224 { CTF_SD_OLE_VIS_AREA_IMPORT_LEFT, -1 }, 225 { CTF_SD_OLE_VIS_AREA_IMPORT_TOP, -1 }, 226 { CTF_SD_OLE_VIS_AREA_IMPORT_WIDTH, -1 }, 227 { CTF_SD_OLE_VIS_AREA_IMPORT_HEIGHT, -1 }, 228 { -1, -1 } 229 }; 230 static sal_uInt16 aFamilies[] = 231 { 232 XML_STYLE_FAMILY_SD_STROKE_DASH_ID, 233 XML_STYLE_FAMILY_SD_MARKER_ID, 234 XML_STYLE_FAMILY_SD_MARKER_ID, 235 XML_STYLE_FAMILY_SD_GRADIENT_ID, 236 XML_STYLE_FAMILY_SD_GRADIENT_ID, 237 XML_STYLE_FAMILY_SD_HATCH_ID, 238 XML_STYLE_FAMILY_SD_FILL_IMAGE_ID 239 }; 240 241 UniReference < SvXMLImportPropertyMapper > xImpPrMap = 242 GetStyles()->GetImportPropertyMapper( GetFamily() ); 243 DBG_ASSERT( xImpPrMap.is(), "There is the import prop mapper" ); 244 if( xImpPrMap.is() ) 245 xImpPrMap->FillPropertySet( GetProperties(), rPropSet, aContextIDs ); 246 247 Reference< XPropertySetInfo > xInfo; 248 // get property set mapper 249 UniReference<XMLPropertySetMapper> xPropMapper( xImpPrMap->getPropertySetMapper() ); 250 251 for( sal_uInt16 i=0; aContextIDs[i].nContextID != -1; i++ ) 252 { 253 sal_Int32 nIndex = aContextIDs[i].nIndex; 254 if( nIndex != -1 ) switch( aContextIDs[i].nContextID ) 255 { 256 case CTF_DASHNAME: 257 case CTF_LINESTARTNAME: 258 case CTF_LINEENDNAME: 259 case CTF_FILLGRADIENTNAME: 260 case CTF_FILLTRANSNAME: 261 case CTF_FILLHATCHNAME: 262 case CTF_FILLBITMAPNAME: 263 { 264 struct XMLPropertyState& rState = GetProperties()[nIndex]; 265 OUString sStyleName; 266 rState.maValue >>= sStyleName; 267 sStyleName = GetImport().GetStyleDisplayName( aFamilies[i], sStyleName ); 268 try 269 { 270 271 // set property 272 const OUString& rPropertyName = xPropMapper->GetEntryAPIName(rState.mnIndex); 273 if( !xInfo.is() ) 274 xInfo = rPropSet->getPropertySetInfo(); 275 if ( xInfo->hasPropertyByName( rPropertyName ) ) 276 { 277 rPropSet->setPropertyValue( rPropertyName, Any( sStyleName ) ); 278 } 279 } 280 catch ( ::com::sun::star::lang::IllegalArgumentException& e ) 281 { 282 Sequence<OUString> aSeq(1); 283 aSeq[0] = sStyleName; 284 GetImport().SetError( 285 XMLERROR_STYLE_PROP_VALUE | XMLERROR_FLAG_WARNING, 286 aSeq, e.Message, NULL ); 287 } 288 break; 289 } 290 case CTF_SD_OLE_VIS_AREA_IMPORT_LEFT: 291 case CTF_SD_OLE_VIS_AREA_IMPORT_TOP: 292 case CTF_SD_OLE_VIS_AREA_IMPORT_WIDTH: 293 case CTF_SD_OLE_VIS_AREA_IMPORT_HEIGHT: 294 { 295 struct XMLPropertyState& rState = GetProperties()[nIndex]; 296 const OUString& rPropertyName = xPropMapper->GetEntryAPIName(rState.mnIndex); 297 try 298 { 299 if( !xInfo.is() ) 300 xInfo = rPropSet->getPropertySetInfo(); 301 if ( xInfo->hasPropertyByName( rPropertyName ) ) 302 { 303 rPropSet->setPropertyValue( rPropertyName, rState.maValue ); 304 } 305 } 306 catch ( ::com::sun::star::lang::IllegalArgumentException& e ) 307 { 308 Sequence<OUString> aSeq; 309 GetImport().SetError( 310 XMLERROR_STYLE_PROP_VALUE | XMLERROR_FLAG_WARNING, 311 aSeq, e.Message, NULL ); 312 } 313 break; 314 } 315 } 316 } 317 318 if (m_sControlDataStyleName.getLength()) 319 { // we had a data-style-name attribute 320 321 // set the formatting on the control model of the control shape 322 uno::Reference< drawing::XControlShape > xControlShape(rPropSet, uno::UNO_QUERY); 323 DBG_ASSERT(xControlShape.is(), "XMLShapeStyleContext::FillPropertySet: data style for a non-control shape!"); 324 if (xControlShape.is()) 325 { 326 uno::Reference< beans::XPropertySet > xControlModel(xControlShape->getControl(), uno::UNO_QUERY); 327 DBG_ASSERT(xControlModel.is(), "XMLShapeStyleContext::FillPropertySet: no control model for the shape!"); 328 if (xControlModel.is()) 329 { 330 GetImport().GetFormImport()->applyControlNumberStyle(xControlModel, m_sControlDataStyleName); 331 } 332 } 333 } 334 } 335 336 void XMLShapeStyleContext::Finish( sal_Bool /*bOverwrite*/ ) 337 { 338 } 339