1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <xmloff/table/XMLTableExport.hxx>
22 #include <sal/config.h>
23 #include <sal/log.hxx>
24 #include <osl/diagnose.h>
26 #include <rtl/ustring.hxx>
28 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
29 #include <com/sun/star/text/XText.hpp>
30 #include <com/sun/star/table/XCellRange.hpp>
31 #include <com/sun/star/table/XColumnRowRange.hpp>
32 #include <com/sun/star/table/XMergeableCell.hpp>
33 #include <com/sun/star/style/XStyle.hpp>
34 #include <com/sun/star/beans/XPropertyState.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/beans/XPropertySetInfo.hpp>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 #include <tools/diagnose_ex.h>
40 #include <xmloff/xmlnmspe.hxx>
41 #include <xmloff/xmlprmap.hxx>
42 #include <xmloff/xmlexppr.hxx>
43 #include <xmloff/xmlexp.hxx>
44 #include <xmloff/xmltypes.hxx>
45 #include <xmlsdtypes.hxx>
46 #include <xmloff/maptype.hxx>
47 #include <xmloff/prhdlfac.hxx>
48 #include <xmloff/txtprmap.hxx>
51 using namespace ::xmloff::token
;
52 using namespace ::com::sun::star::uno
;
53 using namespace ::com::sun::star::lang
;
54 using namespace ::com::sun::star::table
;
55 using namespace ::com::sun::star::beans
;
56 using namespace ::com::sun::star::container
;
57 using namespace ::com::sun::star::text
;
58 using namespace ::com::sun::star::style
;
60 #define MAP_(name,prefix,token,type,context) { name, sizeof(name)-1, prefix, token, type, context, SvtSaveOptions::ODFVER_010, false }
61 #define CMAP(name,prefix,token,type,context) MAP_(name,prefix,token,type|XML_TYPE_PROP_TABLE_COLUMN,context)
62 #define RMAP(name,prefix,token,type,context) MAP_(name,prefix,token,type|XML_TYPE_PROP_TABLE_ROW,context)
63 #define CELLMAP(name,prefix,token,type,context) MAP_(name,prefix,token,type|XML_TYPE_PROP_TABLE_CELL,context)
64 #define MAP_END { nullptr, 0, 0, XML_EMPTY, 0, 0, SvtSaveOptions::ODFVER_010, false }
66 const XMLPropertyMapEntry
* getColumnPropertiesMap()
68 static const XMLPropertyMapEntry aXMLColumnProperties
[] =
70 CMAP( "Width", XML_NAMESPACE_STYLE
, XML_COLUMN_WIDTH
, XML_TYPE_MEASURE
, 0 ),
71 CMAP( "OptimalWidth", XML_NAMESPACE_STYLE
, XML_USE_OPTIMAL_COLUMN_WIDTH
, XML_TYPE_BOOL
, 0 ),
75 return &aXMLColumnProperties
[0];
78 const XMLPropertyMapEntry
* getRowPropertiesMap()
80 static const XMLPropertyMapEntry aXMLRowProperties
[] =
82 RMAP( "Height", XML_NAMESPACE_STYLE
, XML_ROW_HEIGHT
, XML_TYPE_MEASURE
, 0 ),
83 RMAP( "MinHeight", XML_NAMESPACE_STYLE
, XML_MIN_ROW_HEIGHT
, XML_TYPE_MEASURE
, 0 ),
84 RMAP( "OptimalHeight", XML_NAMESPACE_STYLE
, XML_USE_OPTIMAL_ROW_HEIGHT
, XML_TYPE_BOOL
, 0 ),
88 return &aXMLRowProperties
[0];
91 const XMLPropertyMapEntry
* getCellPropertiesMap()
93 static const XMLPropertyMapEntry aXMLCellProperties
[] =
95 CELLMAP( "RotateAngle", XML_NAMESPACE_STYLE
, XML_ROTATION_ANGLE
, XML_SD_TYPE_CELL_ROTATION_ANGLE
, 0),
99 return &aXMLCellProperties
[0];
102 class StringStatisticHelper
105 std::map
< OUString
, sal_Int32
> mStats
;
108 void add( const OUString
& rStyleName
);
109 void clear() { mStats
.clear(); }
111 sal_Int32
getModeString( /* out */ OUString
& rModeString
);
114 void StringStatisticHelper::add( const OUString
& rStyleName
)
116 std::map
< OUString
, sal_Int32
>::iterator
iter( mStats
.find( rStyleName
) );
117 if( iter
== mStats
.end() )
119 mStats
[rStyleName
] = 1;
127 sal_Int32
StringStatisticHelper::getModeString( OUString
& rStyleName
)
130 for( const auto& rStatsEntry
: mStats
)
132 if( rStatsEntry
.second
> nMax
)
134 rStyleName
= rStatsEntry
.first
;
135 nMax
= rStatsEntry
.second
;
144 class XMLCellExportPropertyMapper
: public SvXMLExportPropertyMapper
147 using SvXMLExportPropertyMapper::SvXMLExportPropertyMapper
;
148 /** this method is called for every item that has the
149 MID_FLAG_SPECIAL_ITEM_EXPORT flag set */
150 virtual void handleSpecialItem(SvXMLAttributeList
&, const XMLPropertyState
&, const SvXMLUnitConverter
&,
151 const SvXMLNamespaceMap
&, const std::vector
<XMLPropertyState
>*, sal_uInt32
) const override
153 // the SpecialItem NumberFormat must not be handled by this method
159 // class XMLTableExport
161 XMLTableExport::XMLTableExport(SvXMLExport
& rExp
, const rtl::Reference
< SvXMLExportPropertyMapper
>& xExportPropertyMapper
, const rtl::Reference
< XMLPropertyHandlerFactory
>& xFactoryRef
)
163 , mbExportTables( false )
166 Reference
< XMultiServiceFactory
> xFac( rExp
.GetModel(), UNO_QUERY
);
169 Sequence
< OUString
> sSNS( xFac
->getAvailableServiceNames() );
170 const OUString
* pSNS
= std::find_if(sSNS
.begin(), sSNS
.end(),
171 [](const OUString
& rSNS
) {
172 return rSNS
== "com.sun.star.drawing.TableShape"
173 || rSNS
== "com.sun.star.style.TableStyle"; });
174 if (pSNS
!= sSNS
.end())
176 mbExportTables
= true;
177 mbWriter
= (*pSNS
== "com.sun.star.style.TableStyle");
180 catch(const Exception
&)
186 mxCellExportPropertySetMapper
= new XMLCellExportPropertyMapper(new XMLTextPropertySetMapper(TextPropMap::CELL
, true));
190 mxCellExportPropertySetMapper
= xExportPropertyMapper
;
191 mxCellExportPropertySetMapper
->ChainExportMapper(XMLTextParagraphExport::CreateParaExtPropMapper(rExp
));
192 mxCellExportPropertySetMapper
->ChainExportMapper(new SvXMLExportPropertyMapper(new XMLPropertySetMapper(getCellPropertiesMap(), xFactoryRef
.get(), true)));
195 mxRowExportPropertySetMapper
= new SvXMLExportPropertyMapper( new XMLPropertySetMapper( getRowPropertiesMap(), xFactoryRef
.get(), true ) );
196 mxColumnExportPropertySetMapper
= new SvXMLExportPropertyMapper( new XMLPropertySetMapper( getColumnPropertiesMap(), xFactoryRef
.get(), true ) );
198 mrExport
.GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_COLUMN
,
199 OUString(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_NAME
),
200 mxColumnExportPropertySetMapper
.get(),
201 OUString(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX
));
202 mrExport
.GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_ROW
,
203 OUString(XML_STYLE_FAMILY_TABLE_ROW_STYLES_NAME
),
204 mxRowExportPropertySetMapper
.get(),
205 OUString(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX
));
206 mrExport
.GetAutoStylePool()->AddFamily(XML_STYLE_FAMILY_TABLE_CELL
,
207 OUString(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME
),
208 mxCellExportPropertySetMapper
.get(),
209 OUString(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX
));
212 XMLTableExport::~XMLTableExport ()
216 static bool has_states( const std::vector
< XMLPropertyState
>& xPropStates
)
218 return std::any_of(xPropStates
.cbegin(), xPropStates
.cend(),
219 [](const XMLPropertyState
& rPropertyState
) { return rPropertyState
.mnIndex
!= -1; });
222 void XMLTableExport::collectTableAutoStyles(const Reference
< XColumnRowRange
>& xColumnRowRange
)
224 if( !mbExportTables
)
227 std::shared_ptr
< XMLTableInfo
> xTableInfo( new XMLTableInfo
);
228 maTableInfoMap
[xColumnRowRange
] = xTableInfo
;
232 Reference
< XIndexAccess
> xIndexAccessCols( xColumnRowRange
->getColumns(), UNO_QUERY_THROW
);
233 const sal_Int32 nColumnCount
= xIndexAccessCols
->getCount();
234 for( sal_Int32 nColumn
= 0; nColumn
< nColumnCount
; ++nColumn
) try
236 Reference
< XPropertySet
> xPropSet( xIndexAccessCols
->getByIndex(nColumn
) , UNO_QUERY_THROW
);
237 std::vector
< XMLPropertyState
> aPropStates( mxColumnExportPropertySetMapper
->Filter( xPropSet
) );
239 if( has_states( aPropStates
) )
241 const OUString
sStyleName( mrExport
.GetAutoStylePool()->Add(XML_STYLE_FAMILY_TABLE_COLUMN
, aPropStates
) );
242 Reference
< XInterface
> xKey( xPropSet
, UNO_QUERY
);
243 xTableInfo
->maColumnStyleMap
[xKey
] = sStyleName
;
246 catch(const Exception
&)
248 OSL_FAIL("xmloff::XMLTableExport::collectTableAutoStyles(), exception during column style collection!");
251 Reference
< XIndexAccess
> xIndexAccessRows( xColumnRowRange
->getRows(), UNO_QUERY_THROW
);
252 const sal_Int32 nRowCount
= xIndexAccessRows
->getCount();
253 xTableInfo
->maDefaultRowCellStyles
.resize(nRowCount
);
255 StringStatisticHelper aStringStatistic
;
257 for( sal_Int32 nRow
= 0; nRow
< nRowCount
; ++nRow
)
260 Reference
< XPropertySet
> xPropSet( xIndexAccessRows
->getByIndex(nRow
) , UNO_QUERY_THROW
);
261 std::vector
< XMLPropertyState
> aRowPropStates( mxRowExportPropertySetMapper
->Filter( xPropSet
) );
263 if( has_states( aRowPropStates
) )
265 const OUString
sStyleName( mrExport
.GetAutoStylePool()->Add(XML_STYLE_FAMILY_TABLE_ROW
, aRowPropStates
) );
266 Reference
< XInterface
> xKey( xPropSet
, UNO_QUERY
);
267 xTableInfo
->maRowStyleMap
[xKey
] = sStyleName
;
270 // get the current row
271 Reference
< XCellRange
> xCellRange( xPropSet
, UNO_QUERY_THROW
);
272 for ( sal_Int32 nColumn
= 0; nColumn
< nColumnCount
; ++nColumn
)
274 // get current cell, remarks row index is 0, because we get the range for each row separate
275 Reference
< XPropertySet
> xCellSet( xCellRange
->getCellByPosition(nColumn
, 0), UNO_QUERY_THROW
);
278 OUString sParentStyleName
;
279 Reference
< XPropertySetInfo
> xPropertySetInfo( xCellSet
->getPropertySetInfo() );
280 if( xPropertySetInfo
.is() && xPropertySetInfo
->hasPropertyByName("Style") )
282 Reference
< XStyle
> xStyle( xCellSet
->getPropertyValue("Style"), UNO_QUERY
);
284 sParentStyleName
= xStyle
->getName();
287 // create auto style, if needed
289 std::vector
< XMLPropertyState
> aCellPropStates( mxCellExportPropertySetMapper
->Filter( xCellSet
) );
290 if( has_states( aCellPropStates
) )
291 sStyleName
= mrExport
.GetAutoStylePool()->Add(XML_STYLE_FAMILY_TABLE_CELL
, aCellPropStates
);
293 sStyleName
= sParentStyleName
;
295 if( !sStyleName
.isEmpty() )
297 Reference
< XInterface
> xKey( xCellSet
, UNO_QUERY
);
298 xTableInfo
->maCellStyleMap
[xKey
] = sStyleName
;
301 // create auto style for text
302 Reference
< XText
> xText(xCellSet
, UNO_QUERY
);
303 if(xText
.is() && !xText
->getString().isEmpty())
304 GetExport().GetTextParagraphExport()->collectTextAutoStyles( xText
);
306 aStringStatistic
.add( sStyleName
);
309 OUString sDefaultCellStyle
;
310 if( aStringStatistic
.getModeString( sDefaultCellStyle
) > 1 )
311 xTableInfo
->maDefaultRowCellStyles
[nRow
] = sDefaultCellStyle
;
313 aStringStatistic
.clear();
315 catch(const Exception
&)
317 OSL_FAIL("xmloff::XMLTableExport::collectTableAutoStyles(), exception during column style collection!");
320 catch(const Exception
&)
322 OSL_FAIL("xmloff::XMLTableExport::collectTableAutoStyles(), exception caught!");
326 void XMLTableExport::exportTable( const Reference
< XColumnRowRange
>& xColumnRowRange
)
328 if( !mbExportTables
)
333 std::shared_ptr
< XMLTableInfo
> xTableInfo( maTableInfoMap
[xColumnRowRange
] );
335 // get row and column count
336 Reference
< XIndexAccess
> xIndexAccess( xColumnRowRange
->getRows(), UNO_QUERY_THROW
);
337 Reference
< XIndexAccess
> xIndexAccessCols( xColumnRowRange
->getColumns(), UNO_QUERY_THROW
);
339 const sal_Int32 rowCount
= xIndexAccess
->getCount();
340 const sal_Int32 columnCount
= xIndexAccessCols
->getCount();
342 SvXMLElementExport
tableElement( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE
, true, true );
344 // export table columns
345 ExportTableColumns( xIndexAccessCols
, xTableInfo
);
347 // start iterating rows and columns
348 for ( sal_Int32 rowIndex
= 0; rowIndex
< rowCount
; rowIndex
++ )
350 // get the current row
351 Reference
< XCellRange
> xCellRange( xIndexAccess
->getByIndex(rowIndex
), UNO_QUERY_THROW
);
353 OUString sDefaultCellStyle
;
356 if( xTableInfo
.get() )
358 Reference
< XInterface
> xKey( xCellRange
, UNO_QUERY
);
359 const OUString
sStyleName( xTableInfo
->maRowStyleMap
[xKey
] );
360 if( !sStyleName
.isEmpty() )
361 mrExport
.AddAttribute(XML_NAMESPACE_TABLE
, XML_STYLE_NAME
, sStyleName
);
363 sDefaultCellStyle
= xTableInfo
->maDefaultRowCellStyles
[rowIndex
];
364 if( !sDefaultCellStyle
.isEmpty() )
365 mrExport
.AddAttribute(XML_NAMESPACE_TABLE
, XML_DEFAULT_CELL_STYLE_NAME
, sDefaultCellStyle
);
369 SvXMLElementExport
tableRowElement( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_ROW
, true, true );
371 for ( sal_Int32 columnIndex
= 0; columnIndex
< columnCount
; columnIndex
++ )
373 // get current cell, remarks row index is 0, because we get the range for each row separate
374 Reference
< XCell
> xCell( xCellRange
->getCellByPosition(columnIndex
, 0), UNO_SET_THROW
);
376 // use XMergeableCell interface from offapi
377 Reference
< XMergeableCell
> xMergeableCell( xCell
, UNO_QUERY_THROW
);
380 ExportCell( xCell
, xTableInfo
, sDefaultCellStyle
);
384 catch(const Exception
&)
386 OSL_FAIL( "XMLTableExport::exportTable(), exception caught!" );
390 // Export the table columns
392 void XMLTableExport::ExportTableColumns( const Reference
< XIndexAccess
>& xtableColumnsIndexAccess
, const std::shared_ptr
< XMLTableInfo
>& rTableInfo
)
394 const sal_Int32 nColumnCount
= xtableColumnsIndexAccess
->getCount();
395 for( sal_Int32 nColumn
= 0; nColumn
< nColumnCount
; ++nColumn
)
397 Reference
< XPropertySet
> xColumnProperties( xtableColumnsIndexAccess
->getByIndex(nColumn
) , UNO_QUERY
);
398 if ( xColumnProperties
.is() )
401 if( rTableInfo
.get() )
403 Reference
< XInterface
> xKey( xColumnProperties
, UNO_QUERY
);
404 const OUString
sStyleName( rTableInfo
->maColumnStyleMap
[xKey
] );
405 if( !sStyleName
.isEmpty() )
406 mrExport
.AddAttribute(XML_NAMESPACE_TABLE
, XML_STYLE_NAME
, sStyleName
);
409 // TODO: all columns first have to be checked if someone
410 // have identical properties. If yes, attr table:number-columns-repeated
411 // has to be written.
412 SvXMLElementExport
tableColumnElement( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_COLUMN
, true, true );
417 // ODF export for a table cell.
419 void XMLTableExport::ExportCell( const Reference
< XCell
>& xCell
, const std::shared_ptr
< XMLTableInfo
>& rTableInfo
, const OUString
& rDefaultCellStyle
)
421 bool bIsMerged
= false;
422 sal_Int32 nRowSpan
= 0;
423 sal_Int32 nColSpan
= 0;
427 if( rTableInfo
.get() )
430 Reference
< XInterface
> xKey( xCell
, UNO_QUERY
);
431 const OUString
sStyleName( rTableInfo
->maCellStyleMap
[xKey
] );
432 if( !sStyleName
.isEmpty() && (sStyleName
!= rDefaultCellStyle
) )
433 mrExport
.AddAttribute(XML_NAMESPACE_TABLE
, XML_STYLE_NAME
, sStyleName
);
436 Reference
< XMergeableCell
> xMerge( xCell
, UNO_QUERY
);
439 bIsMerged
= xMerge
->isMerged();
440 nRowSpan
= xMerge
->getRowSpan();
441 nColSpan
= xMerge
->getColumnSpan();
443 SAL_WARN_IF( (nRowSpan
< 1) || (nColSpan
< 1), "xmloff", "xmloff::XMLTableExport::ExportCell(), illegal row or col span < 1?" );
445 catch (const Exception
&)
447 OSL_FAIL( "exception while exporting a table cell" );
450 // table:number-columns-repeated
453 // table:number-columns-spanned
455 mrExport
.AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_COLUMNS_SPANNED
, OUString::number( nColSpan
) );
457 // table:number-rows-spanned
459 mrExport
.AddAttribute(XML_NAMESPACE_TABLE
, XML_NUMBER_ROWS_SPANNED
, OUString::number( nRowSpan
) );
461 // <table:table-cell> or <table:covered-table-cell>
462 SvXMLElementExport
tableCellElement( mrExport
, XML_NAMESPACE_TABLE
, bIsMerged
? XML_COVERED_TABLE_CELL
: XML_TABLE_CELL
, true, true );
464 // export cells text content
465 ImpExportText( xCell
);
468 // ODF export of the text contents of a table cell.
469 // Remarks: Up to now we only export text contents!
470 // TODO: Check against nested tables...
472 void XMLTableExport::ImpExportText( const Reference
< XCell
>& xCell
)
474 Reference
< XText
> xText( xCell
, UNO_QUERY
);
475 if( xText
.is() && !xText
->getString().isEmpty())
476 mrExport
.GetTextParagraphExport()->exportText( xText
);
479 void XMLTableExport::exportTableStyles()
481 if( !mbExportTables
)
484 rtl::Reference
<XMLStyleExport
> aStEx
;
485 OUString sCellStyleName
;
488 sCellStyleName
= "CellStyles";
489 aStEx
.set(new XMLCellStyleExport(mrExport
));
493 // write graphic family styles
494 sCellStyleName
= "cell";
495 aStEx
.set(new XMLStyleExport(mrExport
, mrExport
.GetAutoStylePool().get()));
498 aStEx
->exportStyleFamily(sCellStyleName
, OUString(XML_STYLE_FAMILY_TABLE_CELL_STYLES_NAME
), mxCellExportPropertySetMapper
.get(), true, XML_STYLE_FAMILY_TABLE_CELL
);
500 exportTableTemplates();
503 // Export the collected automatic styles
505 void XMLTableExport::exportAutoStyles()
507 if( !mbExportTables
)
510 mrExport
.GetAutoStylePool()->exportXML( XML_STYLE_FAMILY_TABLE_COLUMN
);
511 mrExport
.GetAutoStylePool()->exportXML( XML_STYLE_FAMILY_TABLE_ROW
);
512 mrExport
.GetAutoStylePool()->exportXML( XML_STYLE_FAMILY_TABLE_CELL
);
515 const TableStyleElement
* getTableStyleMap()
517 static const struct TableStyleElement gTableStyleElements
[] =
519 { XML_FIRST_ROW
, OUString("first-row") },
520 { XML_LAST_ROW
, OUString("last-row") },
521 { XML_FIRST_COLUMN
, OUString("first-column") },
522 { XML_LAST_COLUMN
, OUString("last-column") },
523 { XML_BODY
, OUString("body") },
524 { XML_EVEN_ROWS
, OUString("even-rows") },
525 { XML_ODD_ROWS
, OUString("odd-rows") },
526 { XML_EVEN_COLUMNS
, OUString("even-columns") },
527 { XML_ODD_COLUMNS
, OUString("odd-columns") },
528 { XML_BACKGROUND
, OUString("background") },
529 { XML_TOKEN_END
, OUString() }
532 return &gTableStyleElements
[0];
535 const TableStyleElement
* getWriterSpecificTableStyleMap()
537 static const struct TableStyleElement gWriterSpecificTableStyleElements
[] =
539 { XML_FIRST_ROW_EVEN_COLUMN
, OUString("first-row-even-column") },
540 { XML_LAST_ROW_EVEN_COLUMN
, OUString("last-row-even-column") },
541 { XML_FIRST_ROW_END_COLUMN
, OUString("first-row-end-column") },
542 { XML_FIRST_ROW_START_COLUMN
, OUString("first-row-start-column") },
543 { XML_LAST_ROW_END_COLUMN
, OUString("last-row-end-column") },
544 { XML_LAST_ROW_START_COLUMN
, OUString("last-row-start-column") },
545 { XML_TOKEN_END
, OUString() }
548 return &gWriterSpecificTableStyleElements
[0];
551 static const TableStyleElement
* getWriterSpecificTableStyleAttributes()
553 static const struct TableStyleElement gWriterSpecifitTableStyleAttributes
[] =
555 { XML_FIRST_ROW_END_COLUMN
, OUString("FirstRowEndColumn") },
556 { XML_FIRST_ROW_START_COLUMN
, OUString("FirstRowStartColumn") },
557 { XML_LAST_ROW_END_COLUMN
, OUString("LastRowEndColumn") },
558 { XML_LAST_ROW_START_COLUMN
, OUString("LastRowStartColumn") },
559 { XML_TOKEN_END
, OUString() }
562 return &gWriterSpecifitTableStyleAttributes
[0];
565 void XMLTableExport::exportTableTemplates()
567 if( !mbExportTables
)
572 Reference
< XStyleFamiliesSupplier
> xFamiliesSupp( mrExport
.GetModel(), UNO_QUERY_THROW
);
573 Reference
< XNameAccess
> xFamilies( xFamiliesSupp
->getStyleFamilies() );
574 OUString sFamilyName
;
576 sFamilyName
= "TableStyles";
578 sFamilyName
= "table";
580 Reference
< XIndexAccess
> xTableFamily( xFamilies
->getByName( sFamilyName
), UNO_QUERY_THROW
);
582 for( sal_Int32 nIndex
= 0; nIndex
< xTableFamily
->getCount(); nIndex
++ ) try
584 SvtSaveOptions::ODFSaneDefaultVersion eVersion
= mrExport
.getSaneDefaultVersion();
586 Reference
< XStyle
> xTableStyle( xTableFamily
->getByIndex( nIndex
), UNO_QUERY_THROW
);
587 if( !xTableStyle
->isInUse() )
590 const TableStyleElement
* pElements
;
593 mrExport
.AddAttribute(XML_NAMESPACE_TABLE
, XML_NAME
, xTableStyle
->getName());
594 Reference
<XPropertySet
> xTableStylePropSet(xTableStyle
, UNO_QUERY_THROW
);
595 pElements
= getWriterSpecificTableStyleAttributes();
596 while(pElements
->meElement
!= XML_TOKEN_END
)
601 xTableStylePropSet
->getPropertyValue(pElements
->msStyleName
) >>= sVal
;
602 mrExport
.AddAttribute(XML_NAMESPACE_TABLE
, pElements
->meElement
, sVal
);
604 catch(const Exception
&)
606 TOOLS_WARN_EXCEPTION("xmloff", "XMLTableExport::exportTableTemplates(), export Writer specific attributes, exception caught!");
613 // checks if any of the extended version of ODF are set
614 if ((eVersion
& SvtSaveOptions::ODFSVER_EXTENDED
) != 0)
616 // tdf#106780 historically this wrong attribute was used
617 // for the name; write it if extended because LO < 5.3 can
618 // read only text:style-name, not the correct table:name
619 mrExport
.AddAttribute(XML_NAMESPACE_TEXT
, XML_STYLE_NAME
, GetExport().EncodeStyleName( xTableStyle
->getName() ) );
621 mrExport
.AddAttribute(XML_NAMESPACE_TABLE
, XML_NAME
, GetExport().EncodeStyleName(xTableStyle
->getName()));
624 SvXMLElementExport
tableTemplate( mrExport
, XML_NAMESPACE_TABLE
, XML_TABLE_TEMPLATE
, true, true );
626 Reference
< XNameAccess
> xStyleNames( xTableStyle
, UNO_QUERY_THROW
);
627 pElements
= getTableStyleMap();
628 while( pElements
->meElement
!= XML_TOKEN_END
)
632 Reference
< XStyle
> xStyle( xStyleNames
->getByName( pElements
->msStyleName
), UNO_QUERY
);
635 mrExport
.AddAttribute(XML_NAMESPACE_TABLE
, XML_STYLE_NAME
, GetExport().EncodeStyleName( xStyle
->getName() ) );
636 SvXMLElementExport
element( mrExport
, XML_NAMESPACE_TABLE
, pElements
->meElement
, true, true );
639 catch(const Exception
&)
641 OSL_FAIL("xmloff::XMLTableExport::exportTableTemplates(), exception caught!");
647 if (mbWriter
&& ((eVersion
& SvtSaveOptions::ODFSVER_EXTENDED
) != 0))
649 pElements
= getWriterSpecificTableStyleMap();
650 while(pElements
->meElement
!= XML_TOKEN_END
)
654 Reference
<XStyle
> xStyle(xStyleNames
->getByName(pElements
->msStyleName
), UNO_QUERY
);
657 mrExport
.AddAttribute(XML_NAMESPACE_TABLE
, XML_STYLE_NAME
, GetExport().EncodeStyleName(xStyle
->getName()));
658 SvXMLElementExport
element(mrExport
, XML_NAMESPACE_LO_EXT
, pElements
->meElement
, true, true);
661 catch(const Exception
&)
663 TOOLS_WARN_EXCEPTION("xmloff", "XMLTableExport::exportTableTemplates(), export Writer specific styles, exception caught!");
669 catch(const Exception
&)
671 TOOLS_WARN_EXCEPTION("xmloff", "XMLTableExport::exportTableDesigns(), exception caught while exporting a table design!");
674 catch(const Exception
&)
676 TOOLS_WARN_EXCEPTION("xmloff", "XMLTableExport::exportTableDesigns()");
680 void XMLCellStyleExport::exportStyleContent(const Reference
<XStyle
>& /*rStyle*/)
684 void XMLCellStyleExport::exportStyleAttributes(const Reference
<XStyle
>& rStyle
)
686 Reference
<XPropertySet
> xPropSet(rStyle
, UNO_QUERY
);
689 Reference
<XPropertySetInfo
> xPropSetInfo(xPropSet
->getPropertySetInfo());
690 const OUString
sNumberFormat("NumberFormat");
691 if (xPropSetInfo
->hasPropertyByName(sNumberFormat
))
693 Reference
<XPropertyState
> xPropState(xPropSet
, UNO_QUERY
);
694 if (xPropState
.is() && (PropertyState_DIRECT_VALUE
==
695 xPropState
->getPropertyState(sNumberFormat
)))
697 sal_Int32 nNumberFormat
= 0;
698 if (xPropSet
->getPropertyValue(sNumberFormat
) >>= nNumberFormat
)
699 GetExport().AddAttribute(XML_NAMESPACE_STYLE
, XML_DATA_STYLE_NAME
,
700 GetExport().getDataStyleName(nNumberFormat
));
706 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */