xref: /AOO41X/main/sw/source/filter/xml/xmltble.cxx (revision efeef26f81c84063fb0a91bde3856d4a51172d90)
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 
27 #include <com/sun/star/text/XTextTable.hpp>
28 #include <com/sun/star/text/XTextSection.hpp>
29 
30 #include <hintids.hxx>
31 #include <rtl/ustrbuf.hxx>
32 #include <xmloff/xmlnmspe.hxx>
33 #include <xmloff/xmltoken.hxx>
34 #include <xmloff/xmluconv.hxx>
35 #include <xmloff/numehelp.hxx>
36 #include <svl/cntnrsrt.hxx>
37 #include <svl/zforlist.hxx>
38 #include <editeng/brshitem.hxx>
39 #include <editeng/boxitem.hxx>
40 #include <fmtrowsplt.hxx>
41 #include <editeng/frmdiritem.hxx>
42 #include <list>
43 #include "swtable.hxx"
44 #include "doc.hxx"
45 #include "pam.hxx"
46 #include "frmfmt.hxx"
47 #include "wrtswtbl.hxx"
48 #include "fmtfsize.hxx"
49 #include "fmtornt.hxx"
50 #include "cellatr.hxx"
51 #include "ddefld.hxx"
52 #include "swddetbl.hxx"
53 #include <ndole.hxx>
54 #include <xmloff/nmspmap.hxx>
55 #include <sfx2/linkmgr.hxx>  // for cTokenSeperator
56 #include "unotbl.hxx"
57 #include "xmltexte.hxx"
58 #include "xmlexp.hxx"
59 
60 
61 using ::rtl::OUString;
62 using ::rtl::OUStringBuffer;
63 using namespace ::com::sun::star;
64 using namespace ::com::sun::star::uno;
65 using namespace ::com::sun::star::text;
66 using namespace ::com::sun::star::beans;
67 using namespace ::com::sun::star::lang;
68 using namespace ::com::sun::star::container;
69 using namespace ::xmloff::token;
70 using table::XCell;
71 
72 
73 class SwXMLTableColumn_Impl : public SwWriteTableCol
74 {
75     OUString    sStyleName;
76     sal_uInt32  nRelWidth;
77 
78 public:
79 
80 
SwXMLTableColumn_Impl(sal_uInt32 nPosition)81     SwXMLTableColumn_Impl( sal_uInt32 nPosition ) :
82         SwWriteTableCol( nPosition ),
83         nRelWidth( 0UL )
84     {};
85 
SetStyleName(const OUString & rName)86     void SetStyleName( const OUString& rName ) { sStyleName = rName; }
GetStyleName() const87     const OUString& GetStyleName() const { return sStyleName; }
88 
SetRelWidth(sal_uInt32 nSet)89     void SetRelWidth( sal_uInt32 nSet ) { nRelWidth = nSet; }
GetRelWidth() const90     sal_uInt32 GetRelWidth() const { return nRelWidth; }
91 };
92 
SwXMLTableColumnCmpWidth_Impl(const SwXMLTableColumn_Impl & r1,const SwXMLTableColumn_Impl & r2)93 sal_Int32 SwXMLTableColumnCmpWidth_Impl( const SwXMLTableColumn_Impl& r1,
94                                          const SwXMLTableColumn_Impl& r2 )
95 {
96     sal_Int32 n = (sal_Int32)r1.GetWidthOpt() - (sal_Int32)r2.GetWidthOpt();
97     if( !n )
98         n = (sal_Int32)r1.GetRelWidth() - (sal_Int32)r2.GetRelWidth();
99     return n;
100 }
101 
102 // ---------------------------------------------------------------------
103 
104 typedef SwXMLTableColumn_Impl *SwXMLTableColumnPtr;
105 SV_DECL_PTRARR_SORT_DEL( SwXMLTableColumns_Impl, SwXMLTableColumnPtr, 5, 5 )
106 SV_IMPL_OP_PTRARR_SORT( SwXMLTableColumns_Impl, SwXMLTableColumnPtr )
107 
108 DECLARE_CONTAINER_SORT( SwXMLTableColumnsSortByWidth_Impl,
109                         SwXMLTableColumn_Impl )
110 IMPL_CONTAINER_SORT( SwXMLTableColumnsSortByWidth_Impl, SwXMLTableColumn_Impl,
111                      SwXMLTableColumnCmpWidth_Impl )
112 
113 class SwXMLTableLines_Impl
114 {
115     SwXMLTableColumns_Impl  aCols;
116     const SwTableLines      *pLines;
117     sal_uInt32              nWidth;
118 
119 public:
120 
121     SwXMLTableLines_Impl( const SwTableLines& rLines );
122 
~SwXMLTableLines_Impl()123     ~SwXMLTableLines_Impl() {}
124 
GetWidth() const125     sal_uInt32 GetWidth() const { return nWidth; }
GetLines() const126     const SwTableLines *GetLines() const { return pLines; }
127 
GetColumns() const128     const SwXMLTableColumns_Impl& GetColumns() const { return aCols; }
129 };
130 
SwXMLTableLines_Impl(const SwTableLines & rLines)131 SwXMLTableLines_Impl::SwXMLTableLines_Impl( const SwTableLines& rLines ) :
132     pLines( &rLines ),
133     nWidth( 0UL )
134 {
135 #ifdef DBG_UTIL
136     sal_uInt32 nEndCPos = 0U;
137 #endif
138     sal_uInt16 nLines = rLines.Count();
139     sal_uInt16 nLine;
140     for( nLine=0U; nLine<nLines; nLine++ )
141     {
142         const SwTableLine *pLine = rLines[nLine];
143         const SwTableBoxes& rBoxes = pLine->GetTabBoxes();
144         sal_uInt16 nBoxes = rBoxes.Count();
145 
146         sal_uInt32 nCPos = 0U;
147         for( sal_uInt16 nBox=0U; nBox<nBoxes; nBox++ )
148         {
149             const SwTableBox *pBox = rBoxes[nBox];
150 
151             if( nBox < nBoxes-1U || nWidth==0UL )
152             {
153                 nCPos = nCPos + SwWriteTable::GetBoxWidth( pBox );
154                 SwXMLTableColumn_Impl *pCol =
155                     new SwXMLTableColumn_Impl( nCPos );
156 
157                 if( !aCols.Insert( pCol ) )
158                     delete pCol;
159 
160                 if( nBox==nBoxes-1U )
161                 {
162                     ASSERT( nLine==0U && nWidth==0UL,
163                             "parent width will be lost" );
164                     nWidth = nCPos;
165                 }
166             }
167             else
168             {
169 #ifdef DBG_UTIL
170                 sal_uInt32 nCheckPos =
171                     nCPos + SwWriteTable::GetBoxWidth( pBox );
172                 if( !nEndCPos )
173                 {
174                     nEndCPos = nCheckPos;
175                 }
176                 else
177                 {
178                     /*
179                     ASSERT( SwXMLTableColumn_impl(nCheckPos) ==
180                                         SwXMLTableColumn_Impl(nEndCPos),
181                     "rows have different total widths" );
182                     */
183                 }
184 #endif
185                 nCPos = nWidth;
186 #ifdef DBG_UTIL
187                 SwXMLTableColumn_Impl aCol( nWidth );
188                 ASSERT( aCols.Seek_Entry(&aCol), "couldn't find last column" );
189                 ASSERT( SwXMLTableColumn_Impl(nCheckPos) ==
190                                             SwXMLTableColumn_Impl(nCPos),
191                         "rows have different total widths" );
192 #endif
193             }
194         }
195     }
196 }
197 
198 typedef SwXMLTableLines_Impl *SwXMLTableLinesPtr;
199 DECLARE_LIST( SwXMLTableLinesCache_Impl, SwXMLTableLinesPtr )
200 
201 // ---------------------------------------------------------------------
202 
203 typedef SwFrmFmt *SwFrmFmtPtr;
204 DECLARE_LIST( SwXMLFrmFmts_Impl, SwFrmFmtPtr )
205 
206 class SwXMLTableFrmFmtsSort_Impl : public SwXMLFrmFmts_Impl
207 {
208 public:
SwXMLTableFrmFmtsSort_Impl(sal_uInt16 nInit,sal_uInt16 nGrow)209     SwXMLTableFrmFmtsSort_Impl ( sal_uInt16 nInit, sal_uInt16 nGrow ) :
210         SwXMLFrmFmts_Impl( nInit, nGrow )
211     {}
212 
213     sal_Bool AddRow( SwFrmFmt& rFrmFmt, const OUString& rNamePrefix, sal_uInt32 nLine );
214     sal_Bool AddCell( SwFrmFmt& rFrmFmt, const OUString& rNamePrefix,
215                   sal_uInt32 nCol, sal_uInt32 nRow, sal_Bool bTop );
216 };
217 
AddRow(SwFrmFmt & rFrmFmt,const OUString & rNamePrefix,sal_uInt32 nLine)218 sal_Bool SwXMLTableFrmFmtsSort_Impl::AddRow( SwFrmFmt& rFrmFmt,
219                                          const OUString& rNamePrefix,
220                                          sal_uInt32 nLine )
221 {
222     const SwFmtFrmSize *pFrmSize = 0;
223     const SwFmtRowSplit* pRowSplit = 0;
224     const SvxBrushItem *pBrush = 0;
225 
226     const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
227     const SfxPoolItem *pItem;
228     if( SFX_ITEM_SET == rItemSet.GetItemState( RES_FRM_SIZE, sal_False, &pItem ) )
229         pFrmSize = (const SwFmtFrmSize *)pItem;
230 
231     if( SFX_ITEM_SET == rItemSet.GetItemState( RES_ROW_SPLIT, sal_False, &pItem ) )
232         pRowSplit = (const SwFmtRowSplit *)pItem;
233 
234     if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BACKGROUND, sal_False, &pItem ) )
235         pBrush = (const SvxBrushItem *)pItem;
236 
237     // empty styles have not to be exported
238     if( !pFrmSize && !pBrush && !pRowSplit )
239         return sal_False;
240 
241     // order is: -/brush, size/-, size/brush
242     sal_uInt32 nCount2 = Count();
243     sal_Bool bInsert = sal_True;
244     sal_uInt32 i;
245     for( i = 0; i < nCount2; ++i )
246     {
247         const SwFmtFrmSize *pTestFrmSize = 0;
248         const SwFmtRowSplit* pTestRowSplit = 0;
249         const SvxBrushItem *pTestBrush = 0;
250         const SwFrmFmt *pTestFmt = GetObject(i);
251         const SfxItemSet& rTestSet = pTestFmt->GetAttrSet();
252         if( SFX_ITEM_SET == rTestSet.GetItemState( RES_FRM_SIZE, sal_False,
253                                                   &pItem ) )
254         {
255             if( !pFrmSize )
256                 break;
257 
258             pTestFrmSize = (const SwFmtFrmSize *)pItem;
259         }
260         else
261         {
262             if( pFrmSize )
263                 continue;
264         }
265 
266         if( SFX_ITEM_SET == rTestSet.GetItemState( RES_BACKGROUND, sal_False,
267                                                   &pItem ) )
268         {
269             if( !pBrush )
270                 break;
271 
272             pTestBrush = (const SvxBrushItem *)pItem;
273         }
274         else
275         {
276             if( pBrush )
277                 continue;
278         }
279 
280         if( SFX_ITEM_SET == rTestSet.GetItemState( RES_ROW_SPLIT, sal_False,
281                                                   &pItem ) )
282         {
283             if( !pRowSplit )
284                 break;
285 
286             pTestRowSplit = (const SwFmtRowSplit *)pItem;
287         }
288         else
289         {
290             if( pRowSplit )
291                 continue;
292         }
293 
294 
295         if( pFrmSize &&
296             ( pFrmSize->GetHeightSizeType() != pTestFrmSize->GetHeightSizeType() ||
297               pFrmSize->GetHeight() != pTestFrmSize->GetHeight() ) )
298             continue;
299 
300         if( pBrush && (*pBrush != *pTestBrush) )
301             continue;
302 
303         if( pRowSplit && (!pRowSplit->GetValue() != !pTestRowSplit->GetValue()) )
304             continue;
305 
306         // found!
307         const String& rFmtName = pTestFmt->GetName();
308         rFrmFmt.SetName( rFmtName );
309         bInsert = sal_False;
310         break;
311     }
312 
313     if( bInsert )
314     {
315         OUStringBuffer sBuffer( rNamePrefix.getLength() + 4UL );
316         sBuffer.append( rNamePrefix );
317         sBuffer.append( (sal_Unicode)'.' );
318         sBuffer.append( (sal_Int32)(nLine+1UL) );
319 
320         rFrmFmt.SetName( sBuffer.makeStringAndClear() );
321         Insert( &rFrmFmt, i );
322     }
323 
324     return bInsert;
325 }
326 
327 void lcl_GetTblBoxColStr( sal_uInt16 nCol, String& rNm );
lcl_xmltble_appendBoxPrefix(OUStringBuffer & rBuffer,const OUString & rNamePrefix,sal_uInt32 nCol,sal_uInt32 nRow,sal_Bool bTop)328 void lcl_xmltble_appendBoxPrefix( OUStringBuffer& rBuffer,
329                                   const OUString& rNamePrefix,
330                                   sal_uInt32 nCol, sal_uInt32 nRow, sal_Bool bTop )
331 {
332     rBuffer.append( rNamePrefix );
333     rBuffer.append( (sal_Unicode)'.' );
334     if( bTop )
335     {
336         String sTmp;
337         lcl_GetTblBoxColStr( (sal_uInt16)nCol, sTmp );
338         rBuffer.append( sTmp );
339     }
340     else
341     {
342         rBuffer.append( (sal_Int32)(nCol + 1));
343         rBuffer.append( (sal_Unicode)'.' );
344     }
345     rBuffer.append( (sal_Int32)(nRow + 1));
346 }
347 
AddCell(SwFrmFmt & rFrmFmt,const OUString & rNamePrefix,sal_uInt32 nCol,sal_uInt32 nRow,sal_Bool bTop)348 sal_Bool SwXMLTableFrmFmtsSort_Impl::AddCell( SwFrmFmt& rFrmFmt,
349                                          const OUString& rNamePrefix,
350                                          sal_uInt32 nCol, sal_uInt32 nRow, sal_Bool bTop )
351 {
352     const SwFmtVertOrient *pVertOrient = 0;
353     const SvxBrushItem *pBrush = 0;
354     const SvxBoxItem *pBox = 0;
355     const SwTblBoxNumFormat *pNumFmt = 0;
356     const SvxFrameDirectionItem *pFrameDir = 0;
357 
358     const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
359     const SfxPoolItem *pItem;
360     if( SFX_ITEM_SET == rItemSet.GetItemState( RES_VERT_ORIENT, sal_False,
361                                                &pItem ) )
362         pVertOrient = (const SwFmtVertOrient *)pItem;
363 
364     if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BACKGROUND, sal_False, &pItem ) )
365         pBrush = (const SvxBrushItem *)pItem;
366 
367     if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BOX, sal_False, &pItem ) )
368         pBox = (const SvxBoxItem *)pItem;
369 
370     if ( SFX_ITEM_SET == rItemSet.GetItemState( RES_BOXATR_FORMAT,
371                                                 sal_False, &pItem ) )
372         pNumFmt = (const SwTblBoxNumFormat *)pItem;
373     if ( SFX_ITEM_SET == rItemSet.GetItemState( RES_FRAMEDIR,
374                                                 sal_False, &pItem ) )
375         pFrameDir = (const SvxFrameDirectionItem *)pItem;
376 
377     // empty styles have not to be exported
378     if( !pVertOrient && !pBrush && !pBox && !pNumFmt && !pFrameDir )
379         return sal_False;
380 
381     // order is: -/-/-/num,
382     //           -/-/box/-, --/-/box/num,
383     //           -/brush/-/-, -/brush/-/num, -/brush/box/-, -/brush/box/num,
384     //           vert/-/-/-, vert/-/-/num, vert/-/box/-, ver/-/box/num,
385     //           vert/brush/-/-, vert/brush/-/num, vert/brush/box/-,
386     //           vert/brush/box/num
387     sal_uInt32 nCount2 = Count();
388     sal_Bool bInsert = sal_True;
389     sal_uInt32 i;
390     for( i = 0; i < nCount2; ++i )
391     {
392         const SwFmtVertOrient *pTestVertOrient = 0;
393         const SvxBrushItem *pTestBrush = 0;
394         const SvxBoxItem *pTestBox = 0;
395         const SwTblBoxNumFormat *pTestNumFmt = 0;
396         const SvxFrameDirectionItem *pTestFrameDir = 0;
397         const SwFrmFmt *pTestFmt = GetObject(i);
398         const SfxItemSet& rTestSet = pTestFmt->GetAttrSet();
399         if( SFX_ITEM_SET == rTestSet.GetItemState( RES_VERT_ORIENT, sal_False,
400                                                   &pItem ) )
401         {
402             if( !pVertOrient )
403                 break;
404 
405             pTestVertOrient = (const SwFmtVertOrient *)pItem;
406         }
407         else
408         {
409             if( pVertOrient )
410                 continue;
411         }
412 
413         if( SFX_ITEM_SET == rTestSet.GetItemState( RES_BACKGROUND, sal_False,
414                                                   &pItem ) )
415         {
416             if( !pBrush )
417                 break;
418 
419             pTestBrush = (const SvxBrushItem *)pItem;
420         }
421         else
422         {
423             if( pBrush )
424                 continue;
425         }
426 
427         if( SFX_ITEM_SET == rTestSet.GetItemState( RES_BOX, sal_False, &pItem ) )
428         {
429             if( !pBox )
430                 break;
431 
432             pTestBox = (const SvxBoxItem *)pItem;
433         }
434         else
435         {
436             if( pBox )
437                 continue;
438         }
439 
440         if ( SFX_ITEM_SET == rTestSet.GetItemState( RES_BOXATR_FORMAT,
441                                                 sal_False, &pItem ) )
442         {
443             if( !pNumFmt )
444                 break;
445 
446             pTestNumFmt = (const SwTblBoxNumFormat *)pItem;
447         }
448         else
449         {
450             if( pNumFmt )
451                 continue;
452 
453         }
454 
455         if ( SFX_ITEM_SET == rTestSet.GetItemState( RES_FRAMEDIR,
456                                                 sal_False, &pItem ) )
457         {
458             if( !pFrameDir )
459                 break;
460 
461             pTestFrameDir = (const SvxFrameDirectionItem *)pItem;
462         }
463         else
464         {
465             if( pFrameDir )
466                 continue;
467 
468         }
469 
470         if( pVertOrient &&
471             pVertOrient->GetVertOrient() != pTestVertOrient->GetVertOrient() )
472             continue;
473 
474         if( pBrush && ( *pBrush != *pTestBrush ) )
475             continue;
476 
477         if( pBox && ( *pBox != *pTestBox ) )
478             continue;
479 
480         if( pNumFmt && pNumFmt->GetValue() != pTestNumFmt->GetValue() )
481             continue;
482 
483         if( pFrameDir && pFrameDir->GetValue() != pTestFrameDir->GetValue() )
484             continue;
485 
486         // found!
487         const String& rFmtName = pTestFmt->GetName();
488         rFrmFmt.SetName( rFmtName );
489         bInsert = sal_False;
490         break;
491     }
492 
493     if( bInsert )
494     {
495         OUStringBuffer sBuffer( rNamePrefix.getLength() + 8UL );
496         lcl_xmltble_appendBoxPrefix( sBuffer, rNamePrefix, nCol, nRow, bTop );
497         rFrmFmt.SetName( sBuffer.makeStringAndClear() );
498         Insert( &rFrmFmt, i );
499     }
500 
501     return bInsert;
502 }
503 // ---------------------------------------------------------------------
504 
505 class SwXMLTableInfo_Impl
506 {
507     const SwTable *pTable;
508     Reference < XTextSection > xBaseSection;
509     sal_Bool bBaseSectionValid;
510 
511 public:
512 
513     inline SwXMLTableInfo_Impl( const SwTable *pTbl );
514 
GetTable() const515     const SwTable *GetTable() const { return pTable; }
GetTblFmt() const516     const SwFrmFmt *GetTblFmt() const { return pTable->GetFrmFmt(); }
517 
IsBaseSectionValid() const518     sal_Bool IsBaseSectionValid() const { return bBaseSectionValid; }
GetBaseSection() const519     const Reference < XTextSection >& GetBaseSection() const { return xBaseSection; }
520     inline void SetBaseSection( const Reference < XTextSection >& rBase );
521 };
522 
SwXMLTableInfo_Impl(const SwTable * pTbl)523 inline SwXMLTableInfo_Impl::SwXMLTableInfo_Impl( const SwTable *pTbl ) :
524     pTable( pTbl ),
525     bBaseSectionValid( sal_False )
526 {
527 }
528 
SetBaseSection(const Reference<XTextSection> & rBaseSection)529 inline void SwXMLTableInfo_Impl::SetBaseSection(
530         const Reference < XTextSection >& rBaseSection )
531 {
532     xBaseSection = rBaseSection;
533     bBaseSectionValid = sal_True;
534 }
535 
536 // ---------------------------------------------------------------------
537 
538 
ExportTableColumnStyle(const SwXMLTableColumn_Impl & rCol)539 void SwXMLExport::ExportTableColumnStyle( const SwXMLTableColumn_Impl& rCol )
540 {
541     // <style:style ...>
542     CheckAttrList();
543 
544     // style:name="..."
545     sal_Bool bEncoded = sal_False;
546     AddAttribute( XML_NAMESPACE_STYLE, XML_NAME,
547                     EncodeStyleName( rCol.GetStyleName(), &bEncoded ) );
548     if( bEncoded )
549         AddAttribute( XML_NAMESPACE_STYLE, XML_DISPLAY_NAME, rCol.GetStyleName() );
550 
551     // style:family="table-column"
552     AddAttribute( XML_NAMESPACE_STYLE, XML_FAMILY, XML_TABLE_COLUMN );
553 
554     {
555         SvXMLElementExport aElem( *this, XML_NAMESPACE_STYLE, XML_STYLE, sal_True,
556                                   sal_True );
557         OUStringBuffer sValue;
558         if( rCol.GetWidthOpt() )
559         {
560             GetTwipUnitConverter().convertMeasure( sValue, rCol.GetWidthOpt() );
561             AddAttribute( XML_NAMESPACE_STYLE, XML_COLUMN_WIDTH,
562                           sValue.makeStringAndClear() );
563         }
564         if( rCol.GetRelWidth() )
565         {
566             sValue.append( (sal_Int32)rCol.GetRelWidth() );
567             sValue.append( (sal_Unicode)'*' );
568             AddAttribute( XML_NAMESPACE_STYLE, XML_REL_COLUMN_WIDTH,
569                           sValue.makeStringAndClear() );
570         }
571 
572         {
573             SvXMLElementExport aElemExport( *this, XML_NAMESPACE_STYLE,
574                                       XML_TABLE_COLUMN_PROPERTIES,
575                                       sal_True, sal_True );
576         }
577     }
578 }
579 
ExportTableLinesAutoStyles(const SwTableLines & rLines,sal_uInt32 nAbsWidth,sal_uInt32 nBaseWidth,const OUString & rNamePrefix,SwXMLTableColumnsSortByWidth_Impl & rExpCols,SwXMLTableFrmFmtsSort_Impl & rExpRows,SwXMLTableFrmFmtsSort_Impl & rExpCells,SwXMLTableInfo_Impl & rTblInfo,sal_Bool bTop)580 void SwXMLExport::ExportTableLinesAutoStyles( const SwTableLines& rLines,
581                                     sal_uInt32 nAbsWidth, sal_uInt32 nBaseWidth,
582                                     const OUString& rNamePrefix,
583                                     SwXMLTableColumnsSortByWidth_Impl& rExpCols,
584                                     SwXMLTableFrmFmtsSort_Impl& rExpRows,
585                                     SwXMLTableFrmFmtsSort_Impl& rExpCells,
586                                     SwXMLTableInfo_Impl& rTblInfo,
587                                     sal_Bool bTop )
588 {
589     // pass 1: calculate columns
590     SwXMLTableLines_Impl *pLines =
591         new SwXMLTableLines_Impl( rLines );
592     if( !pTableLines )
593         pTableLines = new SwXMLTableLinesCache_Impl( 5, 5 );
594     pTableLines->Insert( pLines, pTableLines->Count() );
595 
596     OUStringBuffer sBuffer( rNamePrefix.getLength() + 8L );
597 
598     // pass 2: export column styles
599     {
600         const SwXMLTableColumns_Impl& rCols = pLines->GetColumns();
601         sal_uInt32 nCPos = 0U;
602         sal_uInt16 nColumns = rCols.Count();
603         for( sal_uInt16 nColumn=0U; nColumn<nColumns; nColumn++ )
604         {
605             SwXMLTableColumn_Impl *pColumn = rCols[nColumn];
606 
607             sal_uInt32 nOldCPos = nCPos;
608             nCPos = pColumn->GetPos();
609 
610             sal_uInt32 nWidth = nCPos - nOldCPos;
611 
612             // If a base width is given, the table has either an automatic
613             // or margin alignment, or an percentage width. In either case,
614             // relative widths should be exported.
615             if( nBaseWidth )
616             {
617                 pColumn->SetRelWidth( nWidth );
618             }
619 
620             // If an absolute width is given, the table either has a fixed
621             // width, or the current width is known from the layout. In the
622             // later case, a base width is set in addition and must be used
623             // to "absoultize" the relative column width.
624             if( nAbsWidth )
625             {
626                 sal_uInt32 nColAbsWidth = nWidth;
627                 if( nBaseWidth )
628                 {
629                     nColAbsWidth *= nAbsWidth;
630                     nColAbsWidth += (nBaseWidth/2UL);
631                     nColAbsWidth /= nBaseWidth;
632                 }
633                 pColumn->SetWidthOpt( nColAbsWidth, sal_False );
634             }
635 
636             sal_uLong nExpPos = 0;
637             if( rExpCols.Seek_Entry( pColumn, &nExpPos ) )
638             {
639                 pColumn->SetStyleName(
640                         rExpCols.GetObject(nExpPos)->GetStyleName() );
641             }
642             else
643             {
644                 sBuffer.append( rNamePrefix );
645                 sBuffer.append( (sal_Unicode)'.' );
646                 if( bTop )
647                 {
648                     String sTmp;
649                     lcl_GetTblBoxColStr( nColumn, sTmp );
650                     sBuffer.append( sTmp );
651                 }
652                 else
653                 {
654                     sBuffer.append( (sal_Int32)(nColumn + 1U) );
655                 }
656 
657                 pColumn->SetStyleName( sBuffer.makeStringAndClear() );
658                 ExportTableColumnStyle( *pColumn );
659                 rExpCols.Insert( pColumn );
660             }
661         }
662     }
663 
664     // pass 3: export line/rows
665     sal_uInt16 nLines = rLines.Count();
666     for( sal_uInt16 nLine=0U; nLine<nLines; nLine++ )
667     {
668         SwTableLine *pLine = rLines[nLine];
669 
670         SwFrmFmt *pFrmFmt = pLine->GetFrmFmt();
671         if( rExpRows.AddRow( *pFrmFmt, rNamePrefix, nLine ) )
672             ExportFmt( *pFrmFmt, XML_TABLE_ROW );
673 
674         const SwTableBoxes& rBoxes = pLine->GetTabBoxes();
675         sal_uInt16 nBoxes = rBoxes.Count();
676 
677         sal_uInt32 nCPos = 0U;
678         sal_uInt16 nCol = 0U;
679         for( sal_uInt16 nBox=0U; nBox<nBoxes; nBox++ )
680         {
681             SwTableBox *pBox = rBoxes[nBox];
682 
683             if( nBox < nBoxes-1U )
684                 nCPos = nCPos + SwWriteTable::GetBoxWidth( pBox );
685             else
686                 nCPos = pLines->GetWidth();
687 
688 
689             // Und ihren Index
690             sal_uInt16 nOldCol = nCol;
691             SwXMLTableColumn_Impl aCol( nCPos );
692 #ifdef DBG_UTIL
693             sal_Bool bFound =
694 #endif
695                 pLines->GetColumns().Seek_Entry( &aCol, &nCol );
696             ASSERT( bFound, "couldn't find column" );
697 
698             const SwStartNode *pBoxSttNd = pBox->GetSttNd();
699             if( pBoxSttNd )
700             {
701                 SwFrmFmt *pFrmFmt2 = pBox->GetFrmFmt();
702                 if( rExpCells.AddCell( *pFrmFmt2, rNamePrefix, nOldCol, nLine,
703                                        bTop) )
704                     ExportFmt( *pFrmFmt2, XML_TABLE_CELL );
705 
706                 Reference < XCell > xCell = SwXCell::CreateXCell(
707                                                 (SwFrmFmt *)rTblInfo.GetTblFmt(),
708                                                   pBox,
709                                                  (SwTable *)rTblInfo.GetTable() );
710                 if (xCell.is())
711                 {
712                     Reference < XText > xText( xCell, UNO_QUERY );
713                     if( !rTblInfo.IsBaseSectionValid() )
714                     {
715                         Reference<XPropertySet> xCellPropertySet( xCell,
716                                                                 UNO_QUERY );
717                         OUString sTextSection( RTL_CONSTASCII_USTRINGPARAM("TextSection") );
718                         Any aAny = xCellPropertySet->getPropertyValue(sTextSection);
719                         Reference < XTextSection > xTextSection;
720                         aAny >>= xTextSection;
721                         rTblInfo.SetBaseSection( xTextSection );
722                     }
723 
724                     const bool bExportContent = (getExportFlags() & EXPORT_CONTENT ) != 0;
725                     if ( !bExportContent )
726                     {
727                         // AUTOSTYLES - not needed anymore if we are currently exporting content.xml
728                         GetTextParagraphExport()->collectTextAutoStyles(
729                             xText, rTblInfo.GetBaseSection(), IsShowProgress() );
730                     }
731                 }
732                 else {
733                     DBG_ERROR("here should be a XCell");
734                 }
735             }
736             else
737             {
738                 lcl_xmltble_appendBoxPrefix( sBuffer, rNamePrefix, nOldCol,
739                                              nLine, bTop );
740 
741                 ExportTableLinesAutoStyles( pBox->GetTabLines(),
742                                             nAbsWidth, nBaseWidth,
743                                             sBuffer.makeStringAndClear(),
744                                             rExpCols, rExpRows, rExpCells,
745                                             rTblInfo );
746             }
747 
748             nCol++;
749         }
750     }
751 }
752 
ExportTableAutoStyles(const SwTableNode & rTblNd)753 void SwXMLExport::ExportTableAutoStyles( const SwTableNode& rTblNd )
754 {
755     const SwTable& rTbl = rTblNd.GetTable();
756     const SwFrmFmt *pTblFmt = rTbl.GetFrmFmt();
757 
758     if( pTblFmt )
759     {
760         sal_Int16 eTabHoriOri = pTblFmt->GetHoriOrient().GetHoriOrient();
761         const SwFmtFrmSize& rFrmSize = pTblFmt->GetFrmSize();
762 
763         sal_uInt32 nAbsWidth = rFrmSize.GetSize().Width();
764         sal_uInt32 nBaseWidth = 0UL;
765         sal_Int8 nPrcWidth = rFrmSize.GetWidthPercent();
766 
767         sal_Bool bFixAbsWidth = nPrcWidth != 0 || /*text::*/HoriOrientation::NONE == eTabHoriOri
768                                            || /*text::*/HoriOrientation::FULL == eTabHoriOri;
769         if( bFixAbsWidth )
770         {
771             nBaseWidth = nAbsWidth;
772             nAbsWidth = pTblFmt->FindLayoutRect(sal_True).Width();
773             if( !nAbsWidth )
774             {
775                 // TODO???
776             }
777         }
778         ExportTableFmt( *pTblFmt, nAbsWidth );
779 
780         OUString sName( pTblFmt->GetName() );
781         SwXMLTableColumnsSortByWidth_Impl aExpCols( 10, 10 );
782         SwXMLTableFrmFmtsSort_Impl aExpRows( 10, 10 );
783         SwXMLTableFrmFmtsSort_Impl aExpCells( 10, 10 );
784         SwXMLTableInfo_Impl aTblInfo( &rTbl );
785         ExportTableLinesAutoStyles( rTbl.GetTabLines(), nAbsWidth, nBaseWidth,
786                                     sName, aExpCols, aExpRows, aExpCells,
787                                     aTblInfo, sal_True);
788     }
789 }
790 
791 // ---------------------------------------------------------------------
792 
ExportTableBox(const SwTableBox & rBox,sal_uInt16 nColSpan,sal_uInt16 nRowSpan,SwXMLTableInfo_Impl & rTblInfo)793 void SwXMLExport::ExportTableBox( const SwTableBox& rBox,
794                                   sal_uInt16 nColSpan,
795                                   sal_uInt16 nRowSpan,
796                                   SwXMLTableInfo_Impl& rTblInfo )
797 {
798     const SwStartNode *pBoxSttNd = rBox.GetSttNd();
799     if( pBoxSttNd )
800     {
801         const SwFrmFmt *pFrmFmt = rBox.GetFrmFmt();
802         if( pFrmFmt )
803         {
804             const String& rName = pFrmFmt->GetName();
805             if( rName.Len() )
806             {
807                 AddAttribute( XML_NAMESPACE_TABLE, XML_STYLE_NAME, EncodeStyleName(rName) );
808             }
809         }
810     }
811 
812     if( nRowSpan != 1 )
813     {
814         OUStringBuffer sTmp;
815         sTmp.append( (sal_Int32)nRowSpan );
816         AddAttribute( XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_SPANNED,
817                       sTmp.makeStringAndClear() );
818     }
819 
820     if( nColSpan != 1 )
821     {
822         OUStringBuffer sTmp;
823         sTmp.append( (sal_Int32)nColSpan );
824         AddAttribute( XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_SPANNED,
825                       sTmp.makeStringAndClear() );
826     }
827 
828     {
829         if( pBoxSttNd )
830         {
831             // start node -> normal cell
832 
833             // get cell range for table
834             Reference<XCell> xCell = SwXCell::CreateXCell( (SwFrmFmt *)rTblInfo.GetTblFmt(),
835                                                             (SwTableBox *)&rBox,
836                                                             (SwTable *)rTblInfo.GetTable() );
837 
838             if (xCell.is())
839             {
840                 Reference<XText> xText( xCell, UNO_QUERY );
841 
842                 // get formula (and protection)
843                 OUString sCellFormula = xCell->getFormula();
844 
845                 // if this cell has a formula, export it
846                 //     (with value and number format)
847                 if (sCellFormula.getLength()>0)
848                 {
849                     OUString sQValue =
850                         GetNamespaceMap().GetQNameByKey(
851                                 XML_NAMESPACE_OOOW, sCellFormula, sal_False );
852                     // formula
853                     AddAttribute(XML_NAMESPACE_TABLE, XML_FORMULA, sQValue );
854                 }
855 
856                 // value and format (if NumberFormat != -1)
857                 Reference<XPropertySet> xCellPropertySet(xCell,
858                                                         UNO_QUERY);
859                 if (xCellPropertySet.is())
860                 {
861                     sal_Int32 nNumberFormat = 0;
862                     Any aAny = xCellPropertySet->getPropertyValue(sNumberFormat);
863                     aAny >>= nNumberFormat;
864 
865                     if (NUMBERFORMAT_TEXT == nNumberFormat)
866                     {
867                         // text format
868                         AddAttribute( XML_NAMESPACE_OFFICE,
869                                     XML_VALUE_TYPE, XML_STRING );
870                     }
871                     else if ( (-1 != nNumberFormat) && (xText->getString().getLength() > 0) )
872                     {
873                         // number format key:
874                         // (export values only if cell contains text;
875                         //  cf. #83755#)
876                         XMLNumberFormatAttributesExportHelper::
877                             SetNumberFormatAttributes(
878                                 *this, nNumberFormat, xCell->getValue(),
879                                  sal_True );
880                     }
881                     // else: invalid key; ignore
882 
883                     // cell protection
884                     aAny = xCellPropertySet->getPropertyValue(sIsProtected);
885                     if (*(sal_Bool*)aAny.getValue())
886                     {
887                         AddAttribute( XML_NAMESPACE_TABLE, XML_PROTECTED,
888                                         XML_TRUE );
889                     }
890 
891                     if( !rTblInfo.IsBaseSectionValid() )
892                     {
893                         OUString sTextSection( RTL_CONSTASCII_USTRINGPARAM("TextSection") );
894                         aAny = xCellPropertySet->getPropertyValue(sTextSection);
895                         Reference < XTextSection > xTextSection;
896                         aAny >>= xTextSection;
897                         rTblInfo.SetBaseSection( xTextSection );
898                     }
899                 }
900 
901                 // export cell element
902                 SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE,
903                                         XML_TABLE_CELL, sal_True, sal_True );
904 
905                 // export cell content
906                 GetTextParagraphExport()->exportText( xText,
907                                                     rTblInfo.GetBaseSection(),
908                                                     IsShowProgress() );
909             }
910             else
911             {
912                 DBG_ERROR("here should be a XCell");
913                 ClearAttrList();
914             }
915         }
916         else
917         {
918             // no start node -> merged cells: export subtable in cell
919             SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE,
920                                       XML_TABLE_CELL, sal_True, sal_True );
921             {
922                 AddAttribute( XML_NAMESPACE_TABLE, XML_IS_SUB_TABLE,
923                               GetXMLToken( XML_TRUE ) );
924 
925                 SvXMLElementExport aElemExport( *this, XML_NAMESPACE_TABLE,
926                                           XML_TABLE, sal_True, sal_True );
927                 ExportTableLines( rBox.GetTabLines(), rTblInfo );
928             }
929         }
930     }
931 }
932 
ExportTableLine(const SwTableLine & rLine,const SwXMLTableLines_Impl & rLines,SwXMLTableInfo_Impl & rTblInfo)933 void SwXMLExport::ExportTableLine( const SwTableLine& rLine,
934                                    const SwXMLTableLines_Impl& rLines,
935                                    SwXMLTableInfo_Impl& rTblInfo )
936 {
937     if( rLine.hasSoftPageBreak() )
938     {
939         SvXMLElementExport aElem( *this, XML_NAMESPACE_TEXT,
940                                   XML_SOFT_PAGE_BREAK, sal_True, sal_True );
941     }
942     const SwFrmFmt *pFrmFmt = rLine.GetFrmFmt();
943     if( pFrmFmt )
944     {
945         const String& rName = pFrmFmt->GetName();
946         if( rName.Len() )
947         {
948             AddAttribute( XML_NAMESPACE_TABLE, XML_STYLE_NAME, EncodeStyleName(rName) );
949         }
950     }
951 
952     {
953         SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE,
954                                   XML_TABLE_ROW, sal_True, sal_True );
955         const SwTableBoxes& rBoxes = rLine.GetTabBoxes();
956         sal_uInt16 nBoxes = rBoxes.Count();
957 
958         sal_uInt32 nCPos = 0U;
959         sal_uInt16 nCol = 0U;
960         for( sal_uInt16 nBox=0U; nBox<nBoxes; nBox++ )
961         {
962             const SwTableBox *pBox = rBoxes[nBox];
963 
964             // NEW TABLES
965             const long nRowSpan = pBox->getRowSpan();
966             if( nRowSpan < 1 )
967             {
968                 SvXMLElementExport aElem2( *this, XML_NAMESPACE_TABLE,
969                                           XML_COVERED_TABLE_CELL, sal_True,
970                                           sal_False );
971             }
972 
973             if( nBox < nBoxes-1U )
974                 nCPos = nCPos + SwWriteTable::GetBoxWidth( pBox );
975             else
976                 nCPos = rLines.GetWidth();
977 
978             // Und ihren Index
979             const sal_uInt16 nOldCol = nCol;
980             {
981                 SwXMLTableColumn_Impl aCol( nCPos );
982 #ifdef DBG_UTIL
983                 const sal_Bool bFound =
984 #endif
985                     rLines.GetColumns().Seek_Entry( &aCol, &nCol );
986                 ASSERT( bFound, "couldn't find column" );
987             }
988 
989             // --> OD 2009-03-19 #i95726#
990             // Some fault tolerance, if table is somehow corrupted.
991             if ( nCol < nOldCol )
992             {
993                 ASSERT( false, "table and/or table information seems to be corrupted." );
994                 if ( nBox == nBoxes - 1 )
995                 {
996                     nCol = rLines.GetColumns().Count() - 1;
997                 }
998                 else
999                 {
1000                     nCol = nOldCol;
1001                 }
1002             }
1003             // <--
1004 
1005             sal_uInt16 nColSpan = nCol - nOldCol + 1U;
1006 
1007             if ( nRowSpan >= 1 )
1008                 ExportTableBox( *pBox, nColSpan, static_cast< sal_uInt16 >(nRowSpan), rTblInfo );
1009 
1010             for( sal_uInt16 i=nOldCol; i<nCol; i++ )
1011             {
1012                 SvXMLElementExport aElemExport( *this, XML_NAMESPACE_TABLE,
1013                                           XML_COVERED_TABLE_CELL, sal_True,
1014                                           sal_False );
1015             }
1016 
1017             nCol++;
1018         }
1019     }
1020 }
1021 
ExportTableLines(const SwTableLines & rLines,SwXMLTableInfo_Impl & rTblInfo,sal_uInt16 nHeaderRows)1022 void SwXMLExport::ExportTableLines( const SwTableLines& rLines,
1023                                     SwXMLTableInfo_Impl& rTblInfo,
1024                                     sal_uInt16 nHeaderRows )
1025 {
1026     ASSERT( pTableLines && pTableLines->Count(),
1027             "SwXMLExport::ExportTableLines: table columns infos missing" );
1028     if( !pTableLines || 0 == pTableLines->Count() )
1029         return;
1030 
1031     SwXMLTableLines_Impl *pLines = 0;
1032     sal_uInt16 nInfoPos;
1033     for( nInfoPos=0; nInfoPos < pTableLines->Count(); nInfoPos++ )
1034     {
1035         if( pTableLines->GetObject( nInfoPos )->GetLines() == &rLines )
1036         {
1037             pLines = pTableLines->GetObject( nInfoPos );
1038             break;
1039         }
1040     }
1041     ASSERT( pLines,
1042             "SwXMLExport::ExportTableLines: table columns info missing" );
1043     ASSERT( 0==nInfoPos,
1044             "SwXMLExport::ExportTableLines: table columns infos are unsorted" );
1045     if( !pLines )
1046         return;
1047 
1048     pTableLines->Remove( nInfoPos );
1049     if( 0 == pTableLines->Count() )
1050     {
1051         delete pTableLines ;
1052         pTableLines = 0;
1053     }
1054 
1055     // pass 2: export columns
1056     const SwXMLTableColumns_Impl& rCols = pLines->GetColumns();
1057     sal_uInt16 nColumn = 0U;
1058     sal_uInt16 nColumns = rCols.Count();
1059     sal_uInt16 nColRep = 1U;
1060     SwXMLTableColumn_Impl *pColumn = (nColumns > 0) ? rCols[0U] : 0;
1061     while( pColumn )
1062     {
1063         nColumn++;
1064         SwXMLTableColumn_Impl *pNextColumn =
1065             (nColumn < nColumns) ? rCols[nColumn] : 0;
1066         if( pNextColumn &&
1067             pNextColumn->GetStyleName() == pColumn->GetStyleName() )
1068         {
1069             nColRep++;
1070         }
1071         else
1072         {
1073             AddAttribute( XML_NAMESPACE_TABLE, XML_STYLE_NAME,
1074                           EncodeStyleName(pColumn->GetStyleName()) );
1075 
1076             if( nColRep > 1U )
1077             {
1078                 OUStringBuffer sTmp(4);
1079                 sTmp.append( (sal_Int32)nColRep );
1080                 AddAttribute( XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED,
1081                               sTmp.makeStringAndClear() );
1082             }
1083 
1084             {
1085                 SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE,
1086                                           XML_TABLE_COLUMN, sal_True, sal_True );
1087             }
1088 
1089             nColRep = 1U;
1090         }
1091         pColumn = pNextColumn;
1092     }
1093 
1094     // pass 3: export line/rows
1095     sal_uInt16 nLines = rLines.Count();
1096     // export header rows, if present
1097     if( nHeaderRows > 0 )
1098     {
1099         SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE,
1100                                   XML_TABLE_HEADER_ROWS, sal_True, sal_True );
1101 
1102         DBG_ASSERT( nHeaderRows <= nLines, "more headers then lines?" );
1103         for( sal_uInt16 nLine = 0U; nLine < nHeaderRows; nLine++ )
1104             ExportTableLine( *(rLines[nLine]), *pLines, rTblInfo );
1105     }
1106     // export remaining rows
1107     for( sal_uInt16 nLine = nHeaderRows; nLine < nLines; nLine++ )
1108     {
1109         ExportTableLine( *(rLines[nLine]), *pLines, rTblInfo );
1110     }
1111 
1112     delete pLines;
1113 }
1114 
1115 sal_Bool lcl_xmltble_ClearName_Line( const SwTableLine*& rpLine, void* );
1116 
lcl_xmltble_ClearName_Box(const SwTableBox * & rpBox,void *)1117 sal_Bool lcl_xmltble_ClearName_Box( const SwTableBox*& rpBox, void* )
1118 {
1119     if( !rpBox->GetSttNd() )
1120     {
1121         ((SwTableBox *)rpBox)->GetTabLines().ForEach(
1122                                             &lcl_xmltble_ClearName_Line, 0 );
1123     }
1124     else
1125     {
1126         SwFrmFmt *pFrmFmt = ((SwTableBox *)rpBox)->GetFrmFmt();
1127         if( pFrmFmt && pFrmFmt->GetName().Len() )
1128             pFrmFmt->SetName( aEmptyStr );
1129     }
1130 
1131     return sal_True;
1132 }
1133 
lcl_xmltble_ClearName_Line(const SwTableLine * & rpLine,void *)1134 sal_Bool lcl_xmltble_ClearName_Line( const SwTableLine*& rpLine, void* )
1135 {
1136     ((SwTableLine *)rpLine)->GetTabBoxes().ForEach(
1137                                             &lcl_xmltble_ClearName_Box, 0 );
1138 
1139     return sal_True;
1140 }
1141 
ExportTable(const SwTableNode & rTblNd)1142 void SwXMLExport::ExportTable( const SwTableNode& rTblNd )
1143 {
1144     const SwTable& rTbl = rTblNd.GetTable();
1145     const SwFrmFmt *pTblFmt = rTbl.GetFrmFmt();
1146     if( pTblFmt && pTblFmt->GetName().Len() )
1147     {
1148         AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, pTblFmt->GetName() );
1149         AddAttribute( XML_NAMESPACE_TABLE, XML_STYLE_NAME,
1150                       EncodeStyleName( pTblFmt->GetName() ) );
1151     }
1152 
1153     {
1154         SvXMLElementExport aElem( *this, XML_NAMESPACE_TABLE, XML_TABLE,
1155                                   sal_True, sal_True );
1156 
1157         // export DDE source (if this is a DDE table)
1158         if ( rTbl.ISA(SwDDETable) )
1159         {
1160             // get DDE Field Type (contains the DDE connection)
1161             const SwDDEFieldType* pDDEFldType =
1162                 ((SwDDETable&)rTbl).GetDDEFldType();
1163 
1164             // connection name
1165             AddAttribute( XML_NAMESPACE_OFFICE, XML_NAME,
1166                           pDDEFldType->GetName() );
1167 
1168             // DDE command
1169             const String sCmd = pDDEFldType->GetCmd();
1170             AddAttribute( XML_NAMESPACE_OFFICE, XML_DDE_APPLICATION,
1171                           sCmd.GetToken(0, sfx2::cTokenSeperator) );
1172             AddAttribute( XML_NAMESPACE_OFFICE, XML_DDE_ITEM,
1173                           sCmd.GetToken(1, sfx2::cTokenSeperator) );
1174             AddAttribute( XML_NAMESPACE_OFFICE, XML_DDE_TOPIC,
1175                           sCmd.GetToken(2, sfx2::cTokenSeperator) );
1176 
1177             // auto update
1178             if (pDDEFldType->GetType() == sfx2::LINKUPDATE_ALWAYS)
1179             {
1180                 AddAttribute( XML_NAMESPACE_OFFICE,
1181                               XML_AUTOMATIC_UPDATE, XML_TRUE );
1182             }
1183 
1184             // DDE source element (always empty)
1185             SvXMLElementExport aSource(*this, XML_NAMESPACE_OFFICE,
1186                                        XML_DDE_SOURCE, sal_True, sal_False);
1187         }
1188 
1189         SwXMLTableInfo_Impl aTblInfo( &rTbl );
1190         ExportTableLines( rTbl.GetTabLines(), aTblInfo, rTbl.GetRowsToRepeat() );
1191 
1192         ((SwTable &)rTbl).GetTabLines().ForEach( &lcl_xmltble_ClearName_Line,
1193                                                  0 );
1194     }
1195 }
1196 
exportTable(const Reference<XTextContent> & rTextContent,sal_Bool bAutoStyles,sal_Bool _bProgress)1197 void SwXMLTextParagraphExport::exportTable(
1198         const Reference < XTextContent > & rTextContent,
1199         sal_Bool bAutoStyles, sal_Bool _bProgress )
1200 {
1201     sal_Bool bOldShowProgress = ((SwXMLExport&)GetExport()).IsShowProgress();
1202     ((SwXMLExport&)GetExport()).SetShowProgress( _bProgress );
1203 
1204     Reference < XTextTable > xTxtTbl( rTextContent, UNO_QUERY );
1205     DBG_ASSERT( xTxtTbl.is(), "text table missing" );
1206     if( xTxtTbl.is() )
1207     {
1208         const SwXTextTable *pXTable = 0;
1209         Reference<XUnoTunnel> xTableTunnel( rTextContent, UNO_QUERY);
1210         if( xTableTunnel.is() )
1211         {
1212             pXTable = reinterpret_cast< SwXTextTable * >(
1213                     sal::static_int_cast< sal_IntPtr >( xTableTunnel->getSomething( SwXTextTable::getUnoTunnelId() )));
1214             ASSERT( pXTable, "SwXTextTable missing" );
1215         }
1216         if( pXTable )
1217         {
1218             SwFrmFmt *pFmt = pXTable->GetFrmFmt();
1219             ASSERT( pFmt, "table format missing" );
1220             const SwTable *pTbl = SwTable::FindTable( pFmt );
1221             ASSERT( pTbl, "table missing" );
1222             const SwTableNode *pTblNd = pTbl->GetTableNode();
1223             ASSERT( pTblNd, "table node missing" );
1224             if( bAutoStyles )
1225             {
1226                 SwNodeIndex aIdx( *pTblNd );
1227                 // AUTOSTYLES: Optimization: Do not export table autostyle if
1228                 // we are currently exporting the content.xml stuff and
1229                 // the table is located in header/footer:
1230                 // #144704: During the flat XML export (used e.g. by .sdw-export)
1231                 // ALL flags are set at the same time.
1232                 const bool bExportStyles = ( GetExport().getExportFlags() & EXPORT_STYLES ) != 0;
1233                 if ( bExportStyles || !pFmt->GetDoc()->IsInHeaderFooter( aIdx ) )
1234                     ((SwXMLExport&)GetExport()).ExportTableAutoStyles( *pTblNd );
1235             }
1236             else
1237             {
1238                 ((SwXMLExport&)GetExport()).ExportTable( *pTblNd );
1239             }
1240         }
1241     }
1242 
1243     ((SwXMLExport&)GetExport()).SetShowProgress( bOldShowProgress );
1244 }
1245 
1246 
1247