Bump version to 6.4.0.12
[LibreOffice.git] / xmloff / source / table / XMLTableImport.cxx
blobddaae9f5e484f2ab9023efb26cb0592e13626e85
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <com/sun/star/style/XStyleFamiliesSupplier.hpp>
21 #include <com/sun/star/table/XTableRows.hpp>
22 #include <com/sun/star/table/XMergeableCell.hpp>
23 #include <com/sun/star/table/XMergeableCellRange.hpp>
24 #include <com/sun/star/table/XTable.hpp>
25 #include <com/sun/star/text/XText.hpp>
26 #include <com/sun/star/container/XNameContainer.hpp>
27 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
28 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
29 #include <com/sun/star/style/XStyle.hpp>
30 #include <comphelper/sequence.hxx>
31 #include <tools/diagnose_ex.h>
33 #include <xmloff/table/XMLTableImport.hxx>
34 #include <xmloff/xmlprmap.hxx>
35 #include <xmloff/txtimp.hxx>
36 #include <xmloff/xmlimp.hxx>
37 #include <xmloff/nmspmap.hxx>
38 #include <xmloff/xmlstyle.hxx>
39 #include <xmloff/prstylei.hxx>
41 #include <xmloff/xmlnmspe.hxx>
42 #include <xmloff/xmluconv.hxx>
43 #include "table.hxx"
45 #include <osl/diagnose.h>
46 #include <sal/log.hxx>
48 #include <memory>
50 using namespace ::xmloff::token;
51 using namespace ::com::sun::star::beans;
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::table;
54 using namespace ::com::sun::star::xml::sax;
55 using namespace ::com::sun::star::text;
56 using namespace ::com::sun::star::style;
57 using namespace ::com::sun::star::lang;
58 using namespace ::com::sun::star::container;
60 namespace {
62 struct ColumnInfo
64 OUString msStyleName;
65 OUString msDefaultCellStyleName;
70 class XMLProxyContext : public SvXMLImportContext
72 public:
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;
77 private:
78 SvXMLImportContextRef mxParent;
81 struct MergeInfo
83 sal_Int32 const mnStartColumn;
84 sal_Int32 const mnStartRow;
85 sal_Int32 const mnEndColumn;
86 sal_Int32 const mnEndRow;
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 ) {};
92 typedef std::vector< std::shared_ptr< MergeInfo > > MergeInfoVector;
94 class XMLTableImportContext : public SvXMLImportContext
96 public:
97 XMLTableImportContext( const rtl::Reference< XMLTableImport >& xThis, sal_uInt16 nPrfx, const OUString& rLName, Reference< XColumnRowRange > const & xColumnRowRange );
99 virtual SvXMLImportContextRef CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList ) override;
101 virtual void StartElement( const Reference< XAttributeList >& xAttrList ) override;
103 virtual void EndElement() override;
105 void InitColumns();
107 SvXMLImportContextRef ImportColumn( sal_uInt16 nPrefix, const OUString& rLocalName, 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;
127 class XMLCellImportContext : public SvXMLImportContext
129 public:
130 XMLCellImportContext( SvXMLImport& rImport,
131 const Reference< XMergeableCell >& xCell,
132 const OUString& sDefaultCellStyleName,
133 sal_uInt16 nPrfx, const OUString& rLName,
134 const css::uno::Reference< css::xml::sax::XAttributeList >& xAttrList );
136 virtual SvXMLImportContextRef CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList ) override;
138 virtual void EndElement() override;
140 sal_Int32 getColumnSpan() const { return mnColSpan; }
141 sal_Int32 getRowSpan() const { return mnRowSpan; }
142 sal_Int32 getRepeated() const { return mnRepeated; }
144 Reference< XMergeableCell > mxCell;
145 Reference< XTextCursor > mxCursor;
146 Reference< XTextCursor > mxOldCursor;
147 bool mbListContextPushed;
149 sal_Int32 mnColSpan, mnRowSpan, mnRepeated;
152 class XMLTableTemplateContext : public SvXMLStyleContext
154 public:
155 XMLTableTemplateContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName, const Reference< XAttributeList >& xAttrList );
157 virtual SvXMLImportContextRef CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList ) override;
159 virtual void StartElement( const Reference< XAttributeList >& xAttrList ) override;
161 virtual void EndElement() override;
163 virtual void CreateAndInsert( bool bOverwrite ) override;
164 private:
165 XMLTableTemplate maTableTemplate;
166 OUString msTemplateStyleName;
169 // class XMLProxyContext
171 XMLProxyContext::XMLProxyContext( SvXMLImport& rImport, const SvXMLImportContextRef& xParent, sal_uInt16 nPrfx, const OUString& rLName )
172 : SvXMLImportContext( rImport, nPrfx, rLName )
173 , mxParent( xParent )
177 SvXMLImportContextRef XMLProxyContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
179 if( mxParent.is() )
180 return mxParent->CreateChildContext( nPrefix, rLocalName, xAttrList );
181 else
182 return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
185 // class XMLTableImport
187 XMLTableImport::XMLTableImport( SvXMLImport& rImport, const rtl::Reference< XMLPropertySetMapper >& xCellPropertySetMapper, const rtl::Reference< XMLPropertyHandlerFactory >& xFactoryRef )
188 : mrImport( rImport )
190 bool bWriter = false;
191 // check if called by Writer
192 Reference<XMultiServiceFactory> xFac(rImport.GetModel(), UNO_QUERY);
193 if (xFac.is()) try
195 Sequence<OUString> sSNS = xFac->getAvailableServiceNames();
196 bWriter = comphelper::findValue(sSNS, "com.sun.star.style.TableStyle") != -1;
198 catch(const Exception&)
200 SAL_WARN("xmloff.table", "Error while checking available service names");
203 if (bWriter)
205 mxCellImportPropertySetMapper = XMLTextImportHelper::CreateTableCellExtPropMapper(rImport);
207 else
209 mxCellImportPropertySetMapper = new SvXMLImportPropertyMapper( xCellPropertySetMapper.get(), rImport );
210 mxCellImportPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(rImport));
211 mxCellImportPropertySetMapper->ChainImportMapper(new SvXMLImportPropertyMapper(new XMLPropertySetMapper(getCellPropertiesMap(), xFactoryRef.get(), true), rImport));
214 rtl::Reference < XMLPropertySetMapper > xRowMapper( new XMLPropertySetMapper( getRowPropertiesMap(), xFactoryRef.get(), false ) );
215 mxRowImportPropertySetMapper = new SvXMLImportPropertyMapper( xRowMapper, rImport );
217 rtl::Reference < XMLPropertySetMapper > xColMapper( new XMLPropertySetMapper( getColumnPropertiesMap(), xFactoryRef.get(), false ) );
218 mxColumnImportPropertySetMapper = new SvXMLImportPropertyMapper( xColMapper, rImport );
221 XMLTableImport::~XMLTableImport()
225 SvXMLImportContext* XMLTableImport::CreateTableContext( sal_uInt16 nPrfx, const OUString& rLName, Reference< XColumnRowRange > const & xColumnRowRange )
227 rtl::Reference< XMLTableImport > xThis( this );
228 return new XMLTableImportContext( xThis, nPrfx, rLName, xColumnRowRange );
231 SvXMLStyleContext* XMLTableImport::CreateTableTemplateContext( sal_uInt16 nPrfx, const OUString& rLName, const Reference< XAttributeList >& xAttrList )
233 return new XMLTableTemplateContext( mrImport, nPrfx, rLName, xAttrList );
236 void XMLTableImport::addTableTemplate( const OUString& rsStyleName, XMLTableTemplate& xTableTemplate )
238 std::shared_ptr< XMLTableTemplate > xPtr( new XMLTableTemplate );
239 xPtr->swap( xTableTemplate );
240 maTableTemplates[rsStyleName] = xPtr;
243 void XMLTableImport::insertTabletemplate(const OUString& rsStyleName, bool bOverwrite)
245 XMLTableTemplateMap::iterator it = maTableTemplates.find(rsStyleName);
246 if (it == maTableTemplates.end())
247 return;
251 Reference<XStyleFamiliesSupplier> xFamiliesSupp(mrImport.GetModel(), UNO_QUERY_THROW);
252 Reference<XNameAccess> xFamilies(xFamiliesSupp->getStyleFamilies());
253 const OUString sFamilyName("TableStyles");
254 const OUString sCellFamilyName("CellStyles");
256 Reference<XNameContainer> xTableFamily(xFamilies->getByName(sFamilyName), UNO_QUERY_THROW);
257 Reference<XIndexAccess> xCellFamily(xFamilies->getByName(sCellFamilyName), UNO_QUERY_THROW);
259 const OUString sTemplateName(it->first);
260 Reference<XMultiServiceFactory> xFactory(mrImport.GetModel(), UNO_QUERY_THROW);
261 Reference<XNameReplace> xTemplate(xFactory->createInstance("com.sun.star.style.TableStyle"), UNO_QUERY_THROW);
263 std::shared_ptr<XMLTableTemplate> xT(it->second);
265 for (const auto& rStyle : *xT) try
267 const OUString sPropName(rStyle.first);
268 const OUString sStyleName(rStyle.second);
269 // Internally unassigned cell styles are stored by display name.
270 // However table-template elements reference cell styles by its encoded name.
271 // This loop is looking for cell style by their encoded names.
272 sal_Int32 nCount = xCellFamily->getCount();
273 for (sal_Int32 i=0; i < nCount; ++i)
275 Any xCellStyle = xCellFamily->getByIndex(i);
276 OUString sEncodedStyleName = mrImport.GetMM100UnitConverter().encodeStyleName(
277 xCellStyle.get<Reference<XStyle>>()->getName());
278 if (sEncodedStyleName == sStyleName)
280 xTemplate->replaceByName(sPropName, xCellStyle);
281 break;
285 catch (Exception const &)
287 TOOLS_WARN_EXCEPTION("xmloff.table", "XMLTableImport::insertTabletemplate()");
290 if (xTemplate.is())
292 if (xTableFamily->hasByName(sTemplateName) && bOverwrite)
293 xTableFamily->replaceByName(sTemplateName, Any(xTemplate));
294 else
295 xTableFamily->insertByName(sTemplateName, Any(xTemplate));
298 catch (Exception&)
300 TOOLS_WARN_EXCEPTION("xmloff.table", "XMLTableImport::insertTabletemplate()");
304 void XMLTableImport::finishStyles()
306 if( !maTableTemplates.empty() ) try
308 Reference< XStyleFamiliesSupplier > xFamiliesSupp( mrImport.GetModel(), UNO_QUERY_THROW );
309 Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
310 const OUString sFamilyName( "table" );
311 const OUString sCellFamilyName( "cell" );
313 Reference< XNameContainer > xTableFamily( xFamilies->getByName( sFamilyName ), UNO_QUERY_THROW );
314 Reference< XNameAccess > xCellFamily( xFamilies->getByName( sCellFamilyName ), UNO_QUERY_THROW );
316 Reference< XSingleServiceFactory > xFactory( xTableFamily, UNO_QUERY_THROW );
318 for( const auto& rTemplate : maTableTemplates ) try
320 const OUString sTemplateName( rTemplate.first );
321 Reference< XNameReplace > xTemplate( xFactory->createInstance(), UNO_QUERY_THROW );
323 std::shared_ptr< XMLTableTemplate > xT( rTemplate.second );
325 for( const auto& rStyle : *xT ) try
327 const OUString sPropName( rStyle.first );
328 const OUString sStyleName( rStyle.second );
329 xTemplate->replaceByName( sPropName, xCellFamily->getByName( sStyleName ) );
331 catch( Exception& )
333 OSL_FAIL("xmloff::XMLTableImport::finishStyles(), exception caught!");
336 if( xTemplate.is() )
338 if( xTableFamily->hasByName( sTemplateName ) )
339 xTableFamily->replaceByName( sTemplateName, Any( xTemplate ) );
340 else
341 xTableFamily->insertByName( sTemplateName, Any( xTemplate ) );
345 catch( Exception& )
347 OSL_FAIL("xmloff::XMLTableImport::finishStyles(), exception caught!");
350 catch( Exception& )
352 OSL_FAIL("xmloff::XMLTableImport::finishStyles(), exception caught!");
356 // class XMLTableImport
358 XMLTableImportContext::XMLTableImportContext( const rtl::Reference< XMLTableImport >& xImporter, sal_uInt16 nPrfx, const OUString& rLName, Reference< XColumnRowRange > const & xColumnRowRange )
359 : SvXMLImportContext( xImporter->mrImport, nPrfx, rLName )
360 , mxTable( xColumnRowRange, UNO_QUERY )
361 , mxColumns( xColumnRowRange->getColumns() )
362 , mxRows( xColumnRowRange->getRows() )
363 , mnCurrentRow( -1 )
364 , mnCurrentColumn( -1 )
368 SvXMLImportContextRef XMLTableImportContext::ImportColumn( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
370 if( mxColumns.is() && (mnCurrentRow == -1) ) try
372 std::shared_ptr< ColumnInfo > xInfo ( new ColumnInfo );
374 sal_Int32 nRepeated = 1;
376 // read attributes for the table-column
377 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
378 for(sal_Int16 i=0; i < nAttrCount; i++)
380 const OUString sAttrName( xAttrList->getNameByIndex( i ) );
381 const OUString sValue( xAttrList->getValueByIndex( i ) );
382 OUString aLocalName;
384 sal_uInt16 nPrefix2 = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
385 if( XML_NAMESPACE_TABLE == nPrefix2 )
387 if( IsXMLToken( aLocalName, XML_NUMBER_COLUMNS_REPEATED ) )
389 nRepeated = sValue.toInt32();
391 else if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
393 xInfo->msStyleName = sValue;
395 else if( IsXMLToken( aLocalName, XML_DEFAULT_CELL_STYLE_NAME ) )
397 xInfo->msDefaultCellStyleName = sValue;
400 else if ( (XML_NAMESPACE_XML == nPrefix2) &&
401 IsXMLToken(aLocalName, XML_ID) )
403 //FIXME: TODO
407 if( nRepeated <= 1 )
409 maColumnInfos.push_back( xInfo );
411 else
413 maColumnInfos.insert( maColumnInfos.end(), nRepeated, xInfo );
416 catch( Exception& )
418 OSL_FAIL("xmloff::XMLTableImportContext::ImportTableColumn(), exception caught!");
421 return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList);
424 void XMLTableImportContext::InitColumns()
426 if( mxColumns.is() ) try
428 const sal_Int32 nCount1 = mxColumns->getCount();
429 const sal_Int32 nCount2 = sal::static_int_cast< sal_Int32 >( maColumnInfos.size() );
430 if( nCount1 < nCount2 )
431 mxColumns->insertByIndex( nCount1, nCount2 - nCount1 );
433 SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
435 for( sal_Int32 nCol = 0; nCol < nCount2; nCol++ )
437 std::shared_ptr< ColumnInfo > xInfo( maColumnInfos[nCol] );
439 if( pAutoStyles && !xInfo->msStyleName.isEmpty() )
441 const XMLPropStyleContext* pStyle =
442 dynamic_cast< const XMLPropStyleContext* >(
443 pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_TABLE_COLUMN, xInfo->msStyleName) );
445 if( pStyle )
447 Reference< XPropertySet > xColProps( mxColumns->getByIndex(nCol), UNO_QUERY_THROW );
448 const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xColProps );
454 catch( Exception& )
456 OSL_FAIL("xmloff::XMLTableImportContext::ImportTableColumn(), exception caught!");
460 SvXMLImportContext * XMLTableImportContext::ImportRow( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
462 if( mxRows.is() )
464 mnCurrentRow++;
465 if( mnCurrentRow == 0 )
466 InitColumns(); // first init columns
468 mnCurrentColumn = -1;
470 const sal_Int32 nRowCount = mxRows->getCount();
471 if( ( nRowCount - 1) < mnCurrentRow )
473 const sal_Int32 nCount = mnCurrentRow - nRowCount + 1;
474 mxRows->insertByIndex( nRowCount, nCount );
477 Reference< XPropertySet > xRowSet( mxRows->getByIndex(mnCurrentRow), UNO_QUERY );
479 OUString sStyleName;
481 // read attributes for the table-row
482 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
483 for(sal_Int16 i=0; i < nAttrCount; i++)
485 const OUString sAttrName( xAttrList->getNameByIndex( i ) );
486 const OUString sValue( xAttrList->getValueByIndex( i ) );
487 OUString aLocalName;
489 sal_uInt16 nPrefix2 = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
490 if( nPrefix2 == XML_NAMESPACE_TABLE )
492 if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
494 sStyleName = sValue;
496 else if( IsXMLToken( aLocalName, XML_DEFAULT_CELL_STYLE_NAME ) )
498 msDefaultCellStyleName = sValue;
501 else if ( (XML_NAMESPACE_XML == nPrefix2) &&
502 IsXMLToken(aLocalName, XML_ID) )
504 (void) sValue;
505 //FIXME: TODO
509 if( !sStyleName.isEmpty() )
511 SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
512 if( pAutoStyles )
514 const XMLPropStyleContext* pStyle =
515 dynamic_cast< const XMLPropStyleContext* >(
516 pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_TABLE_ROW, sStyleName) );
518 if( pStyle )
520 const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xRowSet );
526 SvXMLImportContextRef xThis( this );
527 return new XMLProxyContext( GetImport(), xThis, nPrefix, rLocalName );
530 SvXMLImportContextRef XMLTableImportContext::ImportCell( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
532 mnCurrentColumn++;
533 if( mxColumns.is() ) try
535 if( mxColumns->getCount() <= mnCurrentColumn )
536 mxColumns->insertByIndex( mxColumns->getCount(), mnCurrentColumn - mxColumns->getCount() + 1 );
538 Reference< XMergeableCell > xCell( mxTable->getCellByPosition( mnCurrentColumn, mnCurrentRow ), UNO_QUERY_THROW );
539 XMLCellImportContext* pCellContext = new XMLCellImportContext( GetImport(), xCell, GetDefaultCellStyleName(), nPrefix, rLocalName, xAttrList );
541 const sal_Int32 nColumnSpan = pCellContext->getColumnSpan();
542 const sal_Int32 nRowSpan = pCellContext->getRowSpan();
543 if( (nColumnSpan > 1) || (nRowSpan > 1) )
544 maMergeInfos.push_back( std::make_shared< MergeInfo >( mnCurrentColumn, mnCurrentRow, nColumnSpan, nRowSpan ) );
546 const sal_Int32 nRepeated = pCellContext->getRepeated();
547 if( nRepeated > 1 )
549 OSL_FAIL("xmloff::XMLTableImportContext::ImportCell(), import of repeated Cells not implemented (TODO)");
550 mnCurrentColumn += nRepeated - 1;
553 return pCellContext;
555 catch( Exception& )
557 OSL_FAIL("xmloff::XMLTableImportContext::ImportCell(), exception caught!");
560 return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList);
563 SvXMLImportContextRef XMLTableImportContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
565 if( nPrefix == XML_NAMESPACE_TABLE )
567 if( IsXMLToken( rLocalName, XML_TABLE_COLUMN ) )
568 return ImportColumn( nPrefix, rLocalName, xAttrList );
569 else if( IsXMLToken( rLocalName, XML_TABLE_ROW ) )
570 return ImportRow( nPrefix, rLocalName, xAttrList );
571 else if( IsXMLToken( rLocalName, XML_TABLE_CELL ) || IsXMLToken( rLocalName, XML_COVERED_TABLE_CELL ) )
572 return ImportCell( nPrefix, rLocalName, xAttrList );
573 else if( IsXMLToken( rLocalName, XML_TABLE_COLUMNS ) || IsXMLToken( rLocalName, XML_TABLE_ROWS ) )
575 SvXMLImportContextRef xThis( this );
576 return new XMLProxyContext( GetImport(), xThis, nPrefix, rLocalName );
580 return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList);
583 void XMLTableImportContext::StartElement( const Reference< XAttributeList >& /*xAttrList*/ )
587 void XMLTableImportContext::EndElement()
589 for( const std::shared_ptr< MergeInfo >& xInfo : maMergeInfos )
591 if( xInfo.get() ) try
593 Reference< XCellRange > xRange( mxTable->getCellRangeByPosition( xInfo->mnStartColumn, xInfo->mnStartRow, xInfo->mnEndColumn, xInfo->mnEndRow ) );
594 Reference< XMergeableCellRange > xCursor( mxTable->createCursorByRange( xRange ), UNO_QUERY_THROW );
595 xCursor->merge();
597 catch( Exception& )
599 OSL_FAIL("XMLTableImportContext::EndElement(), exception caught while merging cells!");
604 OUString XMLTableImportContext::GetDefaultCellStyleName() const
606 OUString sStyleName( msDefaultCellStyleName );
608 // if there is still no style name, try default style name from column
609 if( (sStyleName.isEmpty()) && (mnCurrentColumn < sal::static_int_cast<sal_Int32>(maColumnInfos.size())) )
610 sStyleName = maColumnInfos[mnCurrentColumn]->msDefaultCellStyleName;
612 return sStyleName;
615 // XMLCellImportContext
617 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 )
618 : SvXMLImportContext( rImport, nPrfx, rLName )
619 , mxCell( xCell )
620 , mbListContextPushed( false )
621 , mnColSpan( 1 )
622 , mnRowSpan( 1 )
623 , mnRepeated( 1 )
625 OUString sStyleName;
627 // read attributes for the table-cell
628 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
629 for(sal_Int16 i=0; i < nAttrCount; i++)
631 const OUString sAttrName( xAttrList->getNameByIndex( i ) );
632 const OUString sValue( xAttrList->getValueByIndex( i ) );
633 OUString aLocalName;
635 sal_uInt16 nPrefix2 = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
636 if( XML_NAMESPACE_TABLE == nPrefix2 )
638 if( IsXMLToken( aLocalName, XML_NUMBER_COLUMNS_REPEATED ) )
640 mnRepeated = sValue.toInt32();
642 else if( IsXMLToken( aLocalName, XML_NUMBER_COLUMNS_SPANNED ) )
644 mnColSpan = sValue.toInt32();
646 else if( IsXMLToken( aLocalName, XML_NUMBER_ROWS_SPANNED ) )
648 mnRowSpan = sValue.toInt32();
650 else if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
652 sStyleName = sValue;
655 else if ( (XML_NAMESPACE_XML == nPrefix2) &&
656 IsXMLToken(aLocalName, XML_ID) )
658 //FIXME: TODO
660 //FIXME: RDFa (table:table-cell)
663 // if there is no style name at the cell, try default style name from row
664 if( sStyleName.isEmpty() )
665 sStyleName = sDefaultCellStyleName;
667 if( !sStyleName.isEmpty() )
669 SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
670 if( pAutoStyles )
672 const XMLPropStyleContext* pStyle =
673 dynamic_cast< const XMLPropStyleContext* >(
674 pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_TABLE_CELL, sStyleName) );
676 if( pStyle )
678 Reference< XPropertySet > xCellSet( mxCell, UNO_QUERY );
679 if( xCellSet.is() )
680 const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xCellSet );
686 SvXMLImportContextRef XMLCellImportContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
688 // create text cursor on demand
689 if( !mxCursor.is() )
691 Reference< XText > xText( mxCell, UNO_QUERY );
692 if( xText.is() )
694 rtl::Reference < XMLTextImportHelper > xTxtImport( GetImport().GetTextImport() );
695 mxOldCursor = xTxtImport->GetCursor();
696 mxCursor = xText->createTextCursor();
697 if( mxCursor.is() )
698 xTxtImport->SetCursor( mxCursor );
700 // remember old list item and block (#91964#) and reset them
701 // for the text frame
702 xTxtImport->PushListContext();
703 mbListContextPushed = true;
707 SvXMLImportContext * pContext = nullptr;
709 // if we have a text cursor, lets try to import some text
710 if( mxCursor.is() )
712 pContext = GetImport().GetTextImport()->CreateTextChildContext( GetImport(), nPrefix, rLocalName, xAttrList );
715 if( pContext )
716 return pContext;
717 else
718 return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList);
721 void XMLCellImportContext::EndElement()
723 if(mxCursor.is())
725 // delete addition newline
726 mxCursor->gotoEnd( false );
727 mxCursor->goLeft( 1, true );
728 mxCursor->setString( "" );
730 // reset cursor
731 GetImport().GetTextImport()->ResetCursor();
734 if(mxOldCursor.is())
735 GetImport().GetTextImport()->SetCursor( mxOldCursor );
737 // reinstall old list item (if necessary) #91964#
738 if (mbListContextPushed) {
739 GetImport().GetTextImport()->PopListContext();
743 // class XMLTableTemplateContext
745 XMLTableTemplateContext::XMLTableTemplateContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName, const Reference< XAttributeList >& xAttrList )
746 : SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList, XML_STYLE_FAMILY_TABLE_TEMPLATE_ID, false )
750 void XMLTableTemplateContext::StartElement( const Reference< XAttributeList >& xAttrList )
752 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
753 for(sal_Int16 i=0; i < nAttrCount; i++)
755 OUString sAttrName;
756 sal_uInt16 nAttrPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( i ), &sAttrName );
757 if( (nAttrPrefix == XML_NAMESPACE_TEXT && IsXMLToken( sAttrName, XML_STYLE_NAME ))
758 // Writer specific: according to oasis odf 1.2 prefix should be "table" and element name should be "name"
759 || (nAttrPrefix == XML_NAMESPACE_TABLE && IsXMLToken( sAttrName, XML_NAME )))
761 msTemplateStyleName = xAttrList->getValueByIndex( i );
762 break;
767 void XMLTableTemplateContext::EndElement()
769 rtl::Reference< XMLTableImport > xTableImport( GetImport().GetShapeImport()->GetShapeTableImport() );
770 if( xTableImport.is() )
771 xTableImport->addTableTemplate( msTemplateStyleName, maTableTemplate );
774 void XMLTableTemplateContext::CreateAndInsert(bool bOverwrite)
776 rtl::Reference<XMLTableImport> xTableImport(GetImport().GetShapeImport()->GetShapeTableImport());
777 if(xTableImport.is())
778 xTableImport->insertTabletemplate(msTemplateStyleName, bOverwrite);
781 SvXMLImportContextRef XMLTableTemplateContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
783 if( nPrefix == XML_NAMESPACE_TABLE )
785 const TableStyleElement* pElements = getTableStyleMap();
786 while( (pElements->meElement != XML_TOKEN_END) && !IsXMLToken( rLocalName, pElements->meElement ) )
787 pElements++;
789 if( pElements->meElement != XML_TOKEN_END )
791 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
792 for(sal_Int16 i=0; i < nAttrCount; i++)
794 OUString sAttrName;
795 sal_uInt16 nAttrPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( i ), &sAttrName );
796 if( (nAttrPrefix == XML_NAMESPACE_TEXT || nAttrPrefix == XML_NAMESPACE_TABLE) &&
797 IsXMLToken( sAttrName, XML_STYLE_NAME ) )
799 maTableTemplate[pElements->msStyleName] = xAttrList->getValueByIndex( i );
800 break;
804 } else if (nPrefix == XML_NAMESPACE_LO_EXT) // Writer specific cell styles
806 const TableStyleElement* pElements = getWriterSpecificTableStyleMap();
807 while ((pElements->meElement != XML_TOKEN_END) && !IsXMLToken(rLocalName, pElements->meElement ))
808 pElements++;
810 if (pElements->meElement != XML_TOKEN_END)
812 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
813 for (sal_Int16 i=0; i < nAttrCount; i++)
815 OUString sAttrName;
816 sal_uInt16 nAttrPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName(xAttrList->getNameByIndex( i ), &sAttrName);
817 if( (nAttrPrefix == XML_NAMESPACE_TEXT || nAttrPrefix == XML_NAMESPACE_TABLE) &&
818 IsXMLToken( sAttrName, XML_STYLE_NAME ) )
820 maTableTemplate[pElements->msStyleName] = xAttrList->getValueByIndex(i);
821 break;
827 return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
830 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */