1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_xmloff.hxx" 30 31 #include <tools/debug.hxx> 32 #include <xmloff/XMLShapeStyleContext.hxx> 33 #include "XMLShapePropertySetContext.hxx" 34 #include <xmloff/contextid.hxx> 35 #include <com/sun/star/drawing/XControlShape.hpp> 36 #include "com/sun/star/beans/XPropertySetInfo.hpp" 37 #include <com/sun/star/lang/IllegalArgumentException.hpp> 38 #include <xmloff/xmlimp.hxx> 39 #include <xmloff/xmlnumi.hxx> 40 #include <xmloff/xmlnmspe.hxx> 41 #include <xmloff/xmltoken.hxx> 42 #include "xmloff/xmlerror.hxx" 43 #include <xmloff/maptype.hxx> 44 45 #include "sdpropls.hxx" 46 47 using ::rtl::OUString; 48 using ::rtl::OUStringBuffer; 49 50 using namespace ::com::sun::star; 51 using namespace ::com::sun::star::uno; 52 using namespace ::com::sun::star::beans; 53 using ::xmloff::token::IsXMLToken; 54 using ::xmloff::token::XML_TEXT_PROPERTIES; 55 using ::xmloff::token::XML_GRAPHIC_PROPERTIES; 56 using ::xmloff::token::XML_PARAGRAPH_PROPERTIES; 57 58 ////////////////////////////////////////////////////////////////////////////// 59 60 TYPEINIT1( XMLShapeStyleContext, XMLPropStyleContext ); 61 62 XMLShapeStyleContext::XMLShapeStyleContext( 63 SvXMLImport& rImport, 64 sal_uInt16 nPrfx, 65 const OUString& rLName, 66 const uno::Reference< xml::sax::XAttributeList >& xAttrList, 67 SvXMLStylesContext& rStyles, 68 sal_uInt16 nFamily) 69 : XMLPropStyleContext(rImport, nPrfx, rLName, xAttrList, rStyles, nFamily ), 70 m_bIsNumRuleAlreadyConverted( sal_False ) 71 { 72 } 73 74 XMLShapeStyleContext::~XMLShapeStyleContext() 75 { 76 } 77 78 void XMLShapeStyleContext::SetAttribute( sal_uInt16 nPrefixKey, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue ) 79 { 80 if ((0 == m_sControlDataStyleName.getLength()) && (::xmloff::token::GetXMLToken(::xmloff::token::XML_DATA_STYLE_NAME) == rLocalName)) 81 { 82 m_sControlDataStyleName = rValue; 83 } 84 else if( (XML_NAMESPACE_STYLE == nPrefixKey) && IsXMLToken( rLocalName, ::xmloff::token::XML_LIST_STYLE_NAME ) ) 85 { 86 m_sListStyleName = rValue; 87 } 88 else 89 { 90 XMLPropStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue ); 91 92 if( (XML_NAMESPACE_STYLE == nPrefixKey) && 93 ( IsXMLToken( rLocalName, ::xmloff::token::XML_NAME ) || IsXMLToken( rLocalName, ::xmloff::token::XML_DISPLAY_NAME ) ) ) 94 { 95 if( GetName().getLength() && GetDisplayName().getLength() && GetName() != GetDisplayName() ) 96 { 97 const_cast< SvXMLImport&>( GetImport() ). 98 AddStyleDisplayName( GetFamily(), GetName(), GetDisplayName() ); 99 } 100 } 101 } 102 } 103 104 SvXMLImportContext *XMLShapeStyleContext::CreateChildContext( 105 sal_uInt16 nPrefix, 106 const OUString& rLocalName, 107 const Reference< xml::sax::XAttributeList > & xAttrList ) 108 { 109 SvXMLImportContext *pContext = 0; 110 111 if( XML_NAMESPACE_STYLE == nPrefix ) 112 { 113 sal_uInt32 nFamily = 0; 114 if( IsXMLToken( rLocalName, XML_TEXT_PROPERTIES ) ) 115 nFamily = XML_TYPE_PROP_TEXT; 116 else if( IsXMLToken( rLocalName, XML_PARAGRAPH_PROPERTIES ) ) 117 nFamily = XML_TYPE_PROP_PARAGRAPH; 118 else if( IsXMLToken( rLocalName, XML_GRAPHIC_PROPERTIES ) ) 119 nFamily = XML_TYPE_PROP_GRAPHIC; 120 if( nFamily ) 121 { 122 UniReference < SvXMLImportPropertyMapper > xImpPrMap = 123 GetStyles()->GetImportPropertyMapper( GetFamily() ); 124 if( xImpPrMap.is() ) 125 pContext = new XMLShapePropertySetContext( GetImport(), nPrefix, 126 rLocalName, xAttrList, 127 nFamily, 128 GetProperties(), 129 xImpPrMap ); 130 } 131 } 132 133 if( !pContext ) 134 pContext = XMLPropStyleContext::CreateChildContext( nPrefix, rLocalName, 135 xAttrList ); 136 137 return pContext; 138 } 139 140 void XMLShapeStyleContext::FillPropertySet( const Reference< beans::XPropertySet > & rPropSet ) 141 { 142 if( !m_bIsNumRuleAlreadyConverted ) 143 { 144 m_bIsNumRuleAlreadyConverted = sal_True; 145 146 // for compatibility to beta files, search for CTF_SD_NUMBERINGRULES_NAME to 147 // import numbering rules from the style:properties element 148 const UniReference< XMLPropertySetMapper >&rMapper = GetStyles()->GetImportPropertyMapper( GetFamily() )->getPropertySetMapper(); 149 150 ::std::vector< XMLPropertyState > &rProperties = GetProperties(); 151 ::std::vector< XMLPropertyState >::iterator end( rProperties.end() ); 152 ::std::vector< XMLPropertyState >::iterator property; 153 154 // first, look for the old format, where we had a text:list-style-name 155 // attribute in the style:properties element 156 for( property = rProperties.begin(); property != end; property++ ) 157 { 158 // find properties with context 159 if( (property->mnIndex != -1) && (rMapper->GetEntryContextId( property->mnIndex ) == CTF_SD_NUMBERINGRULES_NAME) ) 160 break; 161 } 162 163 // if we did not find an old list-style-name in the properties, and we need one 164 // because we got a style:list-style attribute in the style-style element 165 // we generate one 166 if( (property == end) && ( 0 != m_sListStyleName.getLength() ) ) 167 { 168 sal_Int32 nIndex = rMapper->FindEntryIndex( CTF_SD_NUMBERINGRULES_NAME ); 169 DBG_ASSERT( -1 != nIndex, "can't find numbering rules property entry, can't set numbering rule!" ); 170 171 XMLPropertyState aNewState( nIndex ); 172 rProperties.push_back( aNewState ); 173 end = rProperties.end(); 174 property = end - 1; 175 } 176 177 // so, if we have an old or a new list style name, we set its value to 178 // a numbering rule 179 if( property != end ) 180 { 181 if( 0 == m_sListStyleName.getLength() ) 182 { 183 property->maValue >>= m_sListStyleName; 184 } 185 186 const SvxXMLListStyleContext *pListStyle = GetImport().GetTextImport()->FindAutoListStyle( m_sListStyleName ); 187 188 DBG_ASSERT( pListStyle, "list-style not found for shape style" ); 189 if( pListStyle ) 190 { 191 uno::Reference< container::XIndexReplace > xNumRule( pListStyle->CreateNumRule( GetImport().GetModel() ) ); 192 pListStyle->FillUnoNumRule(xNumRule, NULL /* const SvI18NMap * ??? */ ); 193 property->maValue <<= xNumRule; 194 } 195 else 196 { 197 property->mnIndex = -1; 198 } 199 } 200 } 201 202 struct _ContextID_Index_Pair aContextIDs[] = 203 { 204 { CTF_DASHNAME , -1 }, 205 { CTF_LINESTARTNAME , -1 }, 206 { CTF_LINEENDNAME , -1 }, 207 { CTF_FILLGRADIENTNAME, -1 }, 208 { CTF_FILLTRANSNAME , -1 }, 209 { CTF_FILLHATCHNAME , -1 }, 210 { CTF_FILLBITMAPNAME , -1 }, 211 { CTF_SD_OLE_VIS_AREA_IMPORT_LEFT, -1 }, 212 { CTF_SD_OLE_VIS_AREA_IMPORT_TOP, -1 }, 213 { CTF_SD_OLE_VIS_AREA_IMPORT_WIDTH, -1 }, 214 { CTF_SD_OLE_VIS_AREA_IMPORT_HEIGHT, -1 }, 215 { -1, -1 } 216 }; 217 static sal_uInt16 aFamilies[] = 218 { 219 XML_STYLE_FAMILY_SD_STROKE_DASH_ID, 220 XML_STYLE_FAMILY_SD_MARKER_ID, 221 XML_STYLE_FAMILY_SD_MARKER_ID, 222 XML_STYLE_FAMILY_SD_GRADIENT_ID, 223 XML_STYLE_FAMILY_SD_GRADIENT_ID, 224 XML_STYLE_FAMILY_SD_HATCH_ID, 225 XML_STYLE_FAMILY_SD_FILL_IMAGE_ID 226 }; 227 228 UniReference < SvXMLImportPropertyMapper > xImpPrMap = 229 GetStyles()->GetImportPropertyMapper( GetFamily() ); 230 DBG_ASSERT( xImpPrMap.is(), "There is the import prop mapper" ); 231 if( xImpPrMap.is() ) 232 xImpPrMap->FillPropertySet( GetProperties(), rPropSet, aContextIDs ); 233 234 Reference< XPropertySetInfo > xInfo; 235 // get property set mapper 236 UniReference<XMLPropertySetMapper> xPropMapper( xImpPrMap->getPropertySetMapper() ); 237 238 for( sal_uInt16 i=0; aContextIDs[i].nContextID != -1; i++ ) 239 { 240 sal_Int32 nIndex = aContextIDs[i].nIndex; 241 if( nIndex != -1 ) switch( aContextIDs[i].nContextID ) 242 { 243 case CTF_DASHNAME: 244 case CTF_LINESTARTNAME: 245 case CTF_LINEENDNAME: 246 case CTF_FILLGRADIENTNAME: 247 case CTF_FILLTRANSNAME: 248 case CTF_FILLHATCHNAME: 249 case CTF_FILLBITMAPNAME: 250 { 251 struct XMLPropertyState& rState = GetProperties()[nIndex]; 252 OUString sStyleName; 253 rState.maValue >>= sStyleName; 254 sStyleName = GetImport().GetStyleDisplayName( aFamilies[i], sStyleName ); 255 try 256 { 257 258 // set property 259 const OUString& rPropertyName = xPropMapper->GetEntryAPIName(rState.mnIndex); 260 if( !xInfo.is() ) 261 xInfo = rPropSet->getPropertySetInfo(); 262 if ( xInfo->hasPropertyByName( rPropertyName ) ) 263 { 264 rPropSet->setPropertyValue( rPropertyName, Any( sStyleName ) ); 265 } 266 } 267 catch ( ::com::sun::star::lang::IllegalArgumentException& e ) 268 { 269 Sequence<OUString> aSeq(1); 270 aSeq[0] = sStyleName; 271 GetImport().SetError( 272 XMLERROR_STYLE_PROP_VALUE | XMLERROR_FLAG_WARNING, 273 aSeq, e.Message, NULL ); 274 } 275 break; 276 } 277 case CTF_SD_OLE_VIS_AREA_IMPORT_LEFT: 278 case CTF_SD_OLE_VIS_AREA_IMPORT_TOP: 279 case CTF_SD_OLE_VIS_AREA_IMPORT_WIDTH: 280 case CTF_SD_OLE_VIS_AREA_IMPORT_HEIGHT: 281 { 282 struct XMLPropertyState& rState = GetProperties()[nIndex]; 283 const OUString& rPropertyName = xPropMapper->GetEntryAPIName(rState.mnIndex); 284 try 285 { 286 if( !xInfo.is() ) 287 xInfo = rPropSet->getPropertySetInfo(); 288 if ( xInfo->hasPropertyByName( rPropertyName ) ) 289 { 290 rPropSet->setPropertyValue( rPropertyName, rState.maValue ); 291 } 292 } 293 catch ( ::com::sun::star::lang::IllegalArgumentException& e ) 294 { 295 Sequence<OUString> aSeq; 296 GetImport().SetError( 297 XMLERROR_STYLE_PROP_VALUE | XMLERROR_FLAG_WARNING, 298 aSeq, e.Message, NULL ); 299 } 300 break; 301 } 302 } 303 } 304 305 if (m_sControlDataStyleName.getLength()) 306 { // we had a data-style-name attribute 307 308 // set the formatting on the control model of the control shape 309 uno::Reference< drawing::XControlShape > xControlShape(rPropSet, uno::UNO_QUERY); 310 DBG_ASSERT(xControlShape.is(), "XMLShapeStyleContext::FillPropertySet: data style for a non-control shape!"); 311 if (xControlShape.is()) 312 { 313 uno::Reference< beans::XPropertySet > xControlModel(xControlShape->getControl(), uno::UNO_QUERY); 314 DBG_ASSERT(xControlModel.is(), "XMLShapeStyleContext::FillPropertySet: no control model for the shape!"); 315 if (xControlModel.is()) 316 { 317 GetImport().GetFormImport()->applyControlNumberStyle(xControlModel, m_sControlDataStyleName); 318 } 319 } 320 } 321 } 322 323 void XMLShapeStyleContext::Finish( sal_Bool /*bOverwrite*/ ) 324 { 325 } 326 327