1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xmltble.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
36 #include <rtl/ustrbuf.hxx>
37 #include <com/sun/star/text/XTextTable.hpp>
38 #include <xmloff/xmlnmspe.hxx>
39 #include <xmloff/xmltoken.hxx>
40 #include <xmloff/xmluconv.hxx>
41 #include <xmloff/numehelp.hxx>
42 #include <svtools/cntnrsrt.hxx>
43 #include <svtools/zforlist.hxx>
44 #include <svx/brshitem.hxx>
45 #include <svx/boxitem.hxx>
46 #include <fmtrowsplt.hxx>
47 #ifndef _SVX_FRAMEDIRITEM_HXX
48 #include <svx/frmdiritem.hxx>
52 #include "swtable.hxx"
56 #include "wrtswtbl.hxx"
57 #include "fmtfsize.hxx"
58 #include "fmtornt.hxx"
59 #include "cellatr.hxx"
61 #include "swddetbl.hxx"
63 #include <xmloff/nmspmap.hxx>
64 #include <sfx2/linkmgr.hxx> // for cTokenSeperator
67 #include "xmltexte.hxx"
71 using ::rtl::OUString
;
72 using ::rtl::OUStringBuffer
;
73 using namespace ::com::sun::star
;
74 using namespace ::com::sun::star::uno
;
75 using namespace ::com::sun::star::text
;
76 using namespace ::com::sun::star::beans
;
77 using namespace ::com::sun::star::lang
;
78 using namespace ::com::sun::star::container
;
79 using namespace ::xmloff::token
;
83 class SwXMLTableColumn_Impl
: public SwWriteTableCol
91 SwXMLTableColumn_Impl( sal_uInt16 nPosition
) :
92 SwWriteTableCol( nPosition
),
96 void SetStyleName( const OUString
& rName
) { sStyleName
= rName
; }
97 const OUString
& GetStyleName() const { return sStyleName
; }
99 void SetRelWidth( sal_uInt32 nSet
) { nRelWidth
= nSet
; }
100 sal_uInt32
GetRelWidth() const { return nRelWidth
; }
103 sal_Int32
SwXMLTableColumnCmpWidth_Impl( const SwXMLTableColumn_Impl
& r1
,
104 const SwXMLTableColumn_Impl
& r2
)
106 sal_Int32 n
= (sal_Int32
)r1
.GetWidthOpt() - (sal_Int32
)r2
.GetWidthOpt();
108 n
= (sal_Int32
)r1
.GetRelWidth() - (sal_Int32
)r2
.GetRelWidth();
112 // ---------------------------------------------------------------------
114 typedef SwXMLTableColumn_Impl
*SwXMLTableColumnPtr
;
115 SV_DECL_PTRARR_SORT_DEL( SwXMLTableColumns_Impl
, SwXMLTableColumnPtr
, 5, 5 )
116 SV_IMPL_OP_PTRARR_SORT( SwXMLTableColumns_Impl
, SwXMLTableColumnPtr
)
118 DECLARE_CONTAINER_SORT( SwXMLTableColumnsSortByWidth_Impl
,
119 SwXMLTableColumn_Impl
)
120 IMPL_CONTAINER_SORT( SwXMLTableColumnsSortByWidth_Impl
, SwXMLTableColumn_Impl
,
121 SwXMLTableColumnCmpWidth_Impl
)
123 class SwXMLTableLines_Impl
125 SwXMLTableColumns_Impl aCols
;
126 const SwTableLines
*pLines
;
131 SwXMLTableLines_Impl( const SwTableLines
& rLines
);
133 ~SwXMLTableLines_Impl() {}
135 sal_uInt32
GetWidth() const { return nWidth
; }
136 const SwTableLines
*GetLines() const { return pLines
; }
138 const SwXMLTableColumns_Impl
& GetColumns() const { return aCols
; }
141 SwXMLTableLines_Impl::SwXMLTableLines_Impl( const SwTableLines
& rLines
) :
146 sal_uInt16 nEndCPos
= 0U;
148 sal_uInt16 nLines
= rLines
.Count();
150 for( nLine
=0U; nLine
<nLines
; nLine
++ )
152 const SwTableLine
*pLine
= rLines
[nLine
];
153 const SwTableBoxes
& rBoxes
= pLine
->GetTabBoxes();
154 sal_uInt16 nBoxes
= rBoxes
.Count();
156 sal_uInt16 nCPos
= 0U;
157 for( sal_uInt16 nBox
=0U; nBox
<nBoxes
; nBox
++ )
159 const SwTableBox
*pBox
= rBoxes
[nBox
];
161 if( nBox
< nBoxes
-1U || nWidth
==0UL )
163 nCPos
= nCPos
+ (sal_uInt16
)SwWriteTable::GetBoxWidth( pBox
);
164 SwXMLTableColumn_Impl
*pCol
=
165 new SwXMLTableColumn_Impl( nCPos
);
167 if( !aCols
.Insert( pCol
) )
170 if( nBox
==nBoxes
-1U )
172 ASSERT( nLine
==0U && nWidth
==0UL,
173 "parent width will be lost" );
180 sal_uInt16 nCheckPos
=
181 nCPos
+ (sal_uInt16
)SwWriteTable::GetBoxWidth( pBox
);
184 nEndCPos
= nCheckPos
;
189 ASSERT( SwXMLTableColumn_impl(nCheckPos) ==
190 SwXMLTableColumn_Impl(nEndCPos),
191 "rows have different total widths" );
195 nCPos
= (sal_uInt16
)nWidth
;
197 SwXMLTableColumn_Impl
aCol( (sal_uInt16
)nWidth
);
198 ASSERT( aCols
.Seek_Entry(&aCol
), "couldn't find last column" );
199 ASSERT( SwXMLTableColumn_Impl(nCheckPos
) ==
200 SwXMLTableColumn_Impl(nCPos
),
201 "rows have different total widths" );
208 typedef SwXMLTableLines_Impl
*SwXMLTableLinesPtr
;
209 DECLARE_LIST( SwXMLTableLinesCache_Impl
, SwXMLTableLinesPtr
)
211 // ---------------------------------------------------------------------
213 typedef SwFrmFmt
*SwFrmFmtPtr
;
214 DECLARE_LIST( SwXMLFrmFmts_Impl
, SwFrmFmtPtr
)
216 class SwXMLTableFrmFmtsSort_Impl
: public SwXMLFrmFmts_Impl
219 SwXMLTableFrmFmtsSort_Impl ( sal_uInt16 nInit
, sal_uInt16 nGrow
) :
220 SwXMLFrmFmts_Impl( nInit
, nGrow
)
223 sal_Bool
AddRow( SwFrmFmt
& rFrmFmt
, const OUString
& rNamePrefix
, sal_uInt32 nLine
);
224 sal_Bool
AddCell( SwFrmFmt
& rFrmFmt
, const OUString
& rNamePrefix
,
225 sal_uInt32 nCol
, sal_uInt32 nRow
, sal_Bool bTop
);
228 sal_Bool
SwXMLTableFrmFmtsSort_Impl::AddRow( SwFrmFmt
& rFrmFmt
,
229 const OUString
& rNamePrefix
,
232 const SwFmtFrmSize
*pFrmSize
= 0;
233 const SwFmtRowSplit
* pRowSplit
= 0;
234 const SvxBrushItem
*pBrush
= 0;
236 const SfxItemSet
& rItemSet
= rFrmFmt
.GetAttrSet();
237 const SfxPoolItem
*pItem
;
238 if( SFX_ITEM_SET
== rItemSet
.GetItemState( RES_FRM_SIZE
, sal_False
, &pItem
) )
239 pFrmSize
= (const SwFmtFrmSize
*)pItem
;
241 if( SFX_ITEM_SET
== rItemSet
.GetItemState( RES_ROW_SPLIT
, sal_False
, &pItem
) )
242 pRowSplit
= (const SwFmtRowSplit
*)pItem
;
244 if( SFX_ITEM_SET
== rItemSet
.GetItemState( RES_BACKGROUND
, sal_False
, &pItem
) )
245 pBrush
= (const SvxBrushItem
*)pItem
;
247 // empty styles have not to be exported
248 if( !pFrmSize
&& !pBrush
&& !pRowSplit
)
251 // order is: -/brush, size/-, size/brush
252 sal_uInt32 nCount2
= Count();
253 sal_Bool bInsert
= sal_True
;
255 for( i
= 0; i
< nCount2
; ++i
)
257 const SwFmtFrmSize
*pTestFrmSize
= 0;
258 const SwFmtRowSplit
* pTestRowSplit
= 0;
259 const SvxBrushItem
*pTestBrush
= 0;
260 const SwFrmFmt
*pTestFmt
= GetObject(i
);
261 const SfxItemSet
& rTestSet
= pTestFmt
->GetAttrSet();
262 if( SFX_ITEM_SET
== rTestSet
.GetItemState( RES_FRM_SIZE
, sal_False
,
268 pTestFrmSize
= (const SwFmtFrmSize
*)pItem
;
276 if( SFX_ITEM_SET
== rTestSet
.GetItemState( RES_BACKGROUND
, sal_False
,
282 pTestBrush
= (const SvxBrushItem
*)pItem
;
290 if( SFX_ITEM_SET
== rTestSet
.GetItemState( RES_ROW_SPLIT
, sal_False
,
296 pTestRowSplit
= (const SwFmtRowSplit
*)pItem
;
306 ( pFrmSize
->GetHeightSizeType() != pTestFrmSize
->GetHeightSizeType() ||
307 pFrmSize
->GetHeight() != pTestFrmSize
->GetHeight() ) )
310 if( pBrush
&& (*pBrush
!= *pTestBrush
) )
313 if( pRowSplit
&& (!pRowSplit
->GetValue() != !pTestRowSplit
->GetValue()) )
317 const String
& rFmtName
= pTestFmt
->GetName();
318 rFrmFmt
.SetName( rFmtName
);
325 OUStringBuffer
sBuffer( rNamePrefix
.getLength() + 4UL );
326 sBuffer
.append( rNamePrefix
);
327 sBuffer
.append( (sal_Unicode
)'.' );
328 sBuffer
.append( (sal_Int32
)(nLine
+1UL) );
330 rFrmFmt
.SetName( sBuffer
.makeStringAndClear() );
331 Insert( &rFrmFmt
, i
);
337 void lcl_GetTblBoxColStr( sal_uInt16 nCol
, String
& rNm
);
338 void lcl_xmltble_appendBoxPrefix( OUStringBuffer
& rBuffer
,
339 const OUString
& rNamePrefix
,
340 sal_uInt32 nCol
, sal_uInt32 nRow
, sal_Bool bTop
)
342 rBuffer
.append( rNamePrefix
);
343 rBuffer
.append( (sal_Unicode
)'.' );
347 lcl_GetTblBoxColStr( (sal_uInt16
)nCol
, sTmp
);
348 rBuffer
.append( sTmp
);
352 rBuffer
.append( (sal_Int32
)(nCol
+ 1));
353 rBuffer
.append( (sal_Unicode
)'.' );
355 rBuffer
.append( (sal_Int32
)(nRow
+ 1));
358 sal_Bool
SwXMLTableFrmFmtsSort_Impl::AddCell( SwFrmFmt
& rFrmFmt
,
359 const OUString
& rNamePrefix
,
360 sal_uInt32 nCol
, sal_uInt32 nRow
, sal_Bool bTop
)
362 const SwFmtVertOrient
*pVertOrient
= 0;
363 const SvxBrushItem
*pBrush
= 0;
364 const SvxBoxItem
*pBox
= 0;
365 const SwTblBoxNumFormat
*pNumFmt
= 0;
366 const SvxFrameDirectionItem
*pFrameDir
= 0;
368 const SfxItemSet
& rItemSet
= rFrmFmt
.GetAttrSet();
369 const SfxPoolItem
*pItem
;
370 if( SFX_ITEM_SET
== rItemSet
.GetItemState( RES_VERT_ORIENT
, sal_False
,
372 pVertOrient
= (const SwFmtVertOrient
*)pItem
;
374 if( SFX_ITEM_SET
== rItemSet
.GetItemState( RES_BACKGROUND
, sal_False
, &pItem
) )
375 pBrush
= (const SvxBrushItem
*)pItem
;
377 if( SFX_ITEM_SET
== rItemSet
.GetItemState( RES_BOX
, sal_False
, &pItem
) )
378 pBox
= (const SvxBoxItem
*)pItem
;
380 if ( SFX_ITEM_SET
== rItemSet
.GetItemState( RES_BOXATR_FORMAT
,
381 sal_False
, &pItem
) )
382 pNumFmt
= (const SwTblBoxNumFormat
*)pItem
;
383 if ( SFX_ITEM_SET
== rItemSet
.GetItemState( RES_FRAMEDIR
,
384 sal_False
, &pItem
) )
385 pFrameDir
= (const SvxFrameDirectionItem
*)pItem
;
387 // empty styles have not to be exported
388 if( !pVertOrient
&& !pBrush
&& !pBox
&& !pNumFmt
&& !pFrameDir
)
391 // order is: -/-/-/num,
392 // -/-/box/-, --/-/box/num,
393 // -/brush/-/-, -/brush/-/num, -/brush/box/-, -/brush/box/num,
394 // vert/-/-/-, vert/-/-/num, vert/-/box/-, ver/-/box/num,
395 // vert/brush/-/-, vert/brush/-/num, vert/brush/box/-,
396 // vert/brush/box/num
397 sal_uInt32 nCount2
= Count();
398 sal_Bool bInsert
= sal_True
;
400 for( i
= 0; i
< nCount2
; ++i
)
402 const SwFmtVertOrient
*pTestVertOrient
= 0;
403 const SvxBrushItem
*pTestBrush
= 0;
404 const SvxBoxItem
*pTestBox
= 0;
405 const SwTblBoxNumFormat
*pTestNumFmt
= 0;
406 const SvxFrameDirectionItem
*pTestFrameDir
= 0;
407 const SwFrmFmt
*pTestFmt
= GetObject(i
);
408 const SfxItemSet
& rTestSet
= pTestFmt
->GetAttrSet();
409 if( SFX_ITEM_SET
== rTestSet
.GetItemState( RES_VERT_ORIENT
, sal_False
,
415 pTestVertOrient
= (const SwFmtVertOrient
*)pItem
;
423 if( SFX_ITEM_SET
== rTestSet
.GetItemState( RES_BACKGROUND
, sal_False
,
429 pTestBrush
= (const SvxBrushItem
*)pItem
;
437 if( SFX_ITEM_SET
== rTestSet
.GetItemState( RES_BOX
, sal_False
, &pItem
) )
442 pTestBox
= (const SvxBoxItem
*)pItem
;
450 if ( SFX_ITEM_SET
== rTestSet
.GetItemState( RES_BOXATR_FORMAT
,
451 sal_False
, &pItem
) )
456 pTestNumFmt
= (const SwTblBoxNumFormat
*)pItem
;
465 if ( SFX_ITEM_SET
== rTestSet
.GetItemState( RES_FRAMEDIR
,
466 sal_False
, &pItem
) )
471 pTestFrameDir
= (const SvxFrameDirectionItem
*)pItem
;
481 pVertOrient
->GetVertOrient() != pTestVertOrient
->GetVertOrient() )
484 if( pBrush
&& ( *pBrush
!= *pTestBrush
) )
487 if( pBox
&& ( *pBox
!= *pTestBox
) )
490 if( pNumFmt
&& pNumFmt
->GetValue() != pTestNumFmt
->GetValue() )
493 if( pFrameDir
&& pFrameDir
->GetValue() != pTestFrameDir
->GetValue() )
497 const String
& rFmtName
= pTestFmt
->GetName();
498 rFrmFmt
.SetName( rFmtName
);
505 OUStringBuffer
sBuffer( rNamePrefix
.getLength() + 8UL );
506 lcl_xmltble_appendBoxPrefix( sBuffer
, rNamePrefix
, nCol
, nRow
, bTop
);
507 rFrmFmt
.SetName( sBuffer
.makeStringAndClear() );
508 Insert( &rFrmFmt
, i
);
513 // ---------------------------------------------------------------------
515 class SwXMLTableInfo_Impl
517 const SwTable
*pTable
;
518 Reference
< XTextSection
> xBaseSection
;
519 sal_Bool bBaseSectionValid
;
523 inline SwXMLTableInfo_Impl( const SwTable
*pTbl
);
525 const SwTable
*GetTable() const { return pTable
; }
526 const SwFrmFmt
*GetTblFmt() const { return pTable
->GetFrmFmt(); }
528 sal_Bool
IsBaseSectionValid() const { return bBaseSectionValid
; }
529 const Reference
< XTextSection
>& GetBaseSection() const { return xBaseSection
; }
530 inline void SetBaseSection( const Reference
< XTextSection
>& rBase
);
533 inline SwXMLTableInfo_Impl::SwXMLTableInfo_Impl( const SwTable
*pTbl
) :
535 bBaseSectionValid( sal_False
)
539 inline void SwXMLTableInfo_Impl::SetBaseSection(
540 const Reference
< XTextSection
>& rBaseSection
)
542 xBaseSection
= rBaseSection
;
543 bBaseSectionValid
= sal_True
;
546 // ---------------------------------------------------------------------
549 void SwXMLExport::ExportTableColumnStyle( const SwXMLTableColumn_Impl
& rCol
)
555 sal_Bool bEncoded
= sal_False
;
556 AddAttribute( XML_NAMESPACE_STYLE
, XML_NAME
,
557 EncodeStyleName( rCol
.GetStyleName(), &bEncoded
) );
559 AddAttribute( XML_NAMESPACE_STYLE
, XML_DISPLAY_NAME
, rCol
.GetStyleName() );
561 // style:family="table-column"
562 AddAttribute( XML_NAMESPACE_STYLE
, XML_FAMILY
, XML_TABLE_COLUMN
);
565 SvXMLElementExport
aElem( *this, XML_NAMESPACE_STYLE
, XML_STYLE
, sal_True
,
567 OUStringBuffer sValue
;
568 if( rCol
.GetWidthOpt() )
570 GetTwipUnitConverter().convertMeasure( sValue
, rCol
.GetWidthOpt() );
571 AddAttribute( XML_NAMESPACE_STYLE
, XML_COLUMN_WIDTH
,
572 sValue
.makeStringAndClear() );
574 if( rCol
.GetRelWidth() )
576 sValue
.append( (sal_Int32
)rCol
.GetRelWidth() );
577 sValue
.append( (sal_Unicode
)'*' );
578 AddAttribute( XML_NAMESPACE_STYLE
, XML_REL_COLUMN_WIDTH
,
579 sValue
.makeStringAndClear() );
583 SvXMLElementExport
aElemExport( *this, XML_NAMESPACE_STYLE
,
584 XML_TABLE_COLUMN_PROPERTIES
,
585 sal_True
, sal_True
);
590 void SwXMLExport::ExportTableLinesAutoStyles( const SwTableLines
& rLines
,
591 sal_uInt32 nAbsWidth
, sal_uInt32 nBaseWidth
,
592 const OUString
& rNamePrefix
,
593 SwXMLTableColumnsSortByWidth_Impl
& rExpCols
,
594 SwXMLTableFrmFmtsSort_Impl
& rExpRows
,
595 SwXMLTableFrmFmtsSort_Impl
& rExpCells
,
596 SwXMLTableInfo_Impl
& rTblInfo
,
599 // pass 1: calculate columns
600 SwXMLTableLines_Impl
*pLines
=
601 new SwXMLTableLines_Impl( rLines
);
603 pTableLines
= new SwXMLTableLinesCache_Impl( 5, 5 );
604 pTableLines
->Insert( pLines
, pTableLines
->Count() );
606 OUStringBuffer
sBuffer( rNamePrefix
.getLength() + 8L );
608 // pass 2: export column styles
610 const SwXMLTableColumns_Impl
& rCols
= pLines
->GetColumns();
611 sal_uInt16 nCPos
= 0U;
612 sal_uInt16 nColumns
= rCols
.Count();
613 for( sal_uInt16 nColumn
=0U; nColumn
<nColumns
; nColumn
++ )
615 SwXMLTableColumn_Impl
*pColumn
= rCols
[nColumn
];
617 sal_uInt16 nOldCPos
= nCPos
;
618 nCPos
= pColumn
->GetPos();
620 sal_uInt32 nWidth
= nCPos
- nOldCPos
;
622 // If a base width is given, the table has either an automatic
623 // or margin alignment, or an percentage width. In either case,
624 // relative widths should be exported.
627 pColumn
->SetRelWidth( nWidth
);
630 // If an absolute width is given, the table either has a fixed
631 // width, or the current width is known from the layout. In the
632 // later case, a base width is set in addition and must be used
633 // to "absoultize" the relative column width.
636 sal_uInt32 nColAbsWidth
= nWidth
;
639 nColAbsWidth
*= nAbsWidth
;
640 nColAbsWidth
+= (nBaseWidth
/2UL);
641 nColAbsWidth
/= nBaseWidth
;
643 pColumn
->SetWidthOpt( (sal_uInt16
)nColAbsWidth
, sal_False
);
647 if( rExpCols
.Seek_Entry( pColumn
, &nExpPos
) )
649 pColumn
->SetStyleName(
650 rExpCols
.GetObject(nExpPos
)->GetStyleName() );
654 sBuffer
.append( rNamePrefix
);
655 sBuffer
.append( (sal_Unicode
)'.' );
659 lcl_GetTblBoxColStr( nColumn
, sTmp
);
660 sBuffer
.append( sTmp
);
664 sBuffer
.append( (sal_Int32
)(nColumn
+ 1U) );
667 pColumn
->SetStyleName( sBuffer
.makeStringAndClear() );
668 ExportTableColumnStyle( *pColumn
);
669 rExpCols
.Insert( pColumn
);
674 // pass 3: export line/rows
675 sal_uInt16 nLines
= rLines
.Count();
676 for( sal_uInt16 nLine
=0U; nLine
<nLines
; nLine
++ )
678 SwTableLine
*pLine
= rLines
[nLine
];
680 SwFrmFmt
*pFrmFmt
= pLine
->GetFrmFmt();
681 if( rExpRows
.AddRow( *pFrmFmt
, rNamePrefix
, nLine
) )
682 ExportFmt( *pFrmFmt
, XML_TABLE_ROW
);
684 const SwTableBoxes
& rBoxes
= pLine
->GetTabBoxes();
685 sal_uInt16 nBoxes
= rBoxes
.Count();
687 sal_uInt16 nCPos
= 0U;
688 sal_uInt16 nCol
= 0U;
689 for( sal_uInt16 nBox
=0U; nBox
<nBoxes
; nBox
++ )
691 SwTableBox
*pBox
= rBoxes
[nBox
];
693 if( nBox
< nBoxes
-1U )
694 nCPos
= nCPos
+ (sal_uInt16
)SwWriteTable::GetBoxWidth( pBox
);
696 nCPos
= (sal_uInt16
)pLines
->GetWidth();
700 sal_uInt16 nOldCol
= nCol
;
701 SwXMLTableColumn_Impl
aCol( nCPos
);
705 pLines
->GetColumns().Seek_Entry( &aCol
, &nCol
);
706 ASSERT( bFound
, "couldn't find column" );
708 const SwStartNode
*pBoxSttNd
= pBox
->GetSttNd();
711 SwFrmFmt
*pFrmFmt2
= pBox
->GetFrmFmt();
712 if( rExpCells
.AddCell( *pFrmFmt2
, rNamePrefix
, nOldCol
, nLine
,
714 ExportFmt( *pFrmFmt2
, XML_TABLE_CELL
);
716 Reference
< XCell
> xCell
= SwXCell::CreateXCell(
717 (SwFrmFmt
*)rTblInfo
.GetTblFmt(),
719 (SwTable
*)rTblInfo
.GetTable() );
722 Reference
< XText
> xText( xCell
, UNO_QUERY
);
723 if( !rTblInfo
.IsBaseSectionValid() )
725 Reference
<XPropertySet
> xCellPropertySet( xCell
,
727 OUString
sTextSection( RTL_CONSTASCII_USTRINGPARAM("TextSection") );
728 Any aAny
= xCellPropertySet
->getPropertyValue(sTextSection
);
729 Reference
< XTextSection
> xTextSection
;
730 aAny
>>= xTextSection
;
731 rTblInfo
.SetBaseSection( xTextSection
);
734 const bool bExportContent
= (getExportFlags() & EXPORT_CONTENT
) != 0;
735 if ( !bExportContent
)
737 // AUTOSTYLES - not needed anymore if we are currently exporting content.xml
738 GetTextParagraphExport()->collectTextAutoStyles(
739 xText
, rTblInfo
.GetBaseSection(), IsShowProgress() );
743 DBG_ERROR("here should be a XCell");
748 lcl_xmltble_appendBoxPrefix( sBuffer
, rNamePrefix
, nOldCol
,
751 ExportTableLinesAutoStyles( pBox
->GetTabLines(),
752 nAbsWidth
, nBaseWidth
,
753 sBuffer
.makeStringAndClear(),
754 rExpCols
, rExpRows
, rExpCells
,
763 void SwXMLExport::ExportTableAutoStyles( const SwTableNode
& rTblNd
)
765 const SwTable
& rTbl
= rTblNd
.GetTable();
766 const SwFrmFmt
*pTblFmt
= rTbl
.GetFrmFmt();
770 sal_Int16 eTabHoriOri
= pTblFmt
->GetHoriOrient().GetHoriOrient();
771 const SwFmtFrmSize
& rFrmSize
= pTblFmt
->GetFrmSize();
773 sal_uInt32 nAbsWidth
= rFrmSize
.GetSize().Width();
774 sal_uInt32 nBaseWidth
= 0UL;
775 sal_Int8 nPrcWidth
= rFrmSize
.GetWidthPercent();
777 sal_Bool bFixAbsWidth
= nPrcWidth
!= 0 || /*text::*/HoriOrientation::NONE
== eTabHoriOri
778 || /*text::*/HoriOrientation::FULL
== eTabHoriOri
;
781 nBaseWidth
= nAbsWidth
;
782 nAbsWidth
= pTblFmt
->FindLayoutRect(sal_True
).Width();
788 ExportTableFmt( *pTblFmt
, nAbsWidth
);
790 OUString
sName( pTblFmt
->GetName() );
791 SwXMLTableColumnsSortByWidth_Impl
aExpCols( 10, 10 );
792 SwXMLTableFrmFmtsSort_Impl
aExpRows( 10, 10 );
793 SwXMLTableFrmFmtsSort_Impl
aExpCells( 10, 10 );
794 SwXMLTableInfo_Impl
aTblInfo( &rTbl
);
795 ExportTableLinesAutoStyles( rTbl
.GetTabLines(), nAbsWidth
, nBaseWidth
,
796 sName
, aExpCols
, aExpRows
, aExpCells
,
801 // ---------------------------------------------------------------------
803 void SwXMLExport::ExportTableBox( const SwTableBox
& rBox
,
806 SwXMLTableInfo_Impl
& rTblInfo
)
808 const SwStartNode
*pBoxSttNd
= rBox
.GetSttNd();
811 const SwFrmFmt
*pFrmFmt
= rBox
.GetFrmFmt();
814 const String
& rName
= pFrmFmt
->GetName();
817 AddAttribute( XML_NAMESPACE_TABLE
, XML_STYLE_NAME
, EncodeStyleName(rName
) );
825 sTmp
.append( (sal_Int32
)nRowSpan
);
826 AddAttribute( XML_NAMESPACE_TABLE
, XML_NUMBER_ROWS_SPANNED
,
827 sTmp
.makeStringAndClear() );
833 sTmp
.append( (sal_Int32
)nColSpan
);
834 AddAttribute( XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_SPANNED
,
835 sTmp
.makeStringAndClear() );
841 // start node -> normal cell
843 // get cell range for table
844 Reference
<XCell
> xCell
= SwXCell::CreateXCell( (SwFrmFmt
*)rTblInfo
.GetTblFmt(),
846 (SwTable
*)rTblInfo
.GetTable() );
850 Reference
<XText
> xText( xCell
, UNO_QUERY
);
852 // get formula (and protection)
853 OUString sCellFormula
= xCell
->getFormula();
855 // if this cell has a formula, export it
856 // (with value and number format)
857 if (sCellFormula
.getLength()>0)
860 GetNamespaceMap().GetQNameByKey(
861 XML_NAMESPACE_OOOW
, sCellFormula
, sal_False
);
863 AddAttribute(XML_NAMESPACE_TABLE
, XML_FORMULA
, sQValue
);
866 // value and format (if NumberFormat != -1)
867 Reference
<XPropertySet
> xCellPropertySet(xCell
,
869 if (xCellPropertySet
.is())
871 sal_Int32 nNumberFormat
= 0;
872 Any aAny
= xCellPropertySet
->getPropertyValue(sNumberFormat
);
873 aAny
>>= nNumberFormat
;
875 if (NUMBERFORMAT_TEXT
== nNumberFormat
)
878 AddAttribute( XML_NAMESPACE_OFFICE
,
879 XML_VALUE_TYPE
, XML_STRING
);
881 else if ( (-1 != nNumberFormat
) && (xText
->getString().getLength() > 0) )
883 // number format key:
884 // (export values only if cell contains text;
886 XMLNumberFormatAttributesExportHelper::
887 SetNumberFormatAttributes(
888 *this, nNumberFormat
, xCell
->getValue(),
891 // else: invalid key; ignore
894 aAny
= xCellPropertySet
->getPropertyValue(sIsProtected
);
895 if (*(sal_Bool
*)aAny
.getValue())
897 AddAttribute( XML_NAMESPACE_TABLE
, XML_PROTECTED
,
901 if( !rTblInfo
.IsBaseSectionValid() )
903 OUString
sTextSection( RTL_CONSTASCII_USTRINGPARAM("TextSection") );
904 aAny
= xCellPropertySet
->getPropertyValue(sTextSection
);
905 Reference
< XTextSection
> xTextSection
;
906 aAny
>>= xTextSection
;
907 rTblInfo
.SetBaseSection( xTextSection
);
911 // export cell element
912 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
,
913 XML_TABLE_CELL
, sal_True
, sal_True
);
915 // export cell content
916 GetTextParagraphExport()->exportText( xText
,
917 rTblInfo
.GetBaseSection(),
922 DBG_ERROR("here should be a XCell");
928 // no start node -> merged cells: export subtable in cell
929 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
,
930 XML_TABLE_CELL
, sal_True
, sal_True
);
932 AddAttribute( XML_NAMESPACE_TABLE
, XML_IS_SUB_TABLE
,
933 GetXMLToken( XML_TRUE
) );
935 SvXMLElementExport
aElemExport( *this, XML_NAMESPACE_TABLE
,
936 XML_TABLE
, sal_True
, sal_True
);
937 ExportTableLines( rBox
.GetTabLines(), rTblInfo
);
943 void SwXMLExport::ExportTableLine( const SwTableLine
& rLine
,
944 const SwXMLTableLines_Impl
& rLines
,
945 SwXMLTableInfo_Impl
& rTblInfo
)
947 if( rLine
.hasSoftPageBreak() )
949 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TEXT
,
950 XML_SOFT_PAGE_BREAK
, sal_True
, sal_True
);
952 const SwFrmFmt
*pFrmFmt
= rLine
.GetFrmFmt();
955 const String
& rName
= pFrmFmt
->GetName();
958 AddAttribute( XML_NAMESPACE_TABLE
, XML_STYLE_NAME
, EncodeStyleName(rName
) );
963 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
,
964 XML_TABLE_ROW
, sal_True
, sal_True
);
965 const SwTableBoxes
& rBoxes
= rLine
.GetTabBoxes();
966 sal_uInt16 nBoxes
= rBoxes
.Count();
968 sal_uInt16 nCPos
= 0U;
969 sal_uInt16 nCol
= 0U;
970 for( sal_uInt16 nBox
=0U; nBox
<nBoxes
; nBox
++ )
972 const SwTableBox
*pBox
= rBoxes
[nBox
];
975 const long nRowSpan
= pBox
->getRowSpan();
978 SvXMLElementExport
aElem2( *this, XML_NAMESPACE_TABLE
,
979 XML_COVERED_TABLE_CELL
, sal_True
,
983 if( nBox
< nBoxes
-1U )
984 nCPos
= nCPos
+ (sal_uInt16
)SwWriteTable::GetBoxWidth( pBox
);
986 nCPos
= (sal_uInt16
)rLines
.GetWidth();
989 const sal_uInt16 nOldCol
= nCol
;
991 SwXMLTableColumn_Impl
aCol( nCPos
);
993 const sal_Bool bFound
=
995 rLines
.GetColumns().Seek_Entry( &aCol
, &nCol
);
996 ASSERT( bFound
, "couldn't find column" );
999 // --> OD 2009-03-19 #i95726#
1000 // Some fault tolerance, if table is somehow corrupted.
1001 if ( nCol
< nOldCol
)
1003 ASSERT( false, "table and/or table information seems to be corrupted." );
1004 if ( nBox
== nBoxes
- 1 )
1006 nCol
= rLines
.GetColumns().Count() - 1;
1015 sal_uInt16 nColSpan
= nCol
- nOldCol
+ 1U;
1017 if ( nRowSpan
>= 1 )
1018 ExportTableBox( *pBox
, nColSpan
, static_cast< sal_uInt16
>(nRowSpan
), rTblInfo
);
1020 for( sal_uInt16 i
=nOldCol
; i
<nCol
; i
++ )
1022 SvXMLElementExport
aElemExport( *this, XML_NAMESPACE_TABLE
,
1023 XML_COVERED_TABLE_CELL
, sal_True
,
1032 void SwXMLExport::ExportTableLines( const SwTableLines
& rLines
,
1033 SwXMLTableInfo_Impl
& rTblInfo
,
1034 USHORT nHeaderRows
)
1036 ASSERT( pTableLines
&& pTableLines
->Count(),
1037 "SwXMLExport::ExportTableLines: table columns infos missing" );
1038 if( !pTableLines
|| 0 == pTableLines
->Count() )
1041 SwXMLTableLines_Impl
*pLines
= 0;
1042 sal_uInt16 nInfoPos
;
1043 for( nInfoPos
=0; nInfoPos
< pTableLines
->Count(); nInfoPos
++ )
1045 if( pTableLines
->GetObject( nInfoPos
)->GetLines() == &rLines
)
1047 pLines
= pTableLines
->GetObject( nInfoPos
);
1052 "SwXMLExport::ExportTableLines: table columns info missing" );
1053 ASSERT( 0==nInfoPos
,
1054 "SwXMLExport::ExportTableLines: table columns infos are unsorted" );
1058 pTableLines
->Remove( nInfoPos
);
1059 if( 0 == pTableLines
->Count() )
1061 delete pTableLines
;
1065 // pass 2: export columns
1066 const SwXMLTableColumns_Impl
& rCols
= pLines
->GetColumns();
1067 sal_uInt16 nColumn
= 0U;
1068 sal_uInt16 nColumns
= rCols
.Count();
1069 sal_uInt16 nColRep
= 1U;
1070 SwXMLTableColumn_Impl
*pColumn
= (nColumns
> 0) ? rCols
[0U] : 0;
1074 SwXMLTableColumn_Impl
*pNextColumn
=
1075 (nColumn
< nColumns
) ? rCols
[nColumn
] : 0;
1077 pNextColumn
->GetStyleName() == pColumn
->GetStyleName() )
1083 AddAttribute( XML_NAMESPACE_TABLE
, XML_STYLE_NAME
,
1084 EncodeStyleName(pColumn
->GetStyleName()) );
1088 OUStringBuffer
sTmp(4);
1089 sTmp
.append( (sal_Int32
)nColRep
);
1090 AddAttribute( XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_REPEATED
,
1091 sTmp
.makeStringAndClear() );
1095 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
,
1096 XML_TABLE_COLUMN
, sal_True
, sal_True
);
1101 pColumn
= pNextColumn
;
1104 // pass 3: export line/rows
1105 sal_uInt16 nLines
= rLines
.Count();
1106 // export header rows, if present
1107 if( nHeaderRows
> 0 )
1109 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
,
1110 XML_TABLE_HEADER_ROWS
, sal_True
, sal_True
);
1112 DBG_ASSERT( nHeaderRows
<= nLines
, "more headers then lines?" );
1113 for( sal_uInt16 nLine
= 0U; nLine
< nHeaderRows
; nLine
++ )
1114 ExportTableLine( *(rLines
[nLine
]), *pLines
, rTblInfo
);
1116 // export remaining rows
1117 for( sal_uInt16 nLine
= nHeaderRows
; nLine
< nLines
; nLine
++ )
1119 ExportTableLine( *(rLines
[nLine
]), *pLines
, rTblInfo
);
1125 sal_Bool
lcl_xmltble_ClearName_Line( const SwTableLine
*& rpLine
, void* );
1127 sal_Bool
lcl_xmltble_ClearName_Box( const SwTableBox
*& rpBox
, void* )
1129 if( !rpBox
->GetSttNd() )
1131 ((SwTableBox
*)rpBox
)->GetTabLines().ForEach(
1132 &lcl_xmltble_ClearName_Line
, 0 );
1136 SwFrmFmt
*pFrmFmt
= ((SwTableBox
*)rpBox
)->GetFrmFmt();
1137 if( pFrmFmt
&& pFrmFmt
->GetName().Len() )
1138 pFrmFmt
->SetName( aEmptyStr
);
1144 sal_Bool
lcl_xmltble_ClearName_Line( const SwTableLine
*& rpLine
, void* )
1146 ((SwTableLine
*)rpLine
)->GetTabBoxes().ForEach(
1147 &lcl_xmltble_ClearName_Box
, 0 );
1152 void SwXMLExport::ExportTable( const SwTableNode
& rTblNd
)
1154 const SwTable
& rTbl
= rTblNd
.GetTable();
1155 const SwFrmFmt
*pTblFmt
= rTbl
.GetFrmFmt();
1156 if( pTblFmt
&& pTblFmt
->GetName().Len() )
1158 AddAttribute( XML_NAMESPACE_TABLE
, XML_NAME
, pTblFmt
->GetName() );
1159 AddAttribute( XML_NAMESPACE_TABLE
, XML_STYLE_NAME
,
1160 EncodeStyleName( pTblFmt
->GetName() ) );
1164 SvXMLElementExport
aElem( *this, XML_NAMESPACE_TABLE
, XML_TABLE
,
1165 sal_True
, sal_True
);
1167 // export DDE source (if this is a DDE table)
1168 if ( rTbl
.ISA(SwDDETable
) )
1170 // get DDE Field Type (contains the DDE connection)
1171 const SwDDEFieldType
* pDDEFldType
=
1172 ((SwDDETable
&)rTbl
).GetDDEFldType();
1175 AddAttribute( XML_NAMESPACE_OFFICE
, XML_NAME
,
1176 pDDEFldType
->GetName() );
1179 const String sCmd
= pDDEFldType
->GetCmd();
1180 AddAttribute( XML_NAMESPACE_OFFICE
, XML_DDE_APPLICATION
,
1181 sCmd
.GetToken(0, sfx2::cTokenSeperator
) );
1182 AddAttribute( XML_NAMESPACE_OFFICE
, XML_DDE_ITEM
,
1183 sCmd
.GetToken(1, sfx2::cTokenSeperator
) );
1184 AddAttribute( XML_NAMESPACE_OFFICE
, XML_DDE_TOPIC
,
1185 sCmd
.GetToken(2, sfx2::cTokenSeperator
) );
1188 if (pDDEFldType
->GetType() == sfx2::LINKUPDATE_ALWAYS
)
1190 AddAttribute( XML_NAMESPACE_OFFICE
,
1191 XML_AUTOMATIC_UPDATE
, XML_TRUE
);
1194 // DDE source element (always empty)
1195 SvXMLElementExport
aSource(*this, XML_NAMESPACE_OFFICE
,
1196 XML_DDE_SOURCE
, sal_True
, sal_False
);
1199 SwXMLTableInfo_Impl
aTblInfo( &rTbl
);
1200 ExportTableLines( rTbl
.GetTabLines(), aTblInfo
, rTbl
.GetRowsToRepeat() );
1202 ((SwTable
&)rTbl
).GetTabLines().ForEach( &lcl_xmltble_ClearName_Line
,
1207 void SwXMLTextParagraphExport::exportTable(
1208 const Reference
< XTextContent
> & rTextContent
,
1209 sal_Bool bAutoStyles
, sal_Bool _bProgress
)
1211 sal_Bool bOldShowProgress
= ((SwXMLExport
&)GetExport()).IsShowProgress();
1212 ((SwXMLExport
&)GetExport()).SetShowProgress( _bProgress
);
1214 Reference
< XTextTable
> xTxtTbl( rTextContent
, UNO_QUERY
);
1215 DBG_ASSERT( xTxtTbl
.is(), "text table missing" );
1218 const SwXTextTable
*pXTable
= 0;
1219 Reference
<XUnoTunnel
> xTableTunnel( rTextContent
, UNO_QUERY
);
1220 if( xTableTunnel
.is() )
1222 pXTable
= reinterpret_cast< SwXTextTable
* >(
1223 sal::static_int_cast
< sal_IntPtr
>( xTableTunnel
->getSomething( SwXTextTable::getUnoTunnelId() )));
1224 ASSERT( pXTable
, "SwXTextTable missing" );
1228 SwFrmFmt
*pFmt
= pXTable
->GetFrmFmt();
1229 ASSERT( pFmt
, "table format missing" );
1230 const SwTable
*pTbl
= SwTable::FindTable( pFmt
);
1231 ASSERT( pTbl
, "table missing" );
1232 const SwTableNode
*pTblNd
= pTbl
->GetTableNode();
1233 ASSERT( pTblNd
, "table node missing" );
1236 SwNodeIndex
aIdx( *pTblNd
);
1237 // AUTOSTYLES: Optimization: Do not export table autostyle if
1238 // we are currently exporting the content.xml stuff and
1239 // the table is located in header/footer:
1240 // #144704: During the flat XML export (used e.g. by .sdw-export)
1241 // ALL flags are set at the same time.
1242 const bool bExportStyles
= ( GetExport().getExportFlags() & EXPORT_STYLES
) != 0;
1243 if ( bExportStyles
|| !pFmt
->GetDoc()->IsInHeaderFooter( aIdx
) )
1244 ((SwXMLExport
&)GetExport()).ExportTableAutoStyles( *pTblNd
);
1248 ((SwXMLExport
&)GetExport()).ExportTable( *pTblNd
);
1253 ((SwXMLExport
&)GetExport()).SetShowProgress( bOldShowProgress
);