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_svx.hxx" 26 #include <tools/debug.hxx> 27 #include <com/sun/star/document/XGraphicObjectResolver.hpp> 28 #include <com/sun/star/embed/ElementModes.hpp> 29 #include <com/sun/star/io/XActiveDataControl.hpp> 30 #include <com/sun/star/io/XActiveDataSource.hpp> 31 #include <com/sun/star/xml/sax/XParser.hpp> 32 #include <com/sun/star/container/XNameContainer.hpp> 33 #include <com/sun/star/xml/sax/XDocumentHandler.hpp> 34 #include <com/sun/star/uno/Sequence.hxx> 35 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp> 36 #include <com/sun/star/drawing/LineDash.hpp> 37 #include <com/sun/star/awt/Gradient.hpp> 38 #include <com/sun/star/drawing/Hatch.hpp> 39 #include <com/sun/star/io/XOutputStream.hpp> 40 #ifndef _COM_SUN_STAR_IO_XSEEKABLE_HDL_ 41 #include <com/sun/star/io/XSeekable.hdl> 42 #endif 43 #include <comphelper/processfactory.hxx> 44 #include <unotools/streamwrap.hxx> 45 #include <rtl/ustrbuf.hxx> 46 #include <sfx2/docfile.hxx> 47 #include <xmloff/xmluconv.hxx> 48 #include "xmloff/xmlnmspe.hxx" 49 #include "xmloff/nmspmap.hxx" 50 51 #include "xmloff/xmltoken.hxx" 52 #include "xmloff/xmlmetae.hxx" 53 #include "xmloff/DashStyle.hxx" 54 #include "xmloff/GradientStyle.hxx" 55 #include "xmloff/HatchStyle.hxx" 56 #include "xmloff/ImageStyle.hxx" 57 #include "xmloff/MarkerStyle.hxx" 58 #include <xmloff/xmlictxt.hxx> 59 #include "svx/xmlgrhlp.hxx" 60 #include "xmloff/attrlist.hxx" 61 62 #include "xmlxtimp.hxx" 63 64 using namespace com::sun::star; 65 using namespace com::sun::star::container; 66 using namespace com::sun::star::document; 67 using namespace com::sun::star::uno; 68 using namespace com::sun::star::awt; 69 using namespace com::sun::star::lang; 70 using namespace com::sun::star::xml::sax; 71 using namespace ::rtl; 72 using namespace ::xmloff::token; 73 using namespace cppu; 74 75 sal_Char __READONLY_DATA sXML_np__office[] = "__office"; 76 sal_Char __READONLY_DATA sXML_np__office_ooo[] = "___office"; 77 sal_Char __READONLY_DATA sXML_np__draw[] = "__draw"; 78 sal_Char __READONLY_DATA sXML_np__draw_ooo[] = "___draw"; 79 sal_Char __READONLY_DATA sXML_np__ooo[] = "__ooo"; 80 sal_Char __READONLY_DATA sXML_np__xlink[] = "__xlink"; 81 82 /////////////////////////////////////////////////////////////////////// 83 84 enum SvxXMLTableImportContextEnum { stice_unknown, stice_color, stice_marker, stice_dash, stice_hatch, stice_gradient, stice_bitmap }; 85 86 /////////////////////////////////////////////////////////////////////// 87 88 class SvxXMLTableImportContext : public SvXMLImportContext 89 { 90 public: 91 SvxXMLTableImportContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName, const uno::Reference< XAttributeList >& xAttrList, SvxXMLTableImportContextEnum eContext, const uno::Reference< XNameContainer >& xTable, 92 sal_Bool bOOoFormat ); 93 virtual ~SvxXMLTableImportContext(); 94 95 virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList ); 96 97 SvxXMLXTableImport& getImport() const { return *(SvxXMLXTableImport*)&GetImport(); } 98 99 protected: 100 void importColor( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName ); 101 void importMarker( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName ); 102 void importDash( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName ); 103 void importHatch( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName ); 104 void importGradient( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName ); 105 void importBitmap( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName ); 106 107 private: 108 uno::Reference< XNameContainer > mxTable; 109 SvxXMLTableImportContextEnum meContext; 110 sal_Bool mbOOoFormat; 111 }; 112 113 /////////////////////////////////////////////////////////////////////// 114 115 SvxXMLTableImportContext::SvxXMLTableImportContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName, const uno::Reference< XAttributeList >&, SvxXMLTableImportContextEnum eContext, const uno::Reference< XNameContainer >& xTable, sal_Bool bOOoFormat ) 116 : SvXMLImportContext( rImport, nPrfx, rLName ), mxTable( xTable ), meContext( eContext ), 117 mbOOoFormat( bOOoFormat ) 118 { 119 } 120 121 SvxXMLTableImportContext::~SvxXMLTableImportContext() 122 { 123 } 124 125 SvXMLImportContext *SvxXMLTableImportContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< XAttributeList >& rAttrList ) 126 { 127 if( XML_NAMESPACE_DRAW == nPrefix ) 128 { 129 uno::Reference< XAttributeList > xAttrList( rAttrList ); 130 if( mbOOoFormat && 131 (stice_dash == meContext || stice_hatch == meContext || 132 stice_bitmap == meContext) ) 133 { 134 SvXMLAttributeList *pAttrList = new SvXMLAttributeList( rAttrList ); 135 xAttrList = pAttrList; 136 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; 137 for( sal_Int16 i=0; i < nAttrCount; i++ ) 138 { 139 const OUString& rAttrName = xAttrList->getNameByIndex( i ); 140 OUString aLocalName; 141 sal_uInt16 nPrefix_ = 142 GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, 143 &aLocalName ); 144 if( XML_NAMESPACE_XLINK == nPrefix_ && 145 stice_bitmap == meContext && 146 IsXMLToken( aLocalName, XML_HREF ) ) 147 { 148 const OUString rValue = xAttrList->getValueByIndex( i ); 149 if( rValue.getLength() && '#' == rValue[0] ) 150 pAttrList->SetValueByIndex( i, rValue.copy( 1 ) ); 151 } 152 else if( XML_NAMESPACE_DRAW == nPrefix_ && 153 ( ( stice_dash == meContext && 154 (IsXMLToken( aLocalName, XML_DOTS1_LENGTH ) || 155 IsXMLToken( aLocalName, XML_DOTS2_LENGTH ) || 156 IsXMLToken( aLocalName, XML_DISTANCE )) ) || 157 ( stice_hatch == meContext && 158 IsXMLToken( aLocalName, XML_HATCH_DISTANCE ) ) ) ) 159 { 160 const OUString rValue = xAttrList->getValueByIndex( i ); 161 sal_Int32 nPos = rValue.getLength(); 162 while( nPos && rValue[nPos-1] <= ' ' ) 163 --nPos; 164 if( nPos > 2 && 165 ('c'==rValue[nPos-2] || 'C'==rValue[nPos-2]) && 166 ('h'==rValue[nPos-1] || 'H'==rValue[nPos-1]) ) 167 { 168 pAttrList->SetValueByIndex( i, rValue.copy( 0, nPos-2 ) ); 169 } 170 } 171 } 172 } 173 try 174 { 175 Any aAny; 176 OUString aName; 177 178 switch( meContext ) 179 { 180 case stice_color: 181 importColor( nPrefix, rLocalName, xAttrList, aAny, aName ); 182 break; 183 case stice_marker: 184 importMarker( nPrefix, rLocalName, xAttrList, aAny, aName ); 185 break; 186 case stice_dash: 187 importDash( nPrefix, rLocalName, xAttrList, aAny, aName ); 188 break; 189 case stice_hatch: 190 importHatch( nPrefix, rLocalName, xAttrList, aAny, aName ); 191 break; 192 case stice_gradient: 193 importGradient( nPrefix, rLocalName, xAttrList, aAny, aName ); 194 break; 195 case stice_bitmap: 196 importBitmap( nPrefix, rLocalName, xAttrList, aAny, aName ); 197 break; 198 case stice_unknown: 199 break; 200 } 201 202 if( aName.getLength() && aAny.hasValue() ) 203 { 204 if( mxTable->hasByName( aName ) ) 205 { 206 mxTable->replaceByName( aName, aAny ); 207 } 208 else 209 { 210 mxTable->insertByName( aName, aAny ); 211 } 212 } 213 } 214 catch( uno::Exception& ) 215 { 216 } 217 } 218 219 return new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); 220 } 221 222 void SvxXMLTableImportContext::importColor( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName ) 223 { 224 (void)nPrfx; 225 (void)rLocalName; 226 227 const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; 228 for( sal_Int16 i=0; i < nAttrCount; i++ ) 229 { 230 const OUString& rFullAttrName = xAttrList->getNameByIndex( i ); 231 OUString aLocalName; 232 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( rFullAttrName, &aLocalName ); 233 234 235 if( XML_NAMESPACE_DRAW == nPrefix ) 236 { 237 if( aLocalName == GetXMLToken(XML_NAME) ) 238 { 239 rName = xAttrList->getValueByIndex( i ); 240 } 241 else if( aLocalName == GetXMLToken(XML_COLOR) ) 242 { 243 Color aColor; 244 SvXMLUnitConverter::convertColor(aColor, xAttrList->getValueByIndex( i )); 245 rAny <<= (sal_Int32)aColor.GetColor(); 246 } 247 } 248 } 249 } 250 251 void SvxXMLTableImportContext::importMarker( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName ) 252 { 253 (void)nPrfx; 254 (void)rLocalName; 255 256 try 257 { 258 XMLMarkerStyleImport aMarkerStyle( GetImport() ); 259 aMarkerStyle.importXML( xAttrList, rAny, rName ); 260 } 261 catch( Exception& ) 262 { 263 DBG_ERROR("SvxXMLTableImportContext::importMarker(), exception caught!"); 264 } 265 } 266 267 void SvxXMLTableImportContext::importDash( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName ) 268 { 269 (void)nPrfx; 270 (void)rLocalName; 271 272 try 273 { 274 XMLDashStyleImport aDashStyle( GetImport() ); 275 aDashStyle.importXML( xAttrList, rAny, rName ); 276 } 277 catch( Exception& ) 278 { 279 DBG_ERROR("SvxXMLTableImportContext::importDash(), exception caught!"); 280 } 281 } 282 283 void SvxXMLTableImportContext::importHatch( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName ) 284 { 285 (void)nPrfx; 286 (void)rLocalName; 287 288 try 289 { 290 XMLHatchStyleImport aHatchStyle( GetImport() ); 291 aHatchStyle.importXML( xAttrList, rAny, rName ); 292 } 293 catch( Exception& ) 294 { 295 DBG_ERROR("SvxXMLTableImportContext::importHatch(), exception caught!"); 296 } 297 } 298 299 void SvxXMLTableImportContext::importGradient( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName ) 300 { 301 (void)nPrfx; 302 (void)rLocalName; 303 304 try 305 { 306 XMLGradientStyleImport aGradientStyle( GetImport() ); 307 aGradientStyle.importXML( xAttrList, rAny, rName ); 308 } 309 catch( Exception& ) 310 { 311 DBG_ERROR("SvxXMLTableImportContext::importGradient(), exception caught!"); 312 } 313 } 314 315 void SvxXMLTableImportContext::importBitmap( sal_uInt16 nPrfx, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList, Any& rAny, OUString& rName ) 316 { 317 (void)nPrfx; 318 (void)rLocalName; 319 320 try 321 { 322 XMLImageStyle aImageStyle; 323 aImageStyle.importXML( xAttrList, rAny, rName, GetImport() ); 324 } 325 catch( Exception& ) 326 { 327 DBG_ERROR("SvxXMLTableImportContext::importBitmap(), exception caught!"); 328 } 329 } 330 331 /////////////////////////////////////////////////////////////////////// 332 333 // #110680# 334 SvxXMLXTableImport::SvxXMLXTableImport( 335 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory, 336 const uno::Reference< XNameContainer > & rTable, 337 uno::Reference< XGraphicObjectResolver >& xGrfResolver ) 338 : SvXMLImport(xServiceFactory, 0), 339 mrTable( rTable ) 340 { 341 SetGraphicResolver( xGrfResolver ); 342 343 GetNamespaceMap().Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__ooo ) ), GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO ); 344 GetNamespaceMap().Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__office ) ), GetXMLToken(XML_N_OFFICE), XML_NAMESPACE_OFFICE ); 345 GetNamespaceMap().Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__draw ) ), GetXMLToken(XML_N_DRAW), XML_NAMESPACE_DRAW ); 346 GetNamespaceMap().Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__xlink ) ), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK ); 347 348 // OOo namespaces for reading OOo 1.1 files 349 GetNamespaceMap().Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__office_ooo ) ), 350 GetXMLToken(XML_N_OFFICE_OOO), 351 XML_NAMESPACE_OFFICE ); 352 GetNamespaceMap().Add( OUString( RTL_CONSTASCII_USTRINGPARAM ( sXML_np__draw_ooo ) ), 353 GetXMLToken(XML_N_DRAW_OOO), 354 XML_NAMESPACE_DRAW ); 355 } 356 357 SvxXMLXTableImport::~SvxXMLXTableImport() throw () 358 { 359 } 360 361 sal_Bool SvxXMLXTableImport::load( const OUString& rUrl, const uno::Reference< XNameContainer >& xTable ) throw() 362 { 363 sal_Bool bRet = sal_True; 364 365 uno::Reference< XGraphicObjectResolver > xGrfResolver; 366 SvXMLGraphicHelper* pGraphicHelper = 0; 367 368 try 369 { 370 do 371 { 372 SfxMedium aMedium( rUrl, STREAM_READ | STREAM_NOCREATE, sal_True ); 373 374 uno::Reference<lang::XMultiServiceFactory> xServiceFactory( ::comphelper::getProcessServiceFactory() ); 375 if( !xServiceFactory.is() ) 376 { 377 DBG_ERROR( "SvxXMLXTableImport::load: got no service manager" ); 378 break; 379 } 380 381 uno::Reference< xml::sax::XParser > xParser( xServiceFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Parser" ) ) ), uno::UNO_QUERY_THROW ); 382 uno::Reference < io::XStream > xIStm; 383 uno::Reference< io::XActiveDataSource > xSource; 384 385 xml::sax::InputSource aParserInput; 386 aParserInput.sSystemId = aMedium.GetName(); 387 388 if( aMedium.IsStorage() ) 389 { 390 uno::Reference < embed::XStorage > xStorage( aMedium.GetStorage( sal_False ), uno::UNO_QUERY_THROW ); 391 392 const String aContentStmName( RTL_CONSTASCII_USTRINGPARAM( "Content.xml" ) ); 393 xIStm.set( xStorage->openStreamElement( aContentStmName, embed::ElementModes::READ ), uno::UNO_QUERY_THROW ); 394 if( !xIStm.is() ) 395 { 396 DBG_ERROR( "could not open Content stream" ); 397 break; 398 } 399 400 aParserInput.aInputStream = xIStm->getInputStream(); 401 pGraphicHelper = SvXMLGraphicHelper::Create( xStorage, GRAPHICHELPER_MODE_READ ); 402 xGrfResolver = pGraphicHelper; 403 } 404 else 405 { 406 aParserInput.aInputStream = aMedium.GetInputStream(); 407 uno::Reference< io::XSeekable > xSeek( aParserInput.aInputStream, uno::UNO_QUERY_THROW ); 408 xSeek->seek( 0 ); 409 } 410 411 if( xSource.is() ) 412 { 413 uno::Reference< io::XActiveDataControl > xSourceControl( xSource, UNO_QUERY_THROW ); 414 xSourceControl->start(); 415 } 416 417 // #110680# 418 // uno::Reference< XDocumentHandler > xHandler( new SvxXMLXTableImport( xTable, xGrfResolver ) ); 419 uno::Reference< XDocumentHandler > xHandler( new SvxXMLXTableImport( xServiceFactory, xTable, xGrfResolver ) ); 420 421 xParser->setDocumentHandler( xHandler ); 422 xParser->parseStream( aParserInput ); 423 } 424 while(0); 425 426 if( pGraphicHelper ) 427 SvXMLGraphicHelper::Destroy( pGraphicHelper ); 428 } 429 catch( uno::Exception& ) 430 { 431 // CL: I disabled this assertion since its an error, but it happens 432 // each time you load a document with property tables that are not 433 // on the current machine. Maybe a better fix would be to place 434 // a file exists check before importing... 435 // DBG_ERROR("svx::SvxXMLXTableImport::load(), exception caught!"); 436 bRet = sal_False; 437 } 438 439 return bRet; 440 } 441 442 SvXMLImportContext *SvxXMLXTableImport::CreateContext( sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< XAttributeList >& xAttrList ) 443 { 444 if( XML_NAMESPACE_OOO == nPrefix || 445 XML_NAMESPACE_OFFICE == nPrefix ) 446 { 447 sal_Bool bOOoFormat = (XML_NAMESPACE_OFFICE == nPrefix); 448 Type aType = mrTable->getElementType(); 449 450 if( rLocalName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "color-table" ) ) ) 451 { 452 if( aType == ::getCppuType((const sal_Int32*)0) ) 453 return new SvxXMLTableImportContext( *this, nPrefix, rLocalName, xAttrList, stice_color, mrTable, bOOoFormat ); 454 } 455 else if( rLocalName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "marker-table" ) ) ) 456 { 457 if( aType == ::getCppuType((const drawing::PolyPolygonBezierCoords*)0) ) 458 return new SvxXMLTableImportContext( *this, nPrefix, rLocalName, xAttrList, stice_marker, mrTable, bOOoFormat ); 459 } 460 else if( rLocalName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "dash-table" ) ) ) 461 { 462 if( aType == ::getCppuType((const drawing::LineDash*)0) ) 463 return new SvxXMLTableImportContext( *this, nPrefix, rLocalName, xAttrList, stice_dash, mrTable, bOOoFormat ); 464 } 465 else if( rLocalName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "hatch-table" ) ) ) 466 { 467 if( aType == ::getCppuType((const drawing::Hatch*)0) ) 468 return new SvxXMLTableImportContext( *this, nPrefix, rLocalName, xAttrList, stice_hatch, mrTable, bOOoFormat ); 469 } 470 else if( rLocalName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "gradient-table" ) ) ) 471 { 472 if( aType == ::getCppuType((const awt::Gradient*)0)) 473 return new SvxXMLTableImportContext( *this, nPrefix, rLocalName, xAttrList, stice_gradient, mrTable, bOOoFormat ); 474 } 475 else if( rLocalName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "bitmap-table" ) ) ) 476 { 477 if( aType == ::getCppuType((const OUString*)0)) 478 return new SvxXMLTableImportContext( *this, nPrefix, rLocalName, xAttrList, stice_bitmap, mrTable, bOOoFormat ); 479 } 480 } 481 482 return new SvXMLImportContext( *this, nPrefix, rLocalName ); 483 } 484 485