xref: /trunk/main/xmloff/source/style/PageMasterExportPropMapper.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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