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 #include "PageMasterExportPropMapper.hxx" 31 #include <xmloff/xmltoken.hxx> 32 #include <comphelper/types.hxx> 33 #include <com/sun/star/table/BorderLine.hpp> 34 #include <xmloff/PageMasterStyleMap.hxx> 35 #include <tools/debug.hxx> 36 #include <rtl/ustrbuf.hxx> 37 #include <comphelper/extract.hxx> 38 39 using namespace ::com::sun::star; 40 using namespace ::com::sun::star::uno; 41 using namespace ::com::sun::star::beans; 42 using namespace ::comphelper; 43 using namespace ::xmloff::token; 44 45 46 //______________________________________________________________________________ 47 48 inline sal_Bool lcl_HasSameLineWidth( const table::BorderLine& rLine1, const table::BorderLine& rLine2 ) 49 { 50 return (rLine1.InnerLineWidth == rLine2.InnerLineWidth) && 51 (rLine1.OuterLineWidth == rLine2.OuterLineWidth) && 52 (rLine1.LineDistance == rLine2.LineDistance); 53 } 54 55 inline sal_Bool operator==( const table::BorderLine& rLine1, const table::BorderLine& rLine2 ) 56 { 57 return (rLine1.Color == rLine2.Color) && 58 lcl_HasSameLineWidth( rLine1, rLine2 ); 59 } 60 61 inline void lcl_RemoveState( XMLPropertyState* pState ) 62 { 63 pState->mnIndex = -1; 64 pState->maValue.clear(); 65 } 66 67 void lcl_RemoveStateIfZero16( XMLPropertyState* pState ) 68 { 69 sal_Int16 nValue = sal_Int16(); 70 if( (pState->maValue >>= nValue) && !nValue ) 71 lcl_RemoveState( pState ); 72 } 73 74 void lcl_AddState(::std::vector< XMLPropertyState >& rPropState, sal_Int32 nIndex, const rtl::OUString& rProperty, uno::Reference< beans::XPropertySet >& xProps) 75 { 76 if(::cppu::any2bool(xProps->getPropertyValue(rProperty))) 77 rPropState.push_back(XMLPropertyState (nIndex, cppu::bool2any(sal_True))); 78 } 79 80 //______________________________________________________________________________ 81 // helper struct to handle equal XMLPropertyState's for page, header and footer 82 83 struct XMLPropertyStateBuffer 84 { 85 XMLPropertyState* pPMMarginAll; 86 XMLPropertyState* pPMMarginTop; 87 XMLPropertyState* pPMMarginBottom; 88 XMLPropertyState* pPMMarginLeft; 89 XMLPropertyState* pPMMarginRight; 90 91 XMLPropertyState* pPMBorderAll; 92 XMLPropertyState* pPMBorderTop; 93 XMLPropertyState* pPMBorderBottom; 94 XMLPropertyState* pPMBorderLeft; 95 XMLPropertyState* pPMBorderRight; 96 97 XMLPropertyState* pPMBorderWidthAll; 98 XMLPropertyState* pPMBorderWidthTop; 99 XMLPropertyState* pPMBorderWidthBottom; 100 XMLPropertyState* pPMBorderWidthLeft; 101 XMLPropertyState* pPMBorderWidthRight; 102 103 XMLPropertyState* pPMPaddingAll; 104 XMLPropertyState* pPMPaddingTop; 105 XMLPropertyState* pPMPaddingBottom; 106 XMLPropertyState* pPMPaddingLeft; 107 XMLPropertyState* pPMPaddingRight; 108 109 XMLPropertyStateBuffer(); 110 void ContextFilter( ::std::vector< XMLPropertyState >& rPropState ); 111 }; 112 113 XMLPropertyStateBuffer::XMLPropertyStateBuffer() 114 : pPMMarginAll( NULL ) 115 , pPMMarginTop( NULL ) 116 , pPMMarginBottom( NULL ) 117 , pPMMarginLeft( NULL ) 118 , pPMMarginRight( NULL ) 119 , 120 pPMBorderAll( NULL ), 121 pPMBorderTop( NULL ), 122 pPMBorderBottom( NULL ), 123 pPMBorderLeft( NULL ), 124 pPMBorderRight( NULL ), 125 126 pPMBorderWidthAll( NULL ), 127 pPMBorderWidthTop( NULL ), 128 pPMBorderWidthBottom( NULL ), 129 pPMBorderWidthLeft( NULL ), 130 pPMBorderWidthRight( NULL ), 131 132 pPMPaddingAll( NULL ), 133 pPMPaddingTop( NULL ), 134 pPMPaddingBottom( NULL ), 135 pPMPaddingLeft( NULL ), 136 pPMPaddingRight( NULL ) 137 { 138 } 139 140 void XMLPropertyStateBuffer::ContextFilter( ::std::vector< XMLPropertyState >& ) 141 { 142 if (pPMMarginAll) 143 { 144 lcl_RemoveState(pPMMarginAll); // #i117696# do not write fo:margin 145 } 146 147 if( pPMBorderAll ) 148 { 149 if( pPMBorderTop && pPMBorderBottom && pPMBorderLeft && pPMBorderRight ) 150 { 151 table::BorderLine aLineTop, aLineBottom, aLineLeft, aLineRight; 152 153 pPMBorderTop->maValue >>= aLineTop; 154 pPMBorderBottom->maValue >>= aLineBottom; 155 pPMBorderLeft->maValue >>= aLineLeft; 156 pPMBorderRight->maValue >>= aLineRight; 157 158 if( (aLineTop == aLineBottom) && (aLineBottom == aLineLeft) && (aLineLeft == aLineRight) ) 159 { 160 lcl_RemoveState( pPMBorderTop ); 161 lcl_RemoveState( pPMBorderBottom ); 162 lcl_RemoveState( pPMBorderLeft ); 163 lcl_RemoveState( pPMBorderRight ); 164 } 165 else 166 lcl_RemoveState( pPMBorderAll ); 167 } 168 else 169 lcl_RemoveState( pPMBorderAll ); 170 } 171 172 if( pPMBorderWidthAll ) 173 { 174 if( pPMBorderWidthTop && pPMBorderWidthBottom && pPMBorderWidthLeft && pPMBorderWidthRight ) 175 { 176 table::BorderLine aLineTop, aLineBottom, aLineLeft, aLineRight; 177 178 pPMBorderWidthTop->maValue >>= aLineTop; 179 pPMBorderWidthBottom->maValue >>= aLineBottom; 180 pPMBorderWidthLeft->maValue >>= aLineLeft; 181 pPMBorderWidthRight->maValue >>= aLineRight; 182 183 if( lcl_HasSameLineWidth( aLineTop, aLineBottom ) && 184 lcl_HasSameLineWidth( aLineBottom, aLineLeft ) && 185 lcl_HasSameLineWidth( aLineLeft, aLineRight ) ) 186 { 187 lcl_RemoveState( pPMBorderWidthTop ); 188 lcl_RemoveState( pPMBorderWidthBottom ); 189 lcl_RemoveState( pPMBorderWidthLeft ); 190 lcl_RemoveState( pPMBorderWidthRight ); 191 } 192 else 193 lcl_RemoveState( pPMBorderWidthAll ); 194 } 195 else 196 lcl_RemoveState( pPMBorderWidthAll ); 197 } 198 199 if( pPMPaddingAll ) 200 { 201 if( pPMPaddingTop && pPMPaddingBottom && pPMPaddingLeft && pPMPaddingRight ) 202 { 203 sal_Int32 nTop = 0, nBottom = 0, nLeft = 0, nRight = 0; 204 205 pPMPaddingTop->maValue >>= nTop; 206 pPMPaddingBottom->maValue >>= nBottom; 207 pPMPaddingLeft->maValue >>= nLeft; 208 pPMPaddingRight->maValue >>= nRight; 209 210 if( (nTop == nBottom) && (nBottom == nLeft) && (nLeft == nRight) ) 211 { 212 lcl_RemoveState( pPMPaddingTop ); 213 lcl_RemoveState( pPMPaddingBottom ); 214 lcl_RemoveState( pPMPaddingLeft ); 215 lcl_RemoveState( pPMPaddingRight ); 216 } 217 else 218 lcl_RemoveState( pPMPaddingAll ); 219 } 220 else 221 lcl_RemoveState( pPMPaddingAll ); 222 } 223 } 224 225 //______________________________________________________________________________ 226 227 XMLPageMasterExportPropMapper::XMLPageMasterExportPropMapper( 228 const UniReference< XMLPropertySetMapper >& rMapper, 229 SvXMLExport& rExport ) : 230 SvXMLExportPropertyMapper( rMapper ), 231 aBackgroundImageExport( rExport ), 232 aTextColumnsExport( rExport ), 233 aFootnoteSeparatorExport( rExport ) 234 { 235 } 236 237 XMLPageMasterExportPropMapper::~XMLPageMasterExportPropMapper() 238 { 239 } 240 241 void XMLPageMasterExportPropMapper::handleElementItem( 242 SvXMLExport&, 243 const XMLPropertyState& rProperty, 244 sal_uInt16 /*nFlags*/, 245 const ::std::vector< XMLPropertyState >* pProperties, 246 sal_uInt32 nIdx ) const 247 { 248 XMLPageMasterExportPropMapper* pThis = (XMLPageMasterExportPropMapper*) this; 249 250 sal_uInt32 nContextId = getPropertySetMapper()->GetEntryContextId( rProperty.mnIndex ); 251 switch( nContextId ) 252 { 253 case CTF_PM_GRAPHICURL: 254 case CTF_PM_HEADERGRAPHICURL: 255 case CTF_PM_FOOTERGRAPHICURL: 256 { 257 DBG_ASSERT( pProperties && (nIdx >= 2), "property vector missing" ); 258 sal_Int32 nPos; 259 sal_Int32 nFilter; 260 switch( nContextId ) 261 { 262 case CTF_PM_GRAPHICURL: 263 nPos = CTF_PM_GRAPHICPOSITION; 264 nFilter = CTF_PM_GRAPHICFILTER; 265 break; 266 case CTF_PM_HEADERGRAPHICURL: 267 nPos = CTF_PM_HEADERGRAPHICPOSITION; 268 nFilter = CTF_PM_HEADERGRAPHICFILTER; 269 break; 270 case CTF_PM_FOOTERGRAPHICURL: 271 nPos = CTF_PM_FOOTERGRAPHICPOSITION; 272 nFilter = CTF_PM_FOOTERGRAPHICFILTER; 273 break; 274 default: 275 nPos = 0; // TODO What values should this be? 276 nFilter = 0; 277 } 278 const Any* pPos = NULL; 279 const Any* pFilter = NULL; 280 if( pProperties && (nIdx >= 2) ) 281 { 282 const XMLPropertyState& rPos = (*pProperties)[nIdx - 2]; 283 DBG_ASSERT( getPropertySetMapper()->GetEntryContextId( rPos.mnIndex ) == nPos, 284 "invalid property map: pos expected" ); 285 if( getPropertySetMapper()->GetEntryContextId( rPos.mnIndex ) == nPos ) 286 pPos = &rPos.maValue; 287 288 const XMLPropertyState& rFilter = (*pProperties)[nIdx - 1]; 289 DBG_ASSERT( getPropertySetMapper()->GetEntryContextId( rFilter.mnIndex ) == nFilter, 290 "invalid property map: filter expected" ); 291 if( getPropertySetMapper()->GetEntryContextId( rFilter.mnIndex ) == nFilter ) 292 pFilter = &rFilter.maValue; 293 } 294 sal_uInt32 nPropIndex = rProperty.mnIndex; 295 pThis->aBackgroundImageExport.exportXML( rProperty.maValue, pPos, pFilter, NULL, 296 getPropertySetMapper()->GetEntryNameSpace( nPropIndex ), 297 getPropertySetMapper()->GetEntryXMLName( nPropIndex ) ); 298 } 299 break; 300 case CTF_PM_TEXTCOLUMNS: 301 pThis->aTextColumnsExport.exportXML( rProperty.maValue ); 302 break; 303 case CTF_PM_FTN_LINE_WEIGTH: 304 pThis->aFootnoteSeparatorExport.exportXML( pProperties, nIdx, 305 getPropertySetMapper()); 306 break; 307 } 308 } 309 310 void XMLPageMasterExportPropMapper::handleSpecialItem( 311 SvXMLAttributeList&, 312 const XMLPropertyState&, 313 const SvXMLUnitConverter&, 314 const SvXMLNamespaceMap&, 315 const ::std::vector< XMLPropertyState >*, 316 sal_uInt32 /*nIdx*/) const 317 { 318 } 319 320 void XMLPageMasterExportPropMapper::ContextFilter( 321 ::std::vector< XMLPropertyState >& rPropState, 322 Reference< XPropertySet > rPropSet ) const 323 { 324 XMLPropertyStateBuffer aPageBuffer; 325 XMLPropertyStateBuffer aHeaderBuffer; 326 XMLPropertyStateBuffer aFooterBuffer; 327 328 XMLPropertyState* pPMHeaderHeight = NULL; 329 XMLPropertyState* pPMHeaderMinHeight = NULL; 330 XMLPropertyState* pPMHeaderDynamic = NULL; 331 332 XMLPropertyState* pPMFooterHeight = NULL; 333 XMLPropertyState* pPMFooterMinHeight = NULL; 334 XMLPropertyState* pPMFooterDynamic = NULL; 335 336 XMLPropertyState* pPMScaleTo = NULL; 337 XMLPropertyState* pPMScaleToPages = NULL; 338 XMLPropertyState* pPMScaleToX = NULL; 339 XMLPropertyState* pPMScaleToY = NULL; 340 XMLPropertyState* pPMStandardMode = NULL; 341 XMLPropertyState* pPMGridBaseWidth = NULL; 342 XMLPropertyState* pPMGridSnapToChars = NULL; 343 344 XMLPropertyState* pPrint = NULL; 345 346 UniReference < XMLPropertySetMapper > aPropMapper(getPropertySetMapper()); 347 348 for( ::std::vector< XMLPropertyState >::iterator aIter = rPropState.begin(); aIter != rPropState.end(); ++aIter ) 349 { 350 XMLPropertyState *pProp = &(*aIter); 351 sal_Int16 nContextId = aPropMapper->GetEntryContextId( pProp->mnIndex ); 352 sal_Int16 nFlag = nContextId & CTF_PM_FLAGMASK; 353 sal_Int16 nSimpleId = nContextId & (~CTF_PM_FLAGMASK | XML_PM_CTF_START); 354 sal_Int16 nPrintId = nContextId & CTF_PM_PRINTMASK; 355 356 XMLPropertyStateBuffer* pBuffer; 357 switch( nFlag ) 358 { 359 case CTF_PM_HEADERFLAG: pBuffer = &aHeaderBuffer; break; 360 case CTF_PM_FOOTERFLAG: pBuffer = &aFooterBuffer; break; 361 default: pBuffer = &aPageBuffer; break; 362 } 363 364 switch( nSimpleId ) 365 { 366 case CTF_PM_MARGINALL: pBuffer->pPMMarginAll = pProp; break; 367 case CTF_PM_MARGINTOP: pBuffer->pPMMarginTop = pProp; break; 368 case CTF_PM_MARGINBOTTOM: pBuffer->pPMMarginBottom = pProp; break; 369 case CTF_PM_MARGINLEFT: pBuffer->pPMMarginLeft = pProp; break; 370 case CTF_PM_MARGINRIGHT: pBuffer->pPMMarginRight = pProp; break; 371 case CTF_PM_BORDERALL: pBuffer->pPMBorderAll = pProp; break; 372 case CTF_PM_BORDERTOP: pBuffer->pPMBorderTop = pProp; break; 373 case CTF_PM_BORDERBOTTOM: pBuffer->pPMBorderBottom = pProp; break; 374 case CTF_PM_BORDERLEFT: pBuffer->pPMBorderLeft = pProp; break; 375 case CTF_PM_BORDERRIGHT: pBuffer->pPMBorderRight = pProp; break; 376 case CTF_PM_BORDERWIDTHALL: pBuffer->pPMBorderWidthAll = pProp; break; 377 case CTF_PM_BORDERWIDTHTOP: pBuffer->pPMBorderWidthTop = pProp; break; 378 case CTF_PM_BORDERWIDTHBOTTOM: pBuffer->pPMBorderWidthBottom = pProp; break; 379 case CTF_PM_BORDERWIDTHLEFT: pBuffer->pPMBorderWidthLeft = pProp; break; 380 case CTF_PM_BORDERWIDTHRIGHT: pBuffer->pPMBorderWidthRight = pProp; break; 381 case CTF_PM_PADDINGALL: pBuffer->pPMPaddingAll = pProp; break; 382 case CTF_PM_PADDINGTOP: pBuffer->pPMPaddingTop = pProp; break; 383 case CTF_PM_PADDINGBOTTOM: pBuffer->pPMPaddingBottom = pProp; break; 384 case CTF_PM_PADDINGLEFT: pBuffer->pPMPaddingLeft = pProp; break; 385 case CTF_PM_PADDINGRIGHT: pBuffer->pPMPaddingRight = pProp; break; 386 } 387 388 switch( nContextId ) 389 { 390 case CTF_PM_HEADERHEIGHT: pPMHeaderHeight = pProp; break; 391 case CTF_PM_HEADERMINHEIGHT: pPMHeaderMinHeight = pProp; break; 392 case CTF_PM_HEADERDYNAMIC: pPMHeaderDynamic = pProp; break; 393 case CTF_PM_FOOTERHEIGHT: pPMFooterHeight = pProp; break; 394 case CTF_PM_FOOTERMINHEIGHT: pPMFooterMinHeight = pProp; break; 395 case CTF_PM_FOOTERDYNAMIC: pPMFooterDynamic = pProp; break; 396 case CTF_PM_SCALETO: pPMScaleTo = pProp; break; 397 case CTF_PM_SCALETOPAGES: pPMScaleToPages = pProp; break; 398 case CTF_PM_SCALETOX: pPMScaleToX = pProp; break; 399 case CTF_PM_SCALETOY: pPMScaleToY = pProp; break; 400 case CTF_PM_STANDARD_MODE: pPMStandardMode = pProp; break; 401 case CTP_PM_GRID_BASE_WIDTH: pPMGridBaseWidth = pProp; break; 402 case CTP_PM_GRID_SNAP_TO_CHARS: pPMGridSnapToChars = pProp; break; 403 } 404 if (nPrintId == CTF_PM_PRINTMASK) 405 { 406 pPrint = pProp; 407 lcl_RemoveState(pPrint); 408 } 409 } 410 411 if( pPMStandardMode && !getBOOL(pPMStandardMode->maValue) ) 412 { 413 lcl_RemoveState(pPMStandardMode); 414 if( pPMGridBaseWidth ) 415 lcl_RemoveState(pPMGridBaseWidth); 416 if( pPMGridSnapToChars ) 417 lcl_RemoveState(pPMGridSnapToChars); 418 } 419 420 if( pPMGridBaseWidth && pPMStandardMode ) 421 lcl_RemoveState(pPMStandardMode); 422 423 aPageBuffer.ContextFilter( rPropState ); 424 aHeaderBuffer.ContextFilter( rPropState ); 425 aFooterBuffer.ContextFilter( rPropState ); 426 427 if( pPMHeaderHeight && (!pPMHeaderDynamic || (pPMHeaderDynamic && getBOOL( pPMHeaderDynamic->maValue ))) ) 428 lcl_RemoveState( pPMHeaderHeight ); 429 if( pPMHeaderMinHeight && pPMHeaderDynamic && !getBOOL( pPMHeaderDynamic->maValue ) ) 430 lcl_RemoveState( pPMHeaderMinHeight ); 431 if( pPMHeaderDynamic ) 432 lcl_RemoveState( pPMHeaderDynamic ); 433 434 if( pPMFooterHeight && (!pPMFooterDynamic || (pPMFooterDynamic && getBOOL( pPMFooterDynamic->maValue ))) ) 435 lcl_RemoveState( pPMFooterHeight ); 436 if( pPMFooterMinHeight && pPMFooterDynamic && !getBOOL( pPMFooterDynamic->maValue ) ) 437 lcl_RemoveState( pPMFooterMinHeight ); 438 if( pPMFooterDynamic ) 439 lcl_RemoveState( pPMFooterDynamic ); 440 441 if( pPMScaleTo ) 442 lcl_RemoveStateIfZero16( pPMScaleTo ); 443 if( pPMScaleToPages ) 444 lcl_RemoveStateIfZero16( pPMScaleToPages ); 445 if( pPMScaleToX ) 446 lcl_RemoveStateIfZero16( pPMScaleToX ); 447 if( pPMScaleToY ) 448 lcl_RemoveStateIfZero16( pPMScaleToY ); 449 450 if (pPrint) 451 { 452 lcl_AddState(rPropState, aPropMapper->FindEntryIndex(CTF_PM_PRINT_ANNOTATIONS), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PrintAnnotations")), rPropSet); 453 lcl_AddState(rPropState, aPropMapper->FindEntryIndex(CTF_PM_PRINT_CHARTS), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PrintCharts")), rPropSet); 454 lcl_AddState(rPropState, aPropMapper->FindEntryIndex(CTF_PM_PRINT_DRAWING), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PrintDrawing")), rPropSet); 455 lcl_AddState(rPropState, aPropMapper->FindEntryIndex(CTF_PM_PRINT_FORMULAS), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PrintFormulas")), rPropSet); 456 lcl_AddState(rPropState, aPropMapper->FindEntryIndex(CTF_PM_PRINT_GRID), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PrintGrid")), rPropSet); 457 lcl_AddState(rPropState, aPropMapper->FindEntryIndex(CTF_PM_PRINT_HEADERS), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PrintHeaders")), rPropSet); 458 lcl_AddState(rPropState, aPropMapper->FindEntryIndex(CTF_PM_PRINT_OBJECTS), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PrintObjects")), rPropSet); 459 lcl_AddState(rPropState, aPropMapper->FindEntryIndex(CTF_PM_PRINT_ZEROVALUES), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PrintZeroValues")), rPropSet); 460 } 461 462 SvXMLExportPropertyMapper::ContextFilter(rPropState,rPropSet); 463 } 464 465