xref: /AOO41X/main/sw/source/filter/xml/xmlexpit.cxx (revision c9a23c92fe06034cc89e1d0a161497dc25e59663)
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_sw.hxx"
26 #include "xmlexpit.hxx"
27 
28 #include <xmloff/xmluconv.hxx>
29 #include <rtl/ustrbuf.hxx>
30 #include <svl/itempool.hxx>
31 #include <svl/poolitem.hxx>
32 #include <svl/itemset.hxx>
33 #include <xmloff/attrlist.hxx>
34 #include <xmloff/nmspmap.hxx>
35 #include <xmloff/xmlnmspe.hxx>
36 #include <editeng/xmlcnitm.hxx>
37 #include <xmloff/xmlexp.hxx>
38 #include <editeng/memberids.hrc>
39 
40 #ifndef _SVSTDARR_USHORTS
41 #define _SVSTDARR_USHORTS
42 #include <svl/svstdarr.hxx>
43 #endif
44 
45 
46 #include "hintids.hxx"
47 #include "unomid.h"
48 #include <svx/unomid.hxx>
49 #include <editeng/lrspitem.hxx>
50 #include <editeng/ulspitem.hxx>
51 #include <editeng/shaditem.hxx>
52 #include <editeng/boxitem.hxx>
53 #include <editeng/brkitem.hxx>
54 #include <editeng/keepitem.hxx>
55 #include <editeng/brshitem.hxx>
56 #include "fmtpdsc.hxx"
57 #include "fmtornt.hxx"
58 #include "fmtfsize.hxx"
59 
60 #ifndef _FMTLSPLT_HXX
61 #include "fmtlsplt.hxx"
62 #endif
63 #include "xmlithlp.hxx"
64 
65 #include "fmtrowsplt.hxx"
66 
67 
68 using ::rtl::OUString;
69 using ::rtl::OUStringBuffer;
70 using namespace ::com::sun::star;
71 using namespace ::xmloff::token;
72 using uno::Any;
73 
74 /** fills the given attribute list with the items in the given set */
exportXML(const SvXMLExport & rExport,SvXMLAttributeList & rAttrList,const SfxItemSet & rSet,const SvXMLUnitConverter & rUnitConverter,const SvXMLNamespaceMap & rNamespaceMap,sal_uInt16 nFlags,SvUShorts * pIndexArray) const75 void SvXMLExportItemMapper::exportXML( const SvXMLExport& rExport,
76                                 SvXMLAttributeList& rAttrList,
77                                 const SfxItemSet& rSet,
78                                 const SvXMLUnitConverter& rUnitConverter,
79                                 const SvXMLNamespaceMap& rNamespaceMap,
80                                 sal_uInt16 nFlags,
81                                 SvUShorts* pIndexArray ) const
82 {
83     const sal_uInt16 nCount = mrMapEntries->getCount();
84     sal_uInt16 nIndex = 0;
85 
86     while( nIndex < nCount )
87     {
88         SvXMLItemMapEntry* pEntry = mrMapEntries->getByIndex( nIndex );
89 
90         // we have a valid map entry here, so lets use it...
91         if( 0 == (pEntry->nMemberId & MID_SW_FLAG_NO_ITEM_EXPORT) )
92         {
93             const SfxPoolItem* pItem = GetItem( rSet, pEntry->nWhichId,
94                                                 nFlags );
95             // do we have an item?
96             if(pItem)
97             {
98                 if( 0 != (pEntry->nMemberId & MID_SW_FLAG_ELEMENT_ITEM_EXPORT) )
99                 {
100                     // element items do not add any properties,
101                     // we export it later
102                     if( pIndexArray )
103                         pIndexArray->Insert( nIndex, pIndexArray->Count() );
104 
105                 }
106                 else
107                 {
108                     exportXML( rExport, rAttrList, *pItem, *pEntry, rUnitConverter,
109                                rNamespaceMap, nFlags, &rSet );
110                 }
111             }
112         }
113         else
114         {
115             handleNoItem( rAttrList, *pEntry, rUnitConverter, rNamespaceMap,
116                           rSet );
117         }
118         nIndex++;
119     }
120 }
121 
exportXML(const SvXMLExport & rExport,SvXMLAttributeList & rAttrList,const SfxPoolItem & rItem,const SvXMLItemMapEntry & rEntry,const SvXMLUnitConverter & rUnitConverter,const SvXMLNamespaceMap & rNamespaceMap,sal_uInt16,const SfxItemSet * pSet) const122 void SvXMLExportItemMapper::exportXML( const SvXMLExport& rExport,
123                                  SvXMLAttributeList& rAttrList,
124                                  const SfxPoolItem& rItem,
125                                  const SvXMLItemMapEntry& rEntry,
126                                  const SvXMLUnitConverter& rUnitConverter,
127                                  const SvXMLNamespaceMap& rNamespaceMap,
128                                  sal_uInt16 /*nFlags*/,
129                                  const SfxItemSet *pSet ) const
130 {
131     if( 0 != (rEntry.nMemberId & MID_SW_FLAG_SPECIAL_ITEM_EXPORT) )
132     {
133         if( rItem.ISA( SwFmtRowSplit ) )
134         {
135             OUString aValue;
136             bool bAddAttribute = true;
137             if( rEntry.nNameSpace == XML_NAMESPACE_STYLE )
138             {
139                 if( (rExport.getExportFlags() & EXPORT_SAVEBACKWARDCOMPATIBLE ) == 0 ||
140                     !QueryXMLValue(rItem, aValue,
141                     static_cast< sal_uInt16 >( rEntry.nMemberId & MID_SW_FLAG_MASK ),
142                     rUnitConverter ) )
143                 {
144                     bAddAttribute = false;
145                 }
146             }
147             else
148             {
149                 OUStringBuffer aOut;
150                 const SfxBoolItem* pSplit = PTR_CAST(SfxBoolItem, &rItem);
151                 DBG_ASSERT( pSplit != NULL, "Wrong Which-ID" );
152                 sal_uInt16 eEnum = pSplit->GetValue() ? 1 : 0;
153                 rUnitConverter.convertEnum( aOut, eEnum, aXML_KeepTogetherType );
154                 aValue = aOut.makeStringAndClear();
155             }
156             if( bAddAttribute )
157             {
158                 OUString sName( rNamespaceMap.GetQNameByKey( rEntry.nNameSpace,
159                                 GetXMLToken(rEntry.eLocalName) ) );
160                 rAttrList.AddAttribute( sName, aValue );
161             }
162         }
163         if( rItem.ISA( SvXMLAttrContainerItem ) )
164         {
165             SvXMLNamespaceMap *pNewNamespaceMap = 0;
166             const SvXMLNamespaceMap *pNamespaceMap = &rNamespaceMap;
167 
168             const SvXMLAttrContainerItem *pUnknown =
169                 PTR_CAST( SvXMLAttrContainerItem, &rItem );
170 
171             sal_uInt16 nCount = pUnknown->GetAttrCount();
172             OUStringBuffer sName;
173             for( sal_uInt16 i=0; i < nCount; i++ )
174             {
175                 OUString sPrefix( pUnknown->GetAttrPrefix( i ) );
176                 if( sPrefix.getLength() )
177                 {
178                     OUString sNamespace( pUnknown->GetAttrNamespace( i ) );
179 
180                     // if the prefix isn't defined yet or has another meaning,
181                     // we have to redefine it now.
182                     sal_uInt16 nIdx =   pNamespaceMap->GetIndexByPrefix( sPrefix );
183                     if( USHRT_MAX == nIdx ||
184                         pNamespaceMap->GetNameByIndex( nIdx ) != sNamespace )
185                     {
186                         if( !pNewNamespaceMap )
187                         {
188                             pNewNamespaceMap =
189                                         new SvXMLNamespaceMap( rNamespaceMap );
190                             pNamespaceMap = pNewNamespaceMap;
191                         }
192                         pNewNamespaceMap->Add( sPrefix, sNamespace );
193 
194                         sName.append( GetXMLToken(XML_XMLNS) );
195                         sName.append( sal_Unicode(':') );
196                         sName.append( sPrefix );
197                         rAttrList.AddAttribute( sName.makeStringAndClear(),
198                                                 sNamespace );
199                     }
200 
201                     sName.append( sPrefix );
202                     sName.append( sal_Unicode(':') );
203                 }
204 
205                 sName.append( pUnknown->GetAttrLName( i ) );
206                 rAttrList.AddAttribute( sName.makeStringAndClear(),
207                                         pUnknown->GetAttrValue(i) );
208             }
209 
210             delete pNewNamespaceMap;
211         }
212         else
213         {
214             handleSpecialItem( rAttrList, rEntry, rItem, rUnitConverter,
215                                rNamespaceMap, pSet );
216         }
217     }
218     else if( 0 == (rEntry.nMemberId & MID_SW_FLAG_ELEMENT_ITEM_EXPORT) )
219     {
220         OUString aValue;
221         if( QueryXMLValue(rItem, aValue,
222                           static_cast< sal_uInt16 >(
223                                         rEntry.nMemberId & MID_SW_FLAG_MASK ),
224                              rUnitConverter ) )
225         {
226             OUString sName(
227                 rNamespaceMap.GetQNameByKey( rEntry.nNameSpace,
228                                              GetXMLToken(rEntry.eLocalName)));
229             rAttrList.AddAttribute( sName, aValue );
230         }
231     }
232 }
233 
exportElementItems(SvXMLExport & rExport,const SvXMLUnitConverter & rUnitConverter,const SfxItemSet & rSet,sal_uInt16 nFlags,const SvUShorts & rIndexArray) const234 void SvXMLExportItemMapper::exportElementItems(
235                           SvXMLExport& rExport,
236                           const SvXMLUnitConverter& rUnitConverter,
237                           const SfxItemSet &rSet,
238                           sal_uInt16 nFlags,
239                           const SvUShorts& rIndexArray ) const
240 {
241     const sal_uInt16 nCount = rIndexArray.Count();
242 
243     sal_Bool bItemsExported = sal_False;
244     for( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
245     {
246         const sal_uInt16 nElement = rIndexArray.GetObject( nIndex );
247         SvXMLItemMapEntry* pEntry = mrMapEntries->getByIndex( nElement );
248         DBG_ASSERT( 0 != (pEntry->nMemberId & MID_SW_FLAG_ELEMENT_ITEM_EXPORT),
249                     "wrong mid flag!" );
250 
251         const SfxPoolItem* pItem = GetItem( rSet, pEntry->nWhichId, nFlags );
252         // do we have an item?
253         if(pItem)
254         {
255             rExport.IgnorableWhitespace();
256             handleElementItem( rExport, *pEntry, *pItem, rUnitConverter,
257                                rSet, nFlags);
258             bItemsExported = sal_True;
259         }
260     }
261 
262     if( bItemsExported )
263         rExport.IgnorableWhitespace();
264 }
265 
266 /** returns the item with the givin WhichId from the given ItemSet if its
267     set or its default item if its not set and the XML_EXPORT_FLAG_DEEP
268     is set in the flags
269 */
GetItem(const SfxItemSet & rSet,sal_uInt16 nWhichId,sal_uInt16 nFlags)270 const SfxPoolItem* SvXMLExportItemMapper::GetItem( const SfxItemSet& rSet,
271                                                    sal_uInt16 nWhichId,
272                                                    sal_uInt16 nFlags )
273 {
274     // first get item from itemset
275     const SfxPoolItem* pItem;
276     SfxItemState eState =
277         rSet.GetItemState( nWhichId,
278                            ( nFlags & XML_EXPORT_FLAG_DEEP ) != 0,
279                            &pItem );
280 
281     if( SFX_ITEM_SET == eState )
282     {
283         return pItem;
284     }
285     else if( (nFlags & XML_EXPORT_FLAG_DEFAULTS) != 0 &&
286               SFX_WHICH_MAX > nWhichId )
287     {
288         // if its not set, try the pool if we export defaults
289         return &rSet.GetPool()->GetDefaultItem(nWhichId);
290     }
291     else
292     {
293         return NULL;
294     }
295 }
296 
SvXMLExportItemMapper(SvXMLItemMapEntriesRef rMapEntries)297 SvXMLExportItemMapper::SvXMLExportItemMapper( SvXMLItemMapEntriesRef rMapEntries )
298 {
299     mrMapEntries = rMapEntries;
300 }
301 
~SvXMLExportItemMapper()302 SvXMLExportItemMapper::~SvXMLExportItemMapper()
303 {
304 }
305 
exportXML(SvXMLExport & rExport,const SfxItemSet & rSet,const SvXMLUnitConverter & rUnitConverter,XMLTokenEnum ePropToken,sal_uInt16 nFlags) const306 void SvXMLExportItemMapper::exportXML( SvXMLExport& rExport,
307                     const SfxItemSet& rSet,
308                     const SvXMLUnitConverter& rUnitConverter,
309                     XMLTokenEnum ePropToken,
310                     sal_uInt16 nFlags ) const
311 {
312     SvUShorts aIndexArray;
313 
314     exportXML( rExport, rExport.GetAttrList(), rSet, rUnitConverter,
315                rExport.GetNamespaceMap(), nFlags, &aIndexArray );
316 
317     if( rExport.GetAttrList().getLength() > 0L ||
318         (nFlags & XML_EXPORT_FLAG_EMPTY) != 0 ||
319         aIndexArray.Count() != 0 )
320     {
321         if( (nFlags & XML_EXPORT_FLAG_IGN_WS) != 0 )
322         {
323             rExport.IgnorableWhitespace();
324         }
325 
326         SvXMLElementExport aElem( rExport, XML_NAMESPACE_STYLE, ePropToken,
327                                   sal_False, sal_False );
328         exportElementItems( rExport, rUnitConverter,
329                             rSet, nFlags, aIndexArray );
330     }
331 }
332 
333 /** this method is called for every item that has the
334     MID_SW_FLAG_SPECIAL_ITEM_EXPORT flag set */
handleSpecialItem(SvXMLAttributeList &,const SvXMLItemMapEntry &,const SfxPoolItem &,const SvXMLUnitConverter &,const SvXMLNamespaceMap &,const SfxItemSet *) const335 void SvXMLExportItemMapper::handleSpecialItem( SvXMLAttributeList& /*rAttrList*/,
336                                     const SvXMLItemMapEntry& /*rEntry*/,
337                                     const SfxPoolItem& /*rItem*/,
338                                     const SvXMLUnitConverter& /*rUnitConverter*/,
339                                     const SvXMLNamespaceMap& /*rNamespaceMap*/,
340                                     const SfxItemSet* /*pSet*/ /* = NULL */ ) const
341 {
342     DBG_ERROR( "special item not handled in xml export" );
343 }
344 
345 /** this method is called for every item that has the
346     MID_SW_FLAG_NO_ITEM_EXPORT flag set */
handleNoItem(SvXMLAttributeList &,const SvXMLItemMapEntry &,const SvXMLUnitConverter &,const SvXMLNamespaceMap &,const SfxItemSet &) const347 void SvXMLExportItemMapper::handleNoItem( SvXMLAttributeList& /*rAttrList*/,
348                                const SvXMLItemMapEntry& /*rEntry*/,
349                                const SvXMLUnitConverter& /*rUnitConverter*/,
350                                const SvXMLNamespaceMap& /*rNamespaceMap*/,
351                                const SfxItemSet& /*rSet*/ ) const
352 {
353     DBG_ERROR( "no item not handled in xml export" );
354 }
355 
356 /** this method is called for every item that has the
357     MID_SW_FLAG_ELEMENT_EXPORT flag set */
handleElementItem(SvXMLExport &,const SvXMLItemMapEntry &,const SfxPoolItem &,const SvXMLUnitConverter &,const SfxItemSet &,sal_uInt16) const358 void SvXMLExportItemMapper::handleElementItem(
359                         SvXMLExport& /*rExport*/,
360                         const SvXMLItemMapEntry& /*rEntry*/,
361                         const SfxPoolItem& /*rItem*/,
362                         const SvXMLUnitConverter& /*rUnitConverter*/,
363                         const SfxItemSet& /*rSet*/,
364                         sal_uInt16 /*nFlags*/ ) const
365 {
366     DBG_ERROR( "element item not handled in xml export" );
367 }
368 
369 
QueryXMLValue(const SfxPoolItem & rItem,OUString & rValue,sal_uInt16 nMemberId,const SvXMLUnitConverter & rUnitConverter)370 sal_Bool SvXMLExportItemMapper::QueryXMLValue(
371     const SfxPoolItem& rItem,
372     OUString& rValue,
373     sal_uInt16 nMemberId,
374     const SvXMLUnitConverter& rUnitConverter )
375 {
376     sal_Bool bOk = sal_False;
377     OUStringBuffer aOut;
378 
379     switch ( rItem.Which() )
380     {
381 
382         case RES_LR_SPACE:
383         {
384             const SvxLRSpaceItem* pLRSpace = PTR_CAST(SvxLRSpaceItem, &rItem);
385             DBG_ASSERT( pLRSpace != NULL, "Wrong Which-ID!" );
386 
387             bOk = sal_True;
388             switch( nMemberId )
389             {
390                 case  MID_L_MARGIN:
391                     if(pLRSpace->GetPropLeft() != 100)
392                         rUnitConverter.convertPercent( aOut, pLRSpace->GetPropLeft() );
393                     else
394                         rUnitConverter.convertMeasure( aOut, pLRSpace->GetLeft() );
395                     break;
396 
397                 case  MID_R_MARGIN:
398                     if(pLRSpace->GetPropRight() != 100)
399                         rUnitConverter.convertPercent( aOut, pLRSpace->GetPropRight() );
400                     else
401                         rUnitConverter.convertMeasure( aOut, pLRSpace->GetRight() );
402                     break;
403 
404                 case MID_FIRST_AUTO:
405                     if( pLRSpace->IsAutoFirst() )
406                         rUnitConverter.convertBool( aOut, pLRSpace->IsAutoFirst() );
407                     else
408                         bOk = sal_False;
409                     break;
410 
411                 case  MID_FIRST_LINE_INDENT:
412                     if( !pLRSpace->IsAutoFirst() )
413                     {
414                         if(pLRSpace->GetPropTxtFirstLineOfst() != 100)
415                             rUnitConverter.convertPercent(
416                                 aOut, pLRSpace->GetPropTxtFirstLineOfst() );
417                         else
418                             rUnitConverter.convertMeasure( aOut, pLRSpace->GetTxtFirstLineOfst() );
419                     }
420                     else
421                         bOk = sal_False;
422                     break;
423 
424                 default:
425                     DBG_ERROR( "unknown member id!");
426                     bOk = sal_False;
427                     break;
428             }
429         }
430         break;
431 
432         case RES_UL_SPACE:
433         {
434             const SvxULSpaceItem* pULSpace = PTR_CAST(SvxULSpaceItem, &rItem);
435             DBG_ASSERT( pULSpace != NULL, "Wrong Which-ID!" );
436 
437             switch( nMemberId )
438             {
439                 case MID_UP_MARGIN:
440                     if( pULSpace->GetPropUpper() != 100 )
441                         rUnitConverter.convertPercent( aOut, pULSpace->GetPropUpper() );
442                     else
443                         rUnitConverter.convertMeasure( aOut, pULSpace->GetUpper() );
444                     break;
445 
446                 case MID_LO_MARGIN:
447                     if( pULSpace->GetPropLower() != 100 )
448                         rUnitConverter.convertPercent( aOut, pULSpace->GetPropLower() );
449                     else
450                         rUnitConverter.convertMeasure( aOut, pULSpace->GetLower() );
451                     break;
452 
453                 default:
454                     DBG_ERROR("unknown MemberId");
455             };
456 
457             bOk = sal_True;
458         }
459         break;
460 
461         case RES_SHADOW:
462         {
463             const SvxShadowItem* pShadow = PTR_CAST(SvxShadowItem, &rItem);
464             DBG_ASSERT( pShadow != NULL, "Wrong Which-ID" );
465 
466             sal_Int32 nX = 1, nY = 1;
467             switch( pShadow->GetLocation() )
468                 {
469                 case SVX_SHADOW_TOPLEFT:
470                     nX = -1;
471                     nY = -1;
472                     break;
473                 case SVX_SHADOW_TOPRIGHT:
474                     nY = -1;
475                     break;
476                 case SVX_SHADOW_BOTTOMLEFT:
477                     nX = -1;
478                     break;
479                 case SVX_SHADOW_BOTTOMRIGHT:
480                     break;
481                 case SVX_SHADOW_NONE:
482                 default:
483                     rValue = GetXMLToken(XML_NONE);
484                     return sal_True;
485                 }
486 
487             nX *= pShadow->GetWidth();
488             nY *= pShadow->GetWidth();
489 
490             rUnitConverter.convertColor( aOut, pShadow->GetColor() );
491             aOut.append( sal_Unicode(' ') );
492             rUnitConverter.convertMeasure( aOut, nX );
493             aOut.append( sal_Unicode(' ') );
494             rUnitConverter.convertMeasure( aOut, nY );
495 
496             bOk = sal_True;
497         }
498         break;
499 
500         case RES_BOX:
501         {
502             SvxBoxItem* pBox = PTR_CAST(SvxBoxItem, &rItem);
503             DBG_ASSERT( pBox != NULL, "Wrong WHich-ID" );
504 
505             /**
506                xml -> MemberId
507 
508                border-padding           ALL_BORDER_PADDING
509                border-padding-before    LEFT_BORDER_PADDING
510                border-padding-after RIGHT_BORDER_PADDING
511                border-padding-start TOP_BORDER_PADDING
512                border-padding-end       BOTTOM_BORDER_PADDING
513 
514                border                   ALL_BORDER
515                border-before            LEFT_BORDER
516                border-after         RIGHT_BORDER
517                border-start         TOP_BORDER
518                border-end               BOTTOM_BORDER
519 
520                border-line-width            ALL_BORDER_LINE_WIDTH
521                border-line-width-before LEFT_BORDER_LINE_WIDTH
522                border-line-width-after      RIGHT_BORDER_LINE_WIDTH
523                border-line-width-start      TOP_BORDER_LINE_WIDTH
524                border-line-width-end        BOTTOM_BORDER_LINE_WIDTH
525             */
526 
527             const SvxBorderLine* pLeft    = pBox->GetLeft();
528             const SvxBorderLine* pRight   = pBox->GetRight();
529             const SvxBorderLine* pTop     = pBox->GetTop();
530             const SvxBorderLine* pBottom  = pBox->GetBottom();
531             sal_uInt16 nTopDist     = pBox->GetDistance( BOX_LINE_TOP );
532             sal_uInt16 nBottomDist  = pBox->GetDistance( BOX_LINE_BOTTOM );
533             sal_uInt16 nLeftDist    = pBox->GetDistance( BOX_LINE_LEFT );
534             sal_uInt16 nRightDist   = pBox->GetDistance( BOX_LINE_RIGHT );
535 
536 
537             // check if we need to export it
538             switch( nMemberId )
539             {
540                 case ALL_BORDER_PADDING:
541                 case LEFT_BORDER_PADDING:
542                 case RIGHT_BORDER_PADDING:
543                 case TOP_BORDER_PADDING:
544                 case BOTTOM_BORDER_PADDING:
545                 {
546                     sal_Bool bEqual = nLeftDist == nRightDist &&
547                                       nLeftDist == nTopDist &&
548                                       nLeftDist == nBottomDist;
549                     // don't export individual paddings if all paddings are equal and
550                     // don't export all padding if some paddings are not equal
551                     if( (bEqual && ALL_BORDER_PADDING != nMemberId) ||
552                         (!bEqual && ALL_BORDER_PADDING == nMemberId) )
553                         return sal_False;
554                 }
555                 break;
556                 case ALL_BORDER:
557                 case LEFT_BORDER:
558                 case RIGHT_BORDER:
559                 case TOP_BORDER:
560                 case BOTTOM_BORDER:
561                 {
562                     sal_Bool bEqual = ( NULL == pTop && NULL == pBottom &&
563                                         NULL == pLeft && NULL == pRight ) ||
564                                       ( pTop && pBottom && pLeft && pRight &&
565                                        *pTop == *pBottom  && *pTop == *pLeft &&
566                                         *pTop == *pRight );
567 
568                     // don't export individual borders if all are the same and
569                     // don't export all borders if some are not equal
570                     if( (bEqual && ALL_BORDER != nMemberId) ||
571                         (!bEqual && ALL_BORDER == nMemberId) )
572                         return sal_False;
573                 }
574                 break;
575                 case ALL_BORDER_LINE_WIDTH:
576                 case LEFT_BORDER_LINE_WIDTH:
577                 case RIGHT_BORDER_LINE_WIDTH:
578                 case TOP_BORDER_LINE_WIDTH:
579                 case BOTTOM_BORDER_LINE_WIDTH:
580                 {
581                     // if no line is set, there is nothing to export
582                     if( !pTop && !pBottom && !pLeft && !pRight )
583                         return sal_False;
584 
585                     sal_Bool bEqual = NULL != pTop &&
586                                       NULL != pBottom &&
587                                       NULL != pLeft &&
588                                       NULL != pRight;
589 
590                     if( bEqual )
591                     {
592                         const sal_uInt16 nDistance = pTop->GetDistance();
593                         const sal_uInt16 nInWidth  = pTop->GetInWidth();
594                         const sal_uInt16 nOutWidth = pTop->GetOutWidth();
595 
596                         bEqual = nDistance == pLeft->GetDistance() &&
597                                  nInWidth  == pLeft->GetInWidth()  &&
598                                  nOutWidth == pLeft->GetOutWidth() &&
599                                  nDistance == pRight->GetDistance()  &&
600                                  nInWidth  == pRight->GetInWidth()   &&
601                                  nOutWidth == pRight->GetOutWidth()  &&
602                                  nDistance == pBottom->GetDistance()  &&
603                                  nInWidth  == pBottom->GetInWidth()   &&
604                                  nOutWidth == pBottom->GetOutWidth();
605                     }
606 
607                     switch( nMemberId )
608                     {
609                         case ALL_BORDER_LINE_WIDTH:
610                             if( !bEqual || pTop->GetDistance() == 0 )
611                                 return sal_False;
612                             break;
613                         case LEFT_BORDER_LINE_WIDTH:
614                             if( bEqual || NULL == pLeft ||
615                                 0 == pLeft->GetDistance() )
616                                 return sal_False;
617                             break;
618                         case RIGHT_BORDER_LINE_WIDTH:
619                             if( bEqual || NULL == pRight ||
620                                 0 == pRight->GetDistance() )
621                                 return sal_False;
622                             break;
623                         case TOP_BORDER_LINE_WIDTH:
624                             if( bEqual || NULL == pTop ||
625                                 0 == pTop->GetDistance() )
626                                 return sal_False;
627                             break;
628                         case BOTTOM_BORDER_LINE_WIDTH:
629                             if( bEqual || NULL == pBottom ||
630                                 0 == pBottom->GetDistance() )
631                                 return sal_False;
632                             break;
633                     }
634                 }
635                 break;
636             }
637 
638             // now export it export
639             switch( nMemberId )
640                 {
641                     // padding
642                 case ALL_BORDER_PADDING:
643                 case LEFT_BORDER_PADDING:
644                     rUnitConverter.convertMeasure( aOut, nLeftDist );
645                     break;
646                 case RIGHT_BORDER_PADDING:
647                     rUnitConverter.convertMeasure( aOut, nRightDist );
648                     break;
649                 case TOP_BORDER_PADDING:
650                     rUnitConverter.convertMeasure( aOut, nTopDist );
651                     break;
652                 case BOTTOM_BORDER_PADDING:
653                     rUnitConverter.convertMeasure( aOut, nBottomDist );
654                     break;
655 
656                     // border
657                 case ALL_BORDER:
658                 case LEFT_BORDER:
659                 case RIGHT_BORDER:
660                 case TOP_BORDER:
661                 case BOTTOM_BORDER:
662                 {
663                     const SvxBorderLine* pLine;
664                     switch( nMemberId )
665                     {
666                     case ALL_BORDER:
667                     case LEFT_BORDER:
668                         pLine = pLeft;
669                         break;
670                     case RIGHT_BORDER:
671                         pLine = pRight;
672                         break;
673                     case TOP_BORDER:
674                         pLine = pTop;
675                         break;
676                     case BOTTOM_BORDER:
677                         pLine = pBottom;
678                         break;
679                     default:
680                         pLine = NULL;
681                         break;
682                     }
683 
684                     if( NULL != pLine )
685                     {
686                         sal_Int32 nWidth = pLine->GetOutWidth();
687                         const sal_uInt16 nDistance = pLine->GetDistance();
688                         if( 0 != nDistance )
689                         {
690                             nWidth += nDistance;
691                             nWidth += pLine->GetInWidth();
692                         }
693 
694                         enum XMLTokenEnum eStyle =
695                             (0 == nDistance) ? XML_SOLID : XML_DOUBLE;
696 
697                         rUnitConverter.convertMeasure( aOut, nWidth );
698                         aOut.append( sal_Unicode( ' ' ) );
699                         aOut.append( GetXMLToken( eStyle ) );
700                         aOut.append( sal_Unicode( ' ' ) );
701                         rUnitConverter.convertColor( aOut, pLine->GetColor() );
702 
703                     }
704                     else
705                     {
706                         aOut.append( GetXMLToken(XML_NONE) );
707                     }
708                 }
709                 break;
710 
711                 // width
712                 case ALL_BORDER_LINE_WIDTH:
713                 case LEFT_BORDER_LINE_WIDTH:
714                 case RIGHT_BORDER_LINE_WIDTH:
715                 case TOP_BORDER_LINE_WIDTH:
716                 case BOTTOM_BORDER_LINE_WIDTH:
717                     const SvxBorderLine* pLine;
718                     switch( nMemberId )
719                     {
720                     case ALL_BORDER_LINE_WIDTH:
721                     case LEFT_BORDER_LINE_WIDTH:
722                         pLine = pLeft;
723                         break;
724                     case RIGHT_BORDER_LINE_WIDTH:
725                         pLine = pRight;
726                         break;
727                     case TOP_BORDER_LINE_WIDTH:
728                         pLine = pTop;
729                         break;
730                     case BOTTOM_BORDER_LINE_WIDTH:
731                         pLine = pBottom;
732                         break;
733                     default:
734                         return sal_False;
735                     }
736                     rUnitConverter.convertMeasure( aOut, pLine->GetInWidth() );
737                     aOut.append( sal_Unicode( ' ' ) );
738                     rUnitConverter.convertMeasure( aOut, pLine->GetDistance() );
739                     aOut.append( sal_Unicode( ' ' ) );
740                     rUnitConverter.convertMeasure( aOut, pLine->GetOutWidth() );
741                     break;
742                 }
743 
744             bOk = sal_True;
745         }
746         break;
747 
748         case RES_BREAK:
749         {
750             const SvxFmtBreakItem* pFmtBreak = PTR_CAST(SvxFmtBreakItem, &rItem);
751             DBG_ASSERT( pFmtBreak != NULL, "Wrong Which-ID" );
752 
753             sal_uInt16 eEnum = 0;
754 
755             switch( nMemberId )
756             {
757             case MID_BREAK_BEFORE:
758                 switch( pFmtBreak->GetValue() )
759                 {
760                     case SVX_BREAK_COLUMN_BEFORE:
761                         eEnum = 1;
762                         break;
763                     case SVX_BREAK_PAGE_BEFORE:
764                         eEnum = 2;
765                         break;
766                     case SVX_BREAK_NONE:
767                         eEnum = 0;
768                         break;
769                     default:
770                         return sal_False;
771                 }
772                 break;
773             case MID_BREAK_AFTER:
774                 switch( pFmtBreak->GetValue() )
775                 {
776                     case SVX_BREAK_COLUMN_AFTER:
777                         eEnum = 1;
778                         break;
779                     case SVX_BREAK_PAGE_AFTER:
780                         eEnum = 2;
781                         break;
782                     case SVX_BREAK_NONE:
783                         eEnum = 0;
784                         break;
785                     default:
786                         return sal_False;
787                 }
788                 break;
789             }
790 
791             bOk = rUnitConverter.convertEnum( aOut, eEnum, psXML_BreakType );
792         }
793         break;
794 
795         case RES_KEEP:
796         {
797             SvxFmtKeepItem* pFmtKeep = PTR_CAST(SvxFmtKeepItem, &rItem);
798             DBG_ASSERT( pFmtKeep != NULL, "Wrong Which-ID" );
799 
800             aOut.append( pFmtKeep->GetValue()
801                          ? GetXMLToken( XML_ALWAYS )
802                          : GetXMLToken( XML_AUTO ) );
803             bOk = sal_True;
804         }
805         break;
806 
807         case RES_BACKGROUND:
808         {
809             SvxBrushItem* pBrush = PTR_CAST(SvxBrushItem, &rItem);
810             DBG_ASSERT( pBrush != NULL, "Wrong Which-ID" );
811 
812             // note: the graphic is only exported if nMemberId equals
813             //       MID_GRAPHIC..
814             //       If not, only the color or transparency is exported
815 
816             switch( nMemberId )
817             {
818                 case MID_BACK_COLOR:
819                     if ( pBrush->GetColor().GetTransparency() )
820                         aOut.append( GetXMLToken(XML_TRANSPARENT) );
821                     else
822                         rUnitConverter.convertColor( aOut, pBrush->GetColor());
823                     bOk = sal_True;
824                     break;
825 
826                 case MID_GRAPHIC_LINK:
827                     if( pBrush->GetGraphicPos() != GPOS_NONE )
828                     {
829                         uno::Any aAny;
830                         pBrush->QueryValue( aAny, MID_GRAPHIC_URL );
831                         OUString sTmp;
832                         aAny >>= sTmp;
833                         aOut.append( sTmp );
834                         bOk = sal_True;
835                     }
836                     break;
837 
838                 case MID_GRAPHIC_POSITION:
839                     switch( pBrush->GetGraphicPos() )
840                     {
841                     case GPOS_LT:
842                     case GPOS_MT:
843                     case GPOS_RT:
844                         aOut.append( GetXMLToken(XML_TOP) );
845                         bOk = sal_True;
846                         break;
847                     case GPOS_LM:
848                     case GPOS_MM:
849                     case GPOS_RM:
850                         aOut.append( GetXMLToken(XML_CENTER) );
851                         bOk = sal_True;
852                         break;
853                     case GPOS_LB:
854                     case GPOS_MB:
855                     case GPOS_RB:
856                         aOut.append( GetXMLToken(XML_BOTTOM) );
857                         bOk = sal_True;
858                         break;
859                     default:
860                         ;
861                     }
862 
863                     if( bOk )
864                     {
865                         aOut.append( sal_Unicode( ' ' ) );
866 
867                         switch( pBrush->GetGraphicPos() )
868                         {
869                         case GPOS_LT:
870                         case GPOS_LB:
871                         case GPOS_LM:
872                             aOut.append( GetXMLToken(XML_LEFT) );
873                             break;
874                         case GPOS_MT:
875                         case GPOS_MM:
876                         case GPOS_MB:
877                             aOut.append( GetXMLToken(XML_CENTER) );
878                             break;
879                         case GPOS_RM:
880                         case GPOS_RT:
881                         case GPOS_RB:
882                             aOut.append( GetXMLToken(XML_RIGHT) );
883                             break;
884                         default:
885                             ;
886                         }
887                     }
888                     break;
889 
890                 case MID_GRAPHIC_REPEAT:
891                 {
892                     SvxGraphicPosition eGraphicPos = pBrush->GetGraphicPos();
893                     if( GPOS_AREA == eGraphicPos )
894                     {
895                         aOut.append( GetXMLToken(XML_BACKGROUND_STRETCH)  );
896                         bOk = sal_True;
897                     }
898                     else if( GPOS_NONE != eGraphicPos && GPOS_TILED != eGraphicPos  )
899                     {
900                         aOut.append( GetXMLToken(XML_BACKGROUND_NO_REPEAT) );
901                         bOk = sal_True;
902                     }
903                 }
904                 break;
905 
906                 case MID_GRAPHIC_FILTER:
907                     if( pBrush->GetGraphicPos() != GPOS_NONE &&
908                         pBrush->GetGraphicFilter() )
909                     {
910                         aOut.append( pBrush->GetGraphicFilter()->GetBuffer() );
911                         bOk = sal_True;
912                     }
913                     break;
914             }
915         }
916         break;
917 
918         case RES_PAGEDESC:
919         {
920             const SwFmtPageDesc* pPageDesc = PTR_CAST(SwFmtPageDesc, &rItem);
921             DBG_ASSERT( pPageDesc != NULL, "Wrong Which-ID" );
922 
923             if( MID_PAGEDESC_PAGENUMOFFSET==nMemberId )
924             {
925                 sal_Int32 const number(pPageDesc->GetNumOffset());
926                 if (0 >= number)
927                 {
928                     aOut.append(GetXMLToken(XML_AUTO));
929                 }
930                 else // #i114163# positiveInteger only!
931                 {
932                     rUnitConverter.convertNumber(aOut, number);
933                 }
934                 bOk = sal_True;
935             }
936         }
937         break;
938 
939         case RES_LAYOUT_SPLIT:
940         case RES_ROW_SPLIT:
941         {
942             const SfxBoolItem* pSplit = PTR_CAST(SfxBoolItem, &rItem);
943             DBG_ASSERT( pSplit != NULL, "Wrong Which-ID" );
944 
945             rUnitConverter.convertBool( aOut, pSplit->GetValue() );
946             bOk = sal_True;
947         }
948         break;
949 
950         case RES_HORI_ORIENT:
951         {
952             SwFmtHoriOrient* pHoriOrient = PTR_CAST(SwFmtHoriOrient, &rItem);
953             DBG_ASSERT( pHoriOrient != NULL, "Wrong Which-ID" );
954 
955             rUnitConverter.convertEnum( aOut, pHoriOrient->GetHoriOrient(),
956                                         aXMLTableAlignMap );
957             bOk = sal_True;
958         }
959         break;
960 
961         case RES_VERT_ORIENT:
962         {
963             SwFmtVertOrient* pVertOrient = PTR_CAST(SwFmtVertOrient, &rItem);
964             DBG_ASSERT( pVertOrient != NULL, "Wrong Which-ID" );
965 
966             rUnitConverter.convertEnum( aOut, pVertOrient->GetVertOrient(),
967                                         aXMLTableVAlignMap );
968             bOk = sal_True;
969         }
970         break;
971 
972         case RES_FRM_SIZE:
973         {
974             SwFmtFrmSize* pFrmSize = PTR_CAST(SwFmtFrmSize, &rItem);
975             DBG_ASSERT( pFrmSize != NULL, "Wrong Which-ID" );
976 
977             sal_Bool bOutHeight = sal_False;
978             switch( nMemberId )
979             {
980                 case MID_FRMSIZE_REL_WIDTH:
981                     if( pFrmSize->GetWidthPercent() )
982                     {
983                         rUnitConverter.convertPercent( aOut, pFrmSize->GetWidthPercent() );
984                         bOk = sal_True;
985                     }
986                     break;
987                 case MID_FRMSIZE_MIN_HEIGHT:
988                     if( ATT_MIN_SIZE == pFrmSize->GetHeightSizeType() )
989                         bOutHeight = sal_True;
990                     break;
991                 case MID_FRMSIZE_FIX_HEIGHT:
992                     if( ATT_FIX_SIZE == pFrmSize->GetHeightSizeType() )
993                         bOutHeight = sal_True;
994                     break;
995             }
996 
997             if( bOutHeight )
998             {
999                 rUnitConverter.convertMeasure( aOut, pFrmSize->GetHeight() );
1000                 bOk = sal_True;
1001             }
1002         }
1003         break;
1004 
1005         case RES_FRAMEDIR:
1006         {
1007             Any aAny;
1008             bOk = rItem.QueryValue( aAny );
1009             if( bOk )
1010             {
1011                 const XMLPropertyHandler* pWritingModeHandler =
1012                     XMLPropertyHandlerFactory::CreatePropertyHandler(
1013                         XML_TYPE_TEXT_WRITING_MODE_WITH_DEFAULT );
1014                 OUString sValue;
1015                 bOk = pWritingModeHandler->exportXML( sValue, aAny,
1016                                                       rUnitConverter );
1017                 if( bOk )
1018                     aOut.append( sValue );
1019 
1020                 delete pWritingModeHandler;  // memory leak #i120072#
1021             }
1022         }
1023         break;
1024 
1025         case RES_COLLAPSING_BORDERS:
1026         {
1027             const SfxBoolItem* pBorders = PTR_CAST(SfxBoolItem, &rItem);
1028             DBG_ASSERT( pBorders != NULL, "Wrong RES-ID" );
1029 
1030             aOut.append( pBorders->GetValue()
1031                          ? GetXMLToken( XML_COLLAPSING )
1032                          : GetXMLToken( XML_SEPARATING ) );
1033             bOk = sal_True;
1034         }
1035         break;
1036 
1037         default:
1038             DBG_ERROR("GetXMLValue not implemented for this item.");
1039             break;
1040     }
1041 
1042     if ( bOk )
1043         rValue = aOut.makeStringAndClear();
1044 
1045     return bOk;
1046 }
1047