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 <sal/config.h>
22 #include <com/sun/star/frame/XModel.hpp>
23 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
24 #include <com/sun/star/table/XTableRows.hpp>
25 #include <com/sun/star/table/XMergeableCell.hpp>
26 #include <com/sun/star/table/XMergeableCellRange.hpp>
27 #include <com/sun/star/table/XTable.hpp>
28 #include <com/sun/star/text/XText.hpp>
29 #include <com/sun/star/container/XNameContainer.hpp>
30 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
31 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
32 #include <com/sun/star/style/XStyle.hpp>
33 #include <comphelper/sequence.hxx>
34 #include <tools/diagnose_ex.h>
36 #include <xmloff/table/XMLTableImport.hxx>
37 #include <xmloff/xmlprmap.hxx>
38 #include <xmloff/txtimp.hxx>
39 #include <xmloff/xmlimp.hxx>
40 #include <xmloff/namespacemap.hxx>
41 #include <xmloff/xmlstyle.hxx>
42 #include <xmloff/prstylei.hxx>
44 #include <xmloff/xmlnamespace.hxx>
45 #include <xmloff/xmluconv.hxx>
48 #include <sal/log.hxx>
52 using namespace ::xmloff::token
;
53 using namespace ::com::sun::star::beans
;
54 using namespace ::com::sun::star::uno
;
55 using namespace ::com::sun::star::table
;
56 using namespace ::com::sun::star::xml::sax
;
57 using namespace ::com::sun::star::text
;
58 using namespace ::com::sun::star::style
;
59 using namespace ::com::sun::star::lang
;
60 using namespace ::com::sun::star::container
;
67 OUString msDefaultCellStyleName
;
70 class XMLProxyContext
: public SvXMLImportContext
73 XMLProxyContext( SvXMLImport
& rImport
, const SvXMLImportContextRef
& xParent
, sal_uInt16 nPrfx
, const OUString
& rLName
);
75 virtual SvXMLImportContextRef
CreateChildContext( sal_uInt16 nPrefix
, const OUString
& rLocalName
, const Reference
< XAttributeList
>& xAttrList
) override
;
78 SvXMLImportContextRef mxParent
;
83 sal_Int32 mnStartColumn
;
85 sal_Int32 mnEndColumn
;
88 MergeInfo( sal_Int32 nStartColumn
, sal_Int32 nStartRow
, sal_Int32 nColumnSpan
, sal_Int32 nRowSpan
)
89 : mnStartColumn( nStartColumn
), mnStartRow( nStartRow
), mnEndColumn( nStartColumn
+ nColumnSpan
- 1 ), mnEndRow( nStartRow
+ nRowSpan
- 1 ) {};
94 typedef std::vector
< std::shared_ptr
< MergeInfo
> > MergeInfoVector
;
96 class XMLTableImportContext
: public SvXMLImportContext
99 XMLTableImportContext( const rtl::Reference
< XMLTableImport
>& xThis
, Reference
< XColumnRowRange
> const & xColumnRowRange
);
101 virtual SvXMLImportContextRef
CreateChildContext( sal_uInt16 nPrefix
, const OUString
& rLocalName
, const Reference
< XAttributeList
>& xAttrList
) override
;
103 virtual void SAL_CALL
endFastElement(sal_Int32 nElement
) override
;
107 SvXMLImportContextRef
ImportColumn( const Reference
< XAttributeList
>& xAttrList
);
108 SvXMLImportContext
* ImportRow( sal_uInt16 nPrefix
, const OUString
& rLocalName
, const Reference
< XAttributeList
>& xAttrList
);
109 SvXMLImportContextRef
ImportCell( sal_uInt16 nPrefix
, const OUString
& rLocalName
, const Reference
< XAttributeList
>& xAttrList
);
111 OUString
GetDefaultCellStyleName() const;
113 css::uno::Reference
< css::table::XTable
> mxTable
;
114 Reference
< XTableColumns
> mxColumns
;
115 Reference
< XTableRows
> mxRows
;
117 std::vector
< std::shared_ptr
< ColumnInfo
> > maColumnInfos
;
118 sal_Int32 mnCurrentRow
;
119 sal_Int32 mnCurrentColumn
;
121 // default cell style name for the current row
122 OUString msDefaultCellStyleName
;
124 MergeInfoVector maMergeInfos
;
129 class XMLCellImportContext
: public SvXMLImportContext
132 XMLCellImportContext( SvXMLImport
& rImport
,
133 const Reference
< XMergeableCell
>& xCell
,
134 const OUString
& sDefaultCellStyleName
,
135 sal_uInt16 nPrfx
, const OUString
& rLName
,
136 const css::uno::Reference
< css::xml::sax::XAttributeList
>& xAttrList
);
138 virtual SvXMLImportContextRef
CreateChildContext( sal_uInt16 nPrefix
, const OUString
& rLocalName
, const Reference
< XAttributeList
>& xAttrList
) override
;
140 virtual void SAL_CALL
endFastElement(sal_Int32 nElement
) override
;
142 sal_Int32
getColumnSpan() const { return mnColSpan
; }
143 sal_Int32
getRowSpan() const { return mnRowSpan
; }
144 sal_Int32
getRepeated() const { return mnRepeated
; }
146 Reference
< XMergeableCell
> mxCell
;
147 Reference
< XTextCursor
> mxCursor
;
148 Reference
< XTextCursor
> mxOldCursor
;
149 bool mbListContextPushed
;
151 sal_Int32 mnColSpan
, mnRowSpan
, mnRepeated
;
154 class XMLTableTemplateContext
: public SvXMLStyleContext
157 XMLTableTemplateContext( SvXMLImport
& rImport
);
159 // Create child element.
160 virtual css::uno::Reference
< css::xml::sax::XFastContextHandler
> SAL_CALL
createFastChildContext(
161 sal_Int32 nElement
, const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& AttrList
) override
;
163 virtual void SAL_CALL
endFastElement(sal_Int32 nElement
) override
;
165 virtual void CreateAndInsert( bool bOverwrite
) override
;
167 virtual void SetAttribute( sal_uInt16 nPrefixKey
,
168 const OUString
& rLocalName
,
169 const OUString
& rValue
) override
;
171 XMLTableTemplate maTableTemplate
;
172 OUString msTemplateStyleName
;
178 XMLProxyContext::XMLProxyContext( SvXMLImport
& rImport
, const SvXMLImportContextRef
& xParent
, sal_uInt16 nPrfx
, const OUString
& rLName
)
179 : SvXMLImportContext( rImport
, nPrfx
, rLName
)
180 , mxParent( xParent
)
184 SvXMLImportContextRef
XMLProxyContext::CreateChildContext( sal_uInt16 nPrefix
, const OUString
& rLocalName
, const Reference
< XAttributeList
>& xAttrList
)
187 return mxParent
->CreateChildContext( nPrefix
, rLocalName
, xAttrList
);
192 XMLTableImport::XMLTableImport( SvXMLImport
& rImport
, const rtl::Reference
< XMLPropertySetMapper
>& xCellPropertySetMapper
, const rtl::Reference
< XMLPropertyHandlerFactory
>& xFactoryRef
)
193 : mrImport( rImport
)
195 bool bWriter
= false;
196 // check if called by Writer
197 Reference
<XMultiServiceFactory
> xFac(rImport
.GetModel(), UNO_QUERY
);
200 Sequence
<OUString
> sSNS
= xFac
->getAvailableServiceNames();
201 bWriter
= comphelper::findValue(sSNS
, "com.sun.star.style.TableStyle") != -1;
203 catch(const Exception
&)
205 SAL_WARN("xmloff.table", "Error while checking available service names");
210 mxCellImportPropertySetMapper
= XMLTextImportHelper::CreateTableCellExtPropMapper(rImport
);
214 mxCellImportPropertySetMapper
= new SvXMLImportPropertyMapper( xCellPropertySetMapper
.get(), rImport
);
215 mxCellImportPropertySetMapper
->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(rImport
));
216 mxCellImportPropertySetMapper
->ChainImportMapper(new SvXMLImportPropertyMapper(new XMLPropertySetMapper(getCellPropertiesMap(), xFactoryRef
.get(), true), rImport
));
219 rtl::Reference
< XMLPropertySetMapper
> xRowMapper( new XMLPropertySetMapper( getRowPropertiesMap(), xFactoryRef
.get(), false ) );
220 mxRowImportPropertySetMapper
= new SvXMLImportPropertyMapper( xRowMapper
, rImport
);
222 rtl::Reference
< XMLPropertySetMapper
> xColMapper( new XMLPropertySetMapper( getColumnPropertiesMap(), xFactoryRef
.get(), false ) );
223 mxColumnImportPropertySetMapper
= new SvXMLImportPropertyMapper( xColMapper
, rImport
);
226 XMLTableImport::~XMLTableImport()
230 SvXMLImportContext
* XMLTableImport::CreateTableContext( Reference
< XColumnRowRange
> const & xColumnRowRange
)
232 rtl::Reference
< XMLTableImport
> xThis( this );
233 return new XMLTableImportContext( xThis
, xColumnRowRange
);
236 SvXMLStyleContext
* XMLTableImport::CreateTableTemplateContext( sal_Int32
/*nElement*/, const Reference
< XFastAttributeList
>& /*xAttrList*/ )
238 return new XMLTableTemplateContext( mrImport
);
241 void XMLTableImport::addTableTemplate( const OUString
& rsStyleName
, XMLTableTemplate
& xTableTemplate
)
243 auto xPtr
= std::make_shared
<XMLTableTemplate
>();
244 xPtr
->swap( xTableTemplate
);
245 maTableTemplates
[rsStyleName
] = xPtr
;
248 void XMLTableImport::insertTabletemplate(const OUString
& rsStyleName
, bool bOverwrite
)
250 XMLTableTemplateMap::iterator it
= maTableTemplates
.find(rsStyleName
);
251 if (it
== maTableTemplates
.end())
256 Reference
<XStyleFamiliesSupplier
> xFamiliesSupp(mrImport
.GetModel(), UNO_QUERY_THROW
);
257 Reference
<XNameAccess
> xFamilies(xFamiliesSupp
->getStyleFamilies());
259 Reference
<XNameContainer
> xTableFamily(xFamilies
->getByName("TableStyles"), UNO_QUERY_THROW
);
260 Reference
<XIndexAccess
> xCellFamily(xFamilies
->getByName("CellStyles"), UNO_QUERY_THROW
);
262 const OUString
sTemplateName(it
->first
);
263 Reference
<XMultiServiceFactory
> xFactory(mrImport
.GetModel(), UNO_QUERY_THROW
);
264 Reference
<XNameReplace
> xTemplate(xFactory
->createInstance("com.sun.star.style.TableStyle"), UNO_QUERY_THROW
);
266 std::shared_ptr
<XMLTableTemplate
> xT(it
->second
);
268 for (const auto& rStyle
: *xT
) try
270 const OUString
sPropName(rStyle
.first
);
271 const OUString
sStyleName(rStyle
.second
);
272 // Internally unassigned cell styles are stored by display name.
273 // However table-template elements reference cell styles by its encoded name.
274 // This loop is looking for cell style by their encoded names.
275 sal_Int32 nCount
= xCellFamily
->getCount();
276 for (sal_Int32 i
=0; i
< nCount
; ++i
)
278 Any xCellStyle
= xCellFamily
->getByIndex(i
);
279 OUString sEncodedStyleName
= mrImport
.GetMM100UnitConverter().encodeStyleName(
280 xCellStyle
.get
<Reference
<XStyle
>>()->getName());
281 if (sEncodedStyleName
== sStyleName
)
283 xTemplate
->replaceByName(sPropName
, xCellStyle
);
288 catch (Exception
const &)
290 TOOLS_WARN_EXCEPTION("xmloff.table", "XMLTableImport::insertTabletemplate()");
295 if (xTableFamily
->hasByName(sTemplateName
) && bOverwrite
)
296 xTableFamily
->replaceByName(sTemplateName
, Any(xTemplate
));
298 xTableFamily
->insertByName(sTemplateName
, Any(xTemplate
));
303 TOOLS_WARN_EXCEPTION("xmloff.table", "XMLTableImport::insertTabletemplate()");
307 void XMLTableImport::finishStyles()
309 if( maTableTemplates
.empty() )
314 Reference
< XStyleFamiliesSupplier
> xFamiliesSupp( mrImport
.GetModel(), UNO_QUERY_THROW
);
315 Reference
< XNameAccess
> xFamilies( xFamiliesSupp
->getStyleFamilies() );
317 Reference
< XNameContainer
> xTableFamily( xFamilies
->getByName( "table" ), UNO_QUERY_THROW
);
318 Reference
< XNameAccess
> xCellFamily( xFamilies
->getByName( "cell" ), UNO_QUERY_THROW
);
320 Reference
< XSingleServiceFactory
> xFactory( xTableFamily
, UNO_QUERY_THROW
);
322 for( const auto& rTemplate
: maTableTemplates
) try
324 const OUString
sTemplateName( rTemplate
.first
);
325 Reference
< XNameReplace
> xTemplate( xFactory
->createInstance(), UNO_QUERY_THROW
);
327 std::shared_ptr
< XMLTableTemplate
> xT( rTemplate
.second
);
329 for( const auto& rStyle
: *xT
) try
331 const OUString
sPropName( rStyle
.first
);
332 const OUString
sStyleName( rStyle
.second
);
333 xTemplate
->replaceByName( sPropName
, xCellFamily
->getByName( sStyleName
) );
337 TOOLS_WARN_EXCEPTION("xmloff.table", "");
342 if( xTableFamily
->hasByName( sTemplateName
) )
343 xTableFamily
->replaceByName( sTemplateName
, Any( xTemplate
) );
345 xTableFamily
->insertByName( sTemplateName
, Any( xTemplate
) );
351 TOOLS_WARN_EXCEPTION("xmloff.table", "");
356 TOOLS_WARN_EXCEPTION("xmloff.table", "");
361 XMLTableImportContext::XMLTableImportContext( const rtl::Reference
< XMLTableImport
>& xImporter
, Reference
< XColumnRowRange
> const & xColumnRowRange
)
362 : SvXMLImportContext( xImporter
->mrImport
)
363 , mxTable( xColumnRowRange
, UNO_QUERY
)
364 , mxColumns( xColumnRowRange
->getColumns() )
365 , mxRows( xColumnRowRange
->getRows() )
367 , mnCurrentColumn( -1 )
371 SvXMLImportContextRef
XMLTableImportContext::ImportColumn( const Reference
< XAttributeList
>& xAttrList
)
373 if( mxColumns
.is() && (mnCurrentRow
== -1) ) try
375 auto xInfo
= std::make_shared
<ColumnInfo
>();
377 sal_Int32 nRepeated
= 1;
379 // read attributes for the table-column
380 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
381 for(sal_Int16 i
=0; i
< nAttrCount
; i
++)
383 const OUString
sAttrName( xAttrList
->getNameByIndex( i
) );
384 const OUString
sValue( xAttrList
->getValueByIndex( i
) );
387 sal_uInt16 nPrefix2
= GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName
, &aLocalName
);
388 if( XML_NAMESPACE_TABLE
== nPrefix2
)
390 if( IsXMLToken( aLocalName
, XML_NUMBER_COLUMNS_REPEATED
) )
392 nRepeated
= sValue
.toInt32();
394 else if( IsXMLToken( aLocalName
, XML_STYLE_NAME
) )
396 xInfo
->msStyleName
= sValue
;
398 else if( IsXMLToken( aLocalName
, XML_DEFAULT_CELL_STYLE_NAME
) )
400 xInfo
->msDefaultCellStyleName
= sValue
;
403 else if ( (XML_NAMESPACE_XML
== nPrefix2
) &&
404 IsXMLToken(aLocalName
, XML_ID
) )
412 maColumnInfos
.push_back( xInfo
);
416 maColumnInfos
.insert( maColumnInfos
.end(), nRepeated
, xInfo
);
421 TOOLS_WARN_EXCEPTION("xmloff.table", "");
427 void XMLTableImportContext::InitColumns()
429 if( !mxColumns
.is() )
434 const sal_Int32 nCount1
= mxColumns
->getCount();
435 const sal_Int32 nCount2
= sal::static_int_cast
< sal_Int32
>( maColumnInfos
.size() );
436 if( nCount1
< nCount2
)
437 mxColumns
->insertByIndex( nCount1
, nCount2
- nCount1
);
439 SvXMLStylesContext
* pAutoStyles
= GetImport().GetShapeImport()->GetAutoStylesContext();
441 for( sal_Int32 nCol
= 0; nCol
< nCount2
; nCol
++ )
443 std::shared_ptr
< ColumnInfo
> xInfo( maColumnInfos
[nCol
] );
445 if( pAutoStyles
&& !xInfo
->msStyleName
.isEmpty() )
447 const XMLPropStyleContext
* pStyle
=
448 dynamic_cast< const XMLPropStyleContext
* >(
449 pAutoStyles
->FindStyleChildContext(XmlStyleFamily::TABLE_COLUMN
, xInfo
->msStyleName
) );
453 Reference
< XPropertySet
> xColProps( mxColumns
->getByIndex(nCol
), UNO_QUERY_THROW
);
454 const_cast< XMLPropStyleContext
* >( pStyle
)->FillPropertySet( xColProps
);
462 TOOLS_WARN_EXCEPTION("xmloff.table", "");
466 SvXMLImportContext
* XMLTableImportContext::ImportRow( sal_uInt16 nPrefix
, const OUString
& rLocalName
, const Reference
< XAttributeList
>& xAttrList
)
471 if( mnCurrentRow
== 0 )
472 InitColumns(); // first init columns
474 mnCurrentColumn
= -1;
476 const sal_Int32 nRowCount
= mxRows
->getCount();
477 if( ( nRowCount
- 1) < mnCurrentRow
)
479 const sal_Int32 nCount
= mnCurrentRow
- nRowCount
+ 1;
480 mxRows
->insertByIndex( nRowCount
, nCount
);
483 Reference
< XPropertySet
> xRowSet( mxRows
->getByIndex(mnCurrentRow
), UNO_QUERY
);
487 // read attributes for the table-row
488 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
489 for(sal_Int16 i
=0; i
< nAttrCount
; i
++)
491 const OUString
sAttrName( xAttrList
->getNameByIndex( i
) );
492 const OUString
sValue( xAttrList
->getValueByIndex( i
) );
495 sal_uInt16 nPrefix2
= GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName
, &aLocalName
);
496 if( nPrefix2
== XML_NAMESPACE_TABLE
)
498 if( IsXMLToken( aLocalName
, XML_STYLE_NAME
) )
502 else if( IsXMLToken( aLocalName
, XML_DEFAULT_CELL_STYLE_NAME
) )
504 msDefaultCellStyleName
= sValue
;
507 else if ( (XML_NAMESPACE_XML
== nPrefix2
) &&
508 IsXMLToken(aLocalName
, XML_ID
) )
515 if( !sStyleName
.isEmpty() )
517 SvXMLStylesContext
* pAutoStyles
= GetImport().GetShapeImport()->GetAutoStylesContext();
520 const XMLPropStyleContext
* pStyle
=
521 dynamic_cast< const XMLPropStyleContext
* >(
522 pAutoStyles
->FindStyleChildContext(XmlStyleFamily::TABLE_ROW
, sStyleName
) );
526 const_cast< XMLPropStyleContext
* >( pStyle
)->FillPropertySet( xRowSet
);
532 SvXMLImportContextRef
xThis( this );
533 return new XMLProxyContext( GetImport(), xThis
, nPrefix
, rLocalName
);
536 SvXMLImportContextRef
XMLTableImportContext::ImportCell( sal_uInt16 nPrefix
, const OUString
& rLocalName
, const Reference
< XAttributeList
>& xAttrList
)
539 if( mxColumns
.is() ) try
541 if( mxColumns
->getCount() <= mnCurrentColumn
)
542 mxColumns
->insertByIndex( mxColumns
->getCount(), mnCurrentColumn
- mxColumns
->getCount() + 1 );
544 Reference
< XMergeableCell
> xCell( mxTable
->getCellByPosition( mnCurrentColumn
, mnCurrentRow
), UNO_QUERY_THROW
);
545 XMLCellImportContext
* pCellContext
= new XMLCellImportContext( GetImport(), xCell
, GetDefaultCellStyleName(), nPrefix
, rLocalName
, xAttrList
);
547 const sal_Int32 nColumnSpan
= pCellContext
->getColumnSpan();
548 const sal_Int32 nRowSpan
= pCellContext
->getRowSpan();
549 if( (nColumnSpan
> 1) || (nRowSpan
> 1) )
550 maMergeInfos
.push_back( std::make_shared
< MergeInfo
>( mnCurrentColumn
, mnCurrentRow
, nColumnSpan
, nRowSpan
) );
552 const sal_Int32 nRepeated
= pCellContext
->getRepeated();
555 OSL_FAIL("xmloff::XMLTableImportContext::ImportCell(), import of repeated Cells not implemented (TODO)");
556 mnCurrentColumn
+= nRepeated
- 1;
563 TOOLS_WARN_EXCEPTION("xmloff.table", "");
569 SvXMLImportContextRef
XMLTableImportContext::CreateChildContext( sal_uInt16 nPrefix
, const OUString
& rLocalName
, const Reference
< XAttributeList
>& xAttrList
)
571 if( nPrefix
== XML_NAMESPACE_TABLE
)
573 if( IsXMLToken( rLocalName
, XML_TABLE_COLUMN
) )
574 return ImportColumn( xAttrList
);
575 else if( IsXMLToken( rLocalName
, XML_TABLE_ROW
) )
576 return ImportRow( nPrefix
, rLocalName
, xAttrList
);
577 else if( IsXMLToken( rLocalName
, XML_TABLE_CELL
) || IsXMLToken( rLocalName
, XML_COVERED_TABLE_CELL
) )
578 return ImportCell( nPrefix
, rLocalName
, xAttrList
);
579 else if( IsXMLToken( rLocalName
, XML_TABLE_COLUMNS
) || IsXMLToken( rLocalName
, XML_TABLE_ROWS
) )
581 SvXMLImportContextRef
xThis( this );
582 return new XMLProxyContext( GetImport(), xThis
, nPrefix
, rLocalName
);
589 void XMLTableImportContext::endFastElement(sal_Int32
)
591 for( const std::shared_ptr
< MergeInfo
>& xInfo
: maMergeInfos
)
595 Reference
< XCellRange
> xRange( mxTable
->getCellRangeByPosition( xInfo
->mnStartColumn
, xInfo
->mnStartRow
, xInfo
->mnEndColumn
, xInfo
->mnEndRow
) );
596 Reference
< XMergeableCellRange
> xCursor( mxTable
->createCursorByRange( xRange
), UNO_QUERY_THROW
);
601 TOOLS_WARN_EXCEPTION("xmloff.table", "");
606 OUString
XMLTableImportContext::GetDefaultCellStyleName() const
608 OUString
sStyleName( msDefaultCellStyleName
);
610 // if there is still no style name, try default style name from column
611 if( (sStyleName
.isEmpty()) && (mnCurrentColumn
< sal::static_int_cast
<sal_Int32
>(maColumnInfos
.size())) )
612 sStyleName
= maColumnInfos
[mnCurrentColumn
]->msDefaultCellStyleName
;
617 // XMLCellImportContext
619 XMLCellImportContext::XMLCellImportContext( SvXMLImport
& rImport
, const Reference
< XMergeableCell
>& xCell
, const OUString
& sDefaultCellStyleName
, sal_uInt16 nPrfx
, const OUString
& rLName
, const css::uno::Reference
< css::xml::sax::XAttributeList
>& xAttrList
)
620 : SvXMLImportContext( rImport
, nPrfx
, rLName
)
622 , mbListContextPushed( false )
629 // read attributes for the table-cell
630 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
631 for(sal_Int16 i
=0; i
< nAttrCount
; i
++)
633 const OUString
sAttrName( xAttrList
->getNameByIndex( i
) );
634 const OUString
sValue( xAttrList
->getValueByIndex( i
) );
637 sal_uInt16 nPrefix2
= GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName
, &aLocalName
);
638 if( XML_NAMESPACE_TABLE
== nPrefix2
)
640 if( IsXMLToken( aLocalName
, XML_NUMBER_COLUMNS_REPEATED
) )
642 mnRepeated
= sValue
.toInt32();
644 else if( IsXMLToken( aLocalName
, XML_NUMBER_COLUMNS_SPANNED
) )
646 mnColSpan
= sValue
.toInt32();
648 else if( IsXMLToken( aLocalName
, XML_NUMBER_ROWS_SPANNED
) )
650 mnRowSpan
= sValue
.toInt32();
652 else if( IsXMLToken( aLocalName
, XML_STYLE_NAME
) )
657 else if ( (XML_NAMESPACE_XML
== nPrefix2
) &&
658 IsXMLToken(aLocalName
, XML_ID
) )
662 //FIXME: RDFa (table:table-cell)
665 // if there is no style name at the cell, try default style name from row
666 if( sStyleName
.isEmpty() )
667 sStyleName
= sDefaultCellStyleName
;
669 if( sStyleName
.isEmpty() )
672 SvXMLStylesContext
* pAutoStyles
= GetImport().GetShapeImport()->GetAutoStylesContext();
676 const XMLPropStyleContext
* pStyle
=
677 dynamic_cast< const XMLPropStyleContext
* >(
678 pAutoStyles
->FindStyleChildContext(XmlStyleFamily::TABLE_CELL
, sStyleName
) );
682 Reference
< XPropertySet
> xCellSet( mxCell
, UNO_QUERY
);
684 const_cast< XMLPropStyleContext
* >( pStyle
)->FillPropertySet( xCellSet
);
688 SvXMLImportContextRef
XMLCellImportContext::CreateChildContext( sal_uInt16 nPrefix
, const OUString
& rLocalName
, const Reference
< XAttributeList
>& xAttrList
)
690 // create text cursor on demand
693 Reference
< XText
> xText( mxCell
, UNO_QUERY
);
696 rtl::Reference
< XMLTextImportHelper
> xTxtImport( GetImport().GetTextImport() );
697 mxOldCursor
= xTxtImport
->GetCursor();
698 mxCursor
= xText
->createTextCursor();
700 xTxtImport
->SetCursor( mxCursor
);
702 // remember old list item and block (#91964#) and reset them
703 // for the text frame
704 xTxtImport
->PushListContext();
705 mbListContextPushed
= true;
709 SvXMLImportContext
* pContext
= nullptr;
711 // if we have a text cursor, lets try to import some text
714 pContext
= GetImport().GetTextImport()->CreateTextChildContext( GetImport(), nPrefix
, rLocalName
, xAttrList
);
720 void XMLCellImportContext::endFastElement(sal_Int32
)
724 // delete addition newline
725 mxCursor
->gotoEnd( false );
726 mxCursor
->goLeft( 1, true );
727 mxCursor
->setString( "" );
730 GetImport().GetTextImport()->ResetCursor();
734 GetImport().GetTextImport()->SetCursor( mxOldCursor
);
736 // reinstall old list item (if necessary) #91964#
737 if (mbListContextPushed
) {
738 GetImport().GetTextImport()->PopListContext();
743 XMLTableTemplateContext::XMLTableTemplateContext( SvXMLImport
& rImport
)
744 : SvXMLStyleContext( rImport
, XmlStyleFamily::TABLE_TEMPLATE_ID
, false )
748 void XMLTableTemplateContext::SetAttribute( sal_uInt16 nPrefixKey
,
749 const OUString
& rLocalName
,
750 const OUString
& rValue
)
752 if( (nPrefixKey
== XML_NAMESPACE_TEXT
&& IsXMLToken( rLocalName
, XML_STYLE_NAME
))
753 // Writer specific: according to oasis odf 1.2 prefix should be "table" and element name should be "name"
754 || (nPrefixKey
== XML_NAMESPACE_TABLE
&& IsXMLToken( rLocalName
, XML_NAME
)))
756 msTemplateStyleName
= rValue
;
760 void XMLTableTemplateContext::endFastElement(sal_Int32
)
762 rtl::Reference
< XMLTableImport
> xTableImport( GetImport().GetShapeImport()->GetShapeTableImport() );
763 if( xTableImport
.is() )
764 xTableImport
->addTableTemplate( msTemplateStyleName
, maTableTemplate
);
767 void XMLTableTemplateContext::CreateAndInsert(bool bOverwrite
)
769 rtl::Reference
<XMLTableImport
> xTableImport(GetImport().GetShapeImport()->GetShapeTableImport());
770 if(xTableImport
.is())
771 xTableImport
->insertTabletemplate(msTemplateStyleName
, bOverwrite
);
774 css::uno::Reference
< css::xml::sax::XFastContextHandler
> XMLTableTemplateContext::createFastChildContext(
776 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
778 if( IsTokenInNamespace(nElement
, XML_NAMESPACE_TABLE
) )
780 const TableStyleElement
* pElements
= getTableStyleMap();
781 sal_Int32 nLocalName
= nElement
& TOKEN_MASK
;
782 while( (pElements
->meElement
!= XML_TOKEN_END
) && pElements
->meElement
!= nLocalName
)
785 if( pElements
->meElement
!= XML_TOKEN_END
)
787 for (auto &aIter
: sax_fastparser::castToFastAttributeList( xAttrList
))
789 switch (aIter
.getToken())
791 case XML_ELEMENT(TEXT
, XML_STYLE_NAME
):
792 case XML_ELEMENT(TABLE
, XML_STYLE_NAME
):
793 maTableTemplate
[pElements
->msStyleName
] = aIter
.toString();
796 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
800 } else if (IsTokenInNamespace(nElement
, XML_NAMESPACE_LO_EXT
)) // Writer specific cell styles
802 const TableStyleElement
* pElements
= getWriterSpecificTableStyleMap();
803 sal_Int32 nLocalName
= nElement
& TOKEN_MASK
;
804 while( (pElements
->meElement
!= XML_TOKEN_END
) && pElements
->meElement
!= nLocalName
)
807 if (pElements
->meElement
!= XML_TOKEN_END
)
809 for (auto &aIter
: sax_fastparser::castToFastAttributeList( xAttrList
))
811 switch (aIter
.getToken())
813 case XML_ELEMENT(TEXT
, XML_STYLE_NAME
):
814 case XML_ELEMENT(TABLE
, XML_STYLE_NAME
):
815 maTableTemplate
[pElements
->msStyleName
] = aIter
.toString();
818 XMLOFF_WARN_UNKNOWN("xmloff", aIter
);
827 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */