xref: /trunk/main/sw/source/filter/xml/xmltble.cxx (revision efeef26f)
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