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