Factor out and simplify COM-safe wait
[LibreOffice.git] / xmloff / source / table / XMLTableImport.cxx
blobaf7b849989eb542b2a2b11c6e6f6d408f5fe65a3
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 <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 <comphelper/sequence.hxx>
33 #include <comphelper/diagnose_ex.hxx>
35 #include <utility>
36 #include <xmloff/table/XMLTableImport.hxx>
37 #include <xmloff/maptype.hxx>
38 #include <xmloff/xmlprmap.hxx>
39 #include <xmloff/txtimp.hxx>
40 #include <xmloff/xmlimp.hxx>
41 #include <xmloff/namespacemap.hxx>
42 #include <xmloff/xmlstyle.hxx>
43 #include <xmloff/prstylei.hxx>
45 #include <xmloff/xmlnamespace.hxx>
46 #include <xmloff/xmluconv.hxx>
47 #include "table.hxx"
49 #include <sal/log.hxx>
51 #include <memory>
53 using namespace ::xmloff::token;
54 using namespace ::com::sun::star::beans;
55 using namespace ::com::sun::star::uno;
56 using namespace ::com::sun::star::table;
57 using namespace ::com::sun::star::xml::sax;
58 using namespace ::com::sun::star::text;
59 using namespace ::com::sun::star::style;
60 using namespace ::com::sun::star::lang;
61 using namespace ::com::sun::star::container;
63 namespace {
65 struct ColumnInfo
67 OUString msStyleName;
68 OUString msDefaultCellStyleName;
71 class XMLProxyContext : public SvXMLImportContext
73 public:
74 XMLProxyContext( SvXMLImport& rImport, SvXMLImportContextRef xParent );
76 virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
77 sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
79 private:
80 SvXMLImportContextRef mxParent;
83 struct MergeInfo
85 sal_Int32 mnStartColumn;
86 sal_Int32 mnStartRow;
87 sal_Int32 mnEndColumn;
88 sal_Int32 mnEndRow;
90 MergeInfo( sal_Int32 nStartColumn, sal_Int32 nStartRow, sal_Int32 nColumnSpan, sal_Int32 nRowSpan )
91 : mnStartColumn( nStartColumn ), mnStartRow( nStartRow ), mnEndColumn( nStartColumn + nColumnSpan - 1 ), mnEndRow( nStartRow + nRowSpan - 1 ) {};
94 class XMLCellImportPropertyMapper : public SvXMLImportPropertyMapper
96 public:
97 using SvXMLImportPropertyMapper::SvXMLImportPropertyMapper;
99 bool handleSpecialItem(
100 XMLPropertyState& rProperty,
101 std::vector< XMLPropertyState >& rProperties,
102 const OUString& rValue,
103 const SvXMLUnitConverter& rUnitConverter,
104 const SvXMLNamespaceMap& /*rNamespaceMap*/) const override
106 assert(getPropertySetMapper()->GetEntryXMLName(rProperty.mnIndex) == GetXMLToken(XML_BACKGROUND_COLOR));
107 (void)rProperty;
109 auto nIndex = getPropertySetMapper()->GetEntryIndex(XML_NAMESPACE_DRAW, GetXMLToken(XML_FILL), 0);
110 XMLPropertyState aFillProperty(nIndex);
112 if (IsXMLToken(rValue, XML_TRANSPARENT))
114 getPropertySetMapper()->importXML(GetXMLToken(XML_NONE), aFillProperty, rUnitConverter);
115 rProperties.push_back(aFillProperty);
117 else
119 getPropertySetMapper()->importXML(GetXMLToken(XML_SOLID), aFillProperty, rUnitConverter);
120 rProperties.push_back(aFillProperty);
122 nIndex = getPropertySetMapper()->GetEntryIndex(XML_NAMESPACE_DRAW, GetXMLToken(XML_FILL_COLOR), 0);
123 XMLPropertyState aColorProperty(nIndex);
124 getPropertySetMapper()->importXML(rValue, aColorProperty, rUnitConverter);
125 rProperties.push_back(aColorProperty);
128 return false;
134 class XMLTableImportContext : public SvXMLImportContext
136 public:
137 XMLTableImportContext( const rtl::Reference< XMLTableImport >& xThis, Reference< XColumnRowRange > const & xColumnRowRange );
139 virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
140 sal_Int32 nElement,
141 const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
143 virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
145 void InitColumns();
147 SvXMLImportContextRef ImportColumn( const Reference< XFastAttributeList >& xAttrList );
148 SvXMLImportContext * ImportRow( const Reference< XFastAttributeList >& xAttrList );
149 SvXMLImportContextRef ImportCell( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttrList );
151 OUString GetDefaultCellStyleName() const;
153 css::uno::Reference< css::table::XTable > mxTable;
154 Reference< XTableColumns > mxColumns;
155 Reference< XTableRows > mxRows;
157 std::vector< std::shared_ptr< ColumnInfo > > maColumnInfos;
158 sal_Int32 mnCurrentRow;
159 sal_Int32 mnCurrentColumn;
161 // default cell style name for the current row
162 OUString msDefaultCellStyleName;
164 std::vector< std::shared_ptr< MergeInfo > > maMergeInfos;
167 namespace {
169 class XMLCellImportContext : public SvXMLImportContext
171 public:
172 XMLCellImportContext( SvXMLImport& rImport,
173 const Reference< XMergeableCell >& xCell,
174 const OUString& sDefaultCellStyleName,
175 sal_Int32 nElement,
176 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList );
178 virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
179 sal_Int32 nElement,
180 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
182 virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
184 sal_Int32 getColumnSpan() const { return mnColSpan; }
185 sal_Int32 getRowSpan() const { return mnRowSpan; }
186 sal_Int32 getRepeated() const { return mnRepeated; }
188 Reference< XMergeableCell > mxCell;
189 Reference< XTextCursor > mxCursor;
190 Reference< XTextCursor > mxOldCursor;
191 bool mbListContextPushed;
193 sal_Int32 mnColSpan, mnRowSpan, mnRepeated;
196 class XMLTableTemplateContext : public SvXMLStyleContext
198 public:
199 XMLTableTemplateContext( SvXMLImport& rImport );
201 // Create child element.
202 virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
203 sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
205 virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
207 protected:
208 virtual void SetAttribute( sal_Int32 nElement,
209 const OUString& rValue ) override;
210 private:
211 XMLTableTemplate maTableTemplate;
212 OUString msTemplateStyleName;
218 XMLProxyContext::XMLProxyContext( SvXMLImport& rImport, SvXMLImportContextRef xParent )
219 : SvXMLImportContext( rImport )
220 , mxParent(std::move( xParent ))
224 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLProxyContext::createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttrList )
226 if( mxParent.is() )
227 return mxParent->createFastChildContext( nElement, xAttrList );
228 return nullptr;
232 XMLTableImport::XMLTableImport( SvXMLImport& rImport, const rtl::Reference< XMLPropertySetMapper >& xCellPropertySetMapper, const rtl::Reference< XMLPropertyHandlerFactory >& xFactoryRef )
233 : mrImport( rImport )
234 , mbWriter( false )
236 // check if called by Writer
237 Reference<XMultiServiceFactory> xFac(rImport.GetModel(), UNO_QUERY);
238 if (xFac.is()) try
240 Sequence<OUString> sSNS = xFac->getAvailableServiceNames();
241 mbWriter = comphelper::findValue(sSNS, "com.sun.star.style.TableStyle") != -1;
243 catch(const Exception&)
245 SAL_WARN("xmloff.table", "Error while checking available service names");
248 if (mbWriter)
250 mxCellImportPropertySetMapper = XMLTextImportHelper::CreateTableCellExtPropMapper(rImport);
252 else
254 mxCellImportPropertySetMapper = new SvXMLImportPropertyMapper( xCellPropertySetMapper, rImport );
255 mxCellImportPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(rImport));
256 mxCellImportPropertySetMapper->ChainImportMapper(new XMLCellImportPropertyMapper(new XMLPropertySetMapper(getCellPropertiesMap(), xFactoryRef, true), rImport));
259 rtl::Reference < XMLPropertySetMapper > xRowMapper( new XMLPropertySetMapper( getRowPropertiesMap(), xFactoryRef, false ) );
260 mxRowImportPropertySetMapper = new SvXMLImportPropertyMapper( xRowMapper, rImport );
262 rtl::Reference < XMLPropertySetMapper > xColMapper( new XMLPropertySetMapper( getColumnPropertiesMap(), xFactoryRef, false ) );
263 mxColumnImportPropertySetMapper = new SvXMLImportPropertyMapper( xColMapper, rImport );
266 XMLTableImport::~XMLTableImport()
270 SvXMLImportContext* XMLTableImport::CreateTableContext( Reference< XColumnRowRange > const & xColumnRowRange )
272 rtl::Reference< XMLTableImport > xThis( this );
273 return new XMLTableImportContext( xThis, xColumnRowRange );
276 SvXMLStyleContext* XMLTableImport::CreateTableTemplateContext( sal_Int32 /*nElement*/, const Reference< XFastAttributeList >& /*xAttrList*/ )
278 return new XMLTableTemplateContext( mrImport );
281 void XMLTableImport::addTableTemplate( const OUString& rsStyleName, XMLTableTemplate& xTableTemplate )
283 auto xPtr = std::make_shared<XMLTableTemplate>();
284 xPtr->swap( xTableTemplate );
285 maTableTemplates.emplace_back(rsStyleName, xPtr);
288 void XMLTableImport::finishStyles()
290 if( maTableTemplates.empty() )
291 return;
295 Reference< XStyleFamiliesSupplier > xFamiliesSupp( mrImport.GetModel(), UNO_QUERY_THROW );
296 Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
298 const OUString aTableFamily(mbWriter ? u"TableStyles" : u"table");
299 const OUString aCellFamily(mbWriter ? u"CellStyles" : u"cell");
300 Reference< XNameContainer > xTableFamily( xFamilies->getByName( aTableFamily ), UNO_QUERY_THROW );
301 Reference< XNameAccess > xCellFamily( xFamilies->getByName( aCellFamily ), UNO_QUERY_THROW );
303 Reference< XSingleServiceFactory > xFactory( xTableFamily, UNO_QUERY );
304 assert(xFactory.is() != mbWriter);
305 Reference< XMultiServiceFactory > xMultiFactory( mrImport.GetModel(), UNO_QUERY_THROW );
307 for( const auto& rTemplate : maTableTemplates ) try
309 const OUString sTemplateName( rTemplate.first );
310 Reference< XNameReplace > xTemplate(xFactory ? xFactory->createInstance() :
311 xMultiFactory->createInstance(u"com.sun.star.style.TableStyle"_ustr), UNO_QUERY_THROW);
313 std::shared_ptr< XMLTableTemplate > xT( rTemplate.second );
315 for( const auto& rStyle : *xT ) try
317 const OUString sPropName( rStyle.first );
318 const OUString sStyleName( mrImport.GetStyleDisplayName(XmlStyleFamily::TABLE_CELL, rStyle.second) );
319 xTemplate->replaceByName( sPropName, xCellFamily->getByName( sStyleName ) );
321 catch( Exception& )
323 TOOLS_WARN_EXCEPTION("xmloff.table", "");
326 if( xTemplate.is() )
328 if( xTableFamily->hasByName( sTemplateName ) )
329 xTableFamily->replaceByName( sTemplateName, Any( xTemplate ) );
330 else
331 xTableFamily->insertByName( sTemplateName, Any( xTemplate ) );
335 catch( Exception& )
337 TOOLS_WARN_EXCEPTION("xmloff.table", "");
340 catch( Exception& )
342 TOOLS_WARN_EXCEPTION("xmloff.table", "");
347 XMLTableImportContext::XMLTableImportContext( const rtl::Reference< XMLTableImport >& xImporter, Reference< XColumnRowRange > const & xColumnRowRange )
348 : SvXMLImportContext( xImporter->mrImport )
349 , mxTable( xColumnRowRange, UNO_QUERY )
350 , mxColumns( xColumnRowRange->getColumns() )
351 , mxRows( xColumnRowRange->getRows() )
352 , mnCurrentRow( -1 )
353 , mnCurrentColumn( -1 )
357 SvXMLImportContextRef XMLTableImportContext::ImportColumn( const Reference< XFastAttributeList >& xAttrList )
359 if( mxColumns.is() && (mnCurrentRow == -1) ) try
361 auto xInfo = std::make_shared<ColumnInfo>();
363 sal_Int32 nRepeated = 1;
365 // read attributes for the table-column
366 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
368 switch (aIter.getToken())
370 case XML_ELEMENT(TABLE, XML_NUMBER_COLUMNS_REPEATED):
371 nRepeated = aIter.toInt32();
372 break;
373 case XML_ELEMENT(TABLE, XML_STYLE_NAME):
374 xInfo->msStyleName = aIter.toString();
375 break;
376 case XML_ELEMENT(TABLE, XML_DEFAULT_CELL_STYLE_NAME):
377 xInfo->msDefaultCellStyleName = aIter.toString();
378 break;
379 case XML_ELEMENT(XML, XML_ID):
380 //FIXME: TODO
381 break;
385 if( nRepeated <= 1 )
387 maColumnInfos.push_back( xInfo );
389 else
391 maColumnInfos.insert( maColumnInfos.end(), nRepeated, xInfo );
394 catch( Exception& )
396 TOOLS_WARN_EXCEPTION("xmloff.table", "");
399 return nullptr;
402 void XMLTableImportContext::InitColumns()
404 if( !mxColumns.is() )
405 return;
409 const sal_Int32 nCount1 = mxColumns->getCount();
410 const sal_Int32 nCount2 = sal::static_int_cast< sal_Int32 >( maColumnInfos.size() );
411 if( nCount1 < nCount2 )
412 mxColumns->insertByIndex( nCount1, nCount2 - nCount1 );
414 SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
416 for( sal_Int32 nCol = 0; nCol < nCount2; nCol++ )
418 std::shared_ptr< ColumnInfo > xInfo( maColumnInfos[nCol] );
420 if( pAutoStyles && !xInfo->msStyleName.isEmpty() )
422 const XMLPropStyleContext* pStyle =
423 dynamic_cast< const XMLPropStyleContext* >(
424 pAutoStyles->FindStyleChildContext(XmlStyleFamily::TABLE_COLUMN, xInfo->msStyleName) );
426 if( pStyle )
428 Reference< XPropertySet > xColProps( mxColumns->getByIndex(nCol), UNO_QUERY_THROW );
429 const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xColProps );
435 catch( Exception& )
437 TOOLS_WARN_EXCEPTION("xmloff.table", "");
441 SvXMLImportContext * XMLTableImportContext::ImportRow( const Reference< XFastAttributeList >& xAttrList )
443 if( mxRows.is() )
445 mnCurrentRow++;
446 if( mnCurrentRow == 0 )
447 InitColumns(); // first init columns
449 mnCurrentColumn = -1;
451 const sal_Int32 nRowCount = mxRows->getCount();
452 if( ( nRowCount - 1) < mnCurrentRow )
454 const sal_Int32 nCount = mnCurrentRow - nRowCount + 1;
455 mxRows->insertByIndex( nRowCount, nCount );
458 Reference< XPropertySet > xRowSet( mxRows->getByIndex(mnCurrentRow), UNO_QUERY );
460 OUString sStyleName;
462 // read attributes for the table-row
463 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
465 switch(aIter.getToken())
467 case XML_ELEMENT(TABLE, XML_STYLE_NAME):
468 sStyleName = aIter.toString();
469 break;
470 case XML_ELEMENT(TABLE, XML_DEFAULT_CELL_STYLE_NAME):
471 msDefaultCellStyleName = aIter.toString();
472 break;
473 case XML_ELEMENT(XML, XML_ID):
474 //FIXME: TODO
475 break;
479 if( !sStyleName.isEmpty() )
481 SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
482 if( pAutoStyles )
484 const XMLPropStyleContext* pStyle =
485 dynamic_cast< const XMLPropStyleContext* >(
486 pAutoStyles->FindStyleChildContext(XmlStyleFamily::TABLE_ROW, sStyleName) );
488 if( pStyle )
490 const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xRowSet );
496 return new XMLProxyContext( GetImport(), SvXMLImportContextRef(this) );
499 SvXMLImportContextRef XMLTableImportContext::ImportCell( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttrList )
501 mnCurrentColumn++;
502 if( mxColumns.is() ) try
504 if( mxColumns->getCount() <= mnCurrentColumn )
505 mxColumns->insertByIndex( mxColumns->getCount(), mnCurrentColumn - mxColumns->getCount() + 1 );
507 Reference< XMergeableCell > xCell( mxTable->getCellByPosition( mnCurrentColumn, mnCurrentRow ), UNO_QUERY_THROW );
508 XMLCellImportContext* pCellContext = new XMLCellImportContext( GetImport(), xCell, GetDefaultCellStyleName(), nElement, xAttrList );
510 const sal_Int32 nColumnSpan = pCellContext->getColumnSpan();
511 const sal_Int32 nRowSpan = pCellContext->getRowSpan();
512 if( (nColumnSpan > 1) || (nRowSpan > 1) )
513 maMergeInfos.push_back( std::make_shared< MergeInfo >( mnCurrentColumn, mnCurrentRow, nColumnSpan, nRowSpan ) );
515 const sal_Int32 nRepeated = pCellContext->getRepeated();
516 if( nRepeated > 1 )
518 OSL_FAIL("xmloff::XMLTableImportContext::ImportCell(), import of repeated Cells not implemented (TODO)");
519 mnCurrentColumn += nRepeated - 1;
522 return pCellContext;
524 catch( Exception& )
526 TOOLS_WARN_EXCEPTION("xmloff.table", "");
529 return nullptr;
532 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLTableImportContext::createFastChildContext(
533 sal_Int32 nElement,
534 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
536 switch (nElement)
538 case XML_ELEMENT(TABLE, XML_TABLE_CELL):
539 case XML_ELEMENT(TABLE, XML_COVERED_TABLE_CELL):
540 return ImportCell( nElement, xAttrList );
541 case XML_ELEMENT(TABLE, XML_TABLE_COLUMN):
542 return ImportColumn( xAttrList );
543 case XML_ELEMENT(TABLE, XML_TABLE_ROW):
544 return ImportRow( xAttrList );
545 case XML_ELEMENT(TABLE, XML_TABLE_COLUMNS):
546 case XML_ELEMENT(TABLE, XML_TABLE_ROWS):
548 SvXMLImportContextRef xThis( this );
549 return new XMLProxyContext( GetImport(), xThis );
552 SAL_WARN("xmloff", "unknown element");
553 return nullptr;
556 void XMLTableImportContext::endFastElement(sal_Int32 )
558 for( const std::shared_ptr< MergeInfo >& xInfo : maMergeInfos )
560 if( xInfo ) try
562 Reference< XCellRange > xRange( mxTable->getCellRangeByPosition( xInfo->mnStartColumn, xInfo->mnStartRow, xInfo->mnEndColumn, xInfo->mnEndRow ) );
563 Reference< XMergeableCellRange > xCursor( mxTable->createCursorByRange( xRange ), UNO_QUERY_THROW );
564 xCursor->merge();
566 catch( Exception& )
568 TOOLS_WARN_EXCEPTION("xmloff.table", "");
573 OUString XMLTableImportContext::GetDefaultCellStyleName() const
575 OUString sStyleName( msDefaultCellStyleName );
577 // if there is still no style name, try default style name from column
578 if( (sStyleName.isEmpty()) && (mnCurrentColumn < sal::static_int_cast<sal_Int32>(maColumnInfos.size())) )
579 sStyleName = maColumnInfos[mnCurrentColumn]->msDefaultCellStyleName;
581 return sStyleName;
584 // XMLCellImportContext
586 XMLCellImportContext::XMLCellImportContext( SvXMLImport& rImport,
587 const Reference< XMergeableCell >& xCell,
588 const OUString& sDefaultCellStyleName,
589 sal_Int32 /*nElement*/,
590 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
591 : SvXMLImportContext( rImport )
592 , mxCell( xCell )
593 , mbListContextPushed( false )
594 , mnColSpan( 1 )
595 , mnRowSpan( 1 )
596 , mnRepeated( 1 )
598 OUString sStyleName;
600 // read attributes for the table-cell
601 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
603 switch (aIter.getToken())
605 case XML_ELEMENT(TABLE, XML_NUMBER_COLUMNS_REPEATED):
606 mnRepeated = aIter.toInt32();
607 break;
608 case XML_ELEMENT(TABLE, XML_NUMBER_COLUMNS_SPANNED):
609 mnColSpan = aIter.toInt32();
610 break;
611 case XML_ELEMENT(TABLE, XML_NUMBER_ROWS_SPANNED):
612 mnRowSpan = aIter.toInt32();
613 break;
614 case XML_ELEMENT(TABLE, XML_STYLE_NAME):
615 sStyleName = aIter.toString();
616 break;
617 case XML_ELEMENT(XML, XML_ID):
618 //FIXME: TODO
619 break;
620 //FIXME: RDFa (table:table-cell)
621 default:
622 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
626 // if there is no style name at the cell, try default style name from row
627 if( sStyleName.isEmpty() )
628 sStyleName = sDefaultCellStyleName;
630 if( sStyleName.isEmpty() )
631 return;
633 SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
634 if( !pAutoStyles )
635 return;
637 const XMLPropStyleContext* pStyle =
638 dynamic_cast< const XMLPropStyleContext* >(
639 pAutoStyles->FindStyleChildContext(XmlStyleFamily::TABLE_CELL, sStyleName) );
641 if( pStyle )
643 Reference< XPropertySet > xCellSet( mxCell, UNO_QUERY );
644 if( xCellSet.is() )
645 const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xCellSet );
649 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLCellImportContext::createFastChildContext(
650 sal_Int32 nElement,
651 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
653 // create text cursor on demand
654 if( !mxCursor.is() )
656 Reference< XText > xText( mxCell, UNO_QUERY );
657 if( xText.is() )
659 rtl::Reference < XMLTextImportHelper > xTxtImport( GetImport().GetTextImport() );
660 mxOldCursor = xTxtImport->GetCursor();
661 mxCursor = xText->createTextCursor();
662 if( mxCursor.is() )
663 xTxtImport->SetCursor( mxCursor );
665 // remember old list item and block (#91964#) and reset them
666 // for the text frame
667 xTxtImport->PushListContext();
668 mbListContextPushed = true;
672 SvXMLImportContext * pContext = nullptr;
674 // if we have a text cursor, let's try to import some text
675 if( mxCursor.is() )
677 pContext = GetImport().GetTextImport()->CreateTextChildContext( GetImport(), nElement, xAttrList );
680 if (!pContext)
681 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
682 return pContext;
685 void XMLCellImportContext::endFastElement(sal_Int32 )
687 if(mxCursor.is())
689 // delete addition newline
690 mxCursor->gotoEnd( false );
691 mxCursor->goLeft( 1, true );
692 mxCursor->setString( u""_ustr );
694 // reset cursor
695 GetImport().GetTextImport()->ResetCursor();
698 if(mxOldCursor.is())
699 GetImport().GetTextImport()->SetCursor( mxOldCursor );
701 // reinstall old list item (if necessary) #91964#
702 if (mbListContextPushed) {
703 GetImport().GetTextImport()->PopListContext();
708 XMLTableTemplateContext::XMLTableTemplateContext( SvXMLImport& rImport )
709 : SvXMLStyleContext( rImport, XmlStyleFamily::TABLE_TEMPLATE_ID, false )
713 void XMLTableTemplateContext::SetAttribute( sal_Int32 nElement,
714 const OUString& rValue )
716 if( nElement == XML_ELEMENT(TEXT, XML_STYLE_NAME)
717 // Writer specific: according to oasis odf 1.2 prefix should be "table" and element name should be "name"
718 || nElement == XML_ELEMENT(TABLE, XML_NAME) )
720 msTemplateStyleName = rValue;
724 void XMLTableTemplateContext::endFastElement(sal_Int32 )
726 rtl::Reference< XMLTableImport > xTableImport( GetImport().GetShapeImport()->GetShapeTableImport() );
727 if( xTableImport.is() )
728 xTableImport->addTableTemplate( msTemplateStyleName, maTableTemplate );
731 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLTableTemplateContext::createFastChildContext(
732 sal_Int32 nElement,
733 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
735 if( IsTokenInNamespace(nElement, XML_NAMESPACE_TABLE) )
737 const TableStyleElement* pElements = getTableStyleMap();
738 sal_Int32 nLocalName = nElement & TOKEN_MASK;
739 while( (pElements->meElement != XML_TOKEN_END) && pElements->meElement != nLocalName)
740 pElements++;
742 if( pElements->meElement != XML_TOKEN_END )
744 for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
746 switch (aIter.getToken())
748 case XML_ELEMENT(TEXT, XML_STYLE_NAME):
749 case XML_ELEMENT(TABLE, XML_STYLE_NAME):
750 maTableTemplate[pElements->msStyleName] = aIter.toString();
751 break;
752 default:
753 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
757 } else if (IsTokenInNamespace(nElement, XML_NAMESPACE_LO_EXT)) // Writer specific cell styles
759 const TableStyleElement* pElements = getWriterSpecificTableStyleMap();
760 sal_Int32 nLocalName = nElement & TOKEN_MASK;
761 while( (pElements->meElement != XML_TOKEN_END) && pElements->meElement != nLocalName)
762 pElements++;
764 if (pElements->meElement != XML_TOKEN_END)
766 for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
768 switch (aIter.getToken())
770 case XML_ELEMENT(TEXT, XML_STYLE_NAME):
771 case XML_ELEMENT(TABLE, XML_STYLE_NAME):
772 maTableTemplate[pElements->msStyleName] = aIter.toString();
773 break;
774 default:
775 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
781 return nullptr;
784 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */