office-gobmx/xmloff/source/table/XMLTableImport.cxx
Noel Grandin 601e9d4bad inline some typedefs
Change-Id: I1608e03ff9f6fbc55987010e88897e034b690b3a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115552
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2021-05-13 17:03:26 +02:00

808 lines
28 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <sal/config.h>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/table/XTableRows.hpp>
#include <com/sun/star/table/XMergeableCell.hpp>
#include <com/sun/star/table/XMergeableCellRange.hpp>
#include <com/sun/star/table/XTable.hpp>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/style/XStyle.hpp>
#include <comphelper/sequence.hxx>
#include <tools/diagnose_ex.h>
#include <xmloff/table/XMLTableImport.hxx>
#include <xmloff/xmlprmap.hxx>
#include <xmloff/txtimp.hxx>
#include <xmloff/xmlimp.hxx>
#include <xmloff/namespacemap.hxx>
#include <xmloff/xmlstyle.hxx>
#include <xmloff/prstylei.hxx>
#include <xmloff/xmlnamespace.hxx>
#include <xmloff/xmluconv.hxx>
#include "table.hxx"
#include <sal/log.hxx>
#include <memory>
using namespace ::xmloff::token;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::table;
using namespace ::com::sun::star::xml::sax;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::style;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::container;
namespace {
struct ColumnInfo
{
OUString msStyleName;
OUString msDefaultCellStyleName;
};
class XMLProxyContext : public SvXMLImportContext
{
public:
XMLProxyContext( SvXMLImport& rImport, const SvXMLImportContextRef& xParent );
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
private:
SvXMLImportContextRef mxParent;
};
struct MergeInfo
{
sal_Int32 mnStartColumn;
sal_Int32 mnStartRow;
sal_Int32 mnEndColumn;
sal_Int32 mnEndRow;
MergeInfo( sal_Int32 nStartColumn, sal_Int32 nStartRow, sal_Int32 nColumnSpan, sal_Int32 nRowSpan )
: mnStartColumn( nStartColumn ), mnStartRow( nStartRow ), mnEndColumn( nStartColumn + nColumnSpan - 1 ), mnEndRow( nStartRow + nRowSpan - 1 ) {};
};
}
class XMLTableImportContext : public SvXMLImportContext
{
public:
XMLTableImportContext( const rtl::Reference< XMLTableImport >& xThis, Reference< XColumnRowRange > const & xColumnRowRange );
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
sal_Int32 nElement,
const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
void InitColumns();
SvXMLImportContextRef ImportColumn( const Reference< XFastAttributeList >& xAttrList );
SvXMLImportContext * ImportRow( const Reference< XFastAttributeList >& xAttrList );
SvXMLImportContextRef ImportCell( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttrList );
OUString GetDefaultCellStyleName() const;
css::uno::Reference< css::table::XTable > mxTable;
Reference< XTableColumns > mxColumns;
Reference< XTableRows > mxRows;
std::vector< std::shared_ptr< ColumnInfo > > maColumnInfos;
sal_Int32 mnCurrentRow;
sal_Int32 mnCurrentColumn;
// default cell style name for the current row
OUString msDefaultCellStyleName;
std::vector< std::shared_ptr< MergeInfo > > maMergeInfos;
};
namespace {
class XMLCellImportContext : public SvXMLImportContext
{
public:
XMLCellImportContext( SvXMLImport& rImport,
const Reference< XMergeableCell >& xCell,
const OUString& sDefaultCellStyleName,
sal_Int32 nElement,
const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList );
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
sal_Int32 nElement,
const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
sal_Int32 getColumnSpan() const { return mnColSpan; }
sal_Int32 getRowSpan() const { return mnRowSpan; }
sal_Int32 getRepeated() const { return mnRepeated; }
Reference< XMergeableCell > mxCell;
Reference< XTextCursor > mxCursor;
Reference< XTextCursor > mxOldCursor;
bool mbListContextPushed;
sal_Int32 mnColSpan, mnRowSpan, mnRepeated;
};
class XMLTableTemplateContext : public SvXMLStyleContext
{
public:
XMLTableTemplateContext( SvXMLImport& rImport );
// Create child element.
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
virtual void CreateAndInsert( bool bOverwrite ) override;
protected:
virtual void SetAttribute( sal_Int32 nElement,
const OUString& rValue ) override;
private:
XMLTableTemplate maTableTemplate;
OUString msTemplateStyleName;
};
}
XMLProxyContext::XMLProxyContext( SvXMLImport& rImport, const SvXMLImportContextRef& xParent )
: SvXMLImportContext( rImport )
, mxParent( xParent )
{
}
css::uno::Reference< css::xml::sax::XFastContextHandler > XMLProxyContext::createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttrList )
{
if( mxParent.is() )
return mxParent->createFastChildContext( nElement, xAttrList );
return nullptr;
}
XMLTableImport::XMLTableImport( SvXMLImport& rImport, const rtl::Reference< XMLPropertySetMapper >& xCellPropertySetMapper, const rtl::Reference< XMLPropertyHandlerFactory >& xFactoryRef )
: mrImport( rImport )
{
bool bWriter = false;
// check if called by Writer
Reference<XMultiServiceFactory> xFac(rImport.GetModel(), UNO_QUERY);
if (xFac.is()) try
{
Sequence<OUString> sSNS = xFac->getAvailableServiceNames();
bWriter = comphelper::findValue(sSNS, "com.sun.star.style.TableStyle") != -1;
}
catch(const Exception&)
{
SAL_WARN("xmloff.table", "Error while checking available service names");
}
if (bWriter)
{
mxCellImportPropertySetMapper = XMLTextImportHelper::CreateTableCellExtPropMapper(rImport);
}
else
{
mxCellImportPropertySetMapper = new SvXMLImportPropertyMapper( xCellPropertySetMapper, rImport );
mxCellImportPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(rImport));
mxCellImportPropertySetMapper->ChainImportMapper(new SvXMLImportPropertyMapper(new XMLPropertySetMapper(getCellPropertiesMap(), xFactoryRef, true), rImport));
}
rtl::Reference < XMLPropertySetMapper > xRowMapper( new XMLPropertySetMapper( getRowPropertiesMap(), xFactoryRef, false ) );
mxRowImportPropertySetMapper = new SvXMLImportPropertyMapper( xRowMapper, rImport );
rtl::Reference < XMLPropertySetMapper > xColMapper( new XMLPropertySetMapper( getColumnPropertiesMap(), xFactoryRef, false ) );
mxColumnImportPropertySetMapper = new SvXMLImportPropertyMapper( xColMapper, rImport );
}
XMLTableImport::~XMLTableImport()
{
}
SvXMLImportContext* XMLTableImport::CreateTableContext( Reference< XColumnRowRange > const & xColumnRowRange )
{
rtl::Reference< XMLTableImport > xThis( this );
return new XMLTableImportContext( xThis, xColumnRowRange );
}
SvXMLStyleContext* XMLTableImport::CreateTableTemplateContext( sal_Int32 /*nElement*/, const Reference< XFastAttributeList >& /*xAttrList*/ )
{
return new XMLTableTemplateContext( mrImport );
}
void XMLTableImport::addTableTemplate( const OUString& rsStyleName, XMLTableTemplate& xTableTemplate )
{
auto xPtr = std::make_shared<XMLTableTemplate>();
xPtr->swap( xTableTemplate );
maTableTemplates[rsStyleName] = xPtr;
}
void XMLTableImport::insertTabletemplate(const OUString& rsStyleName, bool bOverwrite)
{
XMLTableTemplateMap::iterator it = maTableTemplates.find(rsStyleName);
if (it == maTableTemplates.end())
return;
try
{
Reference<XStyleFamiliesSupplier> xFamiliesSupp(mrImport.GetModel(), UNO_QUERY_THROW);
Reference<XNameAccess> xFamilies(xFamiliesSupp->getStyleFamilies());
Reference<XNameContainer> xTableFamily(xFamilies->getByName("TableStyles"), UNO_QUERY_THROW);
Reference<XIndexAccess> xCellFamily(xFamilies->getByName("CellStyles"), UNO_QUERY_THROW);
const OUString sTemplateName(it->first);
Reference<XMultiServiceFactory> xFactory(mrImport.GetModel(), UNO_QUERY_THROW);
Reference<XNameReplace> xTemplate(xFactory->createInstance("com.sun.star.style.TableStyle"), UNO_QUERY_THROW);
std::shared_ptr<XMLTableTemplate> xT(it->second);
for (const auto& rStyle : *xT) try
{
const OUString sPropName(rStyle.first);
const OUString sStyleName(rStyle.second);
// Internally unassigned cell styles are stored by display name.
// However table-template elements reference cell styles by its encoded name.
// This loop is looking for cell style by their encoded names.
sal_Int32 nCount = xCellFamily->getCount();
for (sal_Int32 i=0; i < nCount; ++i)
{
Any xCellStyle = xCellFamily->getByIndex(i);
OUString sEncodedStyleName = mrImport.GetMM100UnitConverter().encodeStyleName(
xCellStyle.get<Reference<XStyle>>()->getName());
if (sEncodedStyleName == sStyleName)
{
xTemplate->replaceByName(sPropName, xCellStyle);
break;
}
}
}
catch (Exception const &)
{
TOOLS_WARN_EXCEPTION("xmloff.table", "XMLTableImport::insertTabletemplate()");
}
if (xTemplate.is())
{
if (xTableFamily->hasByName(sTemplateName) && bOverwrite)
xTableFamily->replaceByName(sTemplateName, Any(xTemplate));
else
xTableFamily->insertByName(sTemplateName, Any(xTemplate));
}
}
catch (Exception&)
{
TOOLS_WARN_EXCEPTION("xmloff.table", "XMLTableImport::insertTabletemplate()");
}
}
void XMLTableImport::finishStyles()
{
if( maTableTemplates.empty() )
return;
try
{
Reference< XStyleFamiliesSupplier > xFamiliesSupp( mrImport.GetModel(), UNO_QUERY_THROW );
Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
Reference< XNameContainer > xTableFamily( xFamilies->getByName( "table" ), UNO_QUERY_THROW );
Reference< XNameAccess > xCellFamily( xFamilies->getByName( "cell" ), UNO_QUERY_THROW );
Reference< XSingleServiceFactory > xFactory( xTableFamily, UNO_QUERY_THROW );
for( const auto& rTemplate : maTableTemplates ) try
{
const OUString sTemplateName( rTemplate.first );
Reference< XNameReplace > xTemplate( xFactory->createInstance(), UNO_QUERY_THROW );
std::shared_ptr< XMLTableTemplate > xT( rTemplate.second );
for( const auto& rStyle : *xT ) try
{
const OUString sPropName( rStyle.first );
const OUString sStyleName( rStyle.second );
xTemplate->replaceByName( sPropName, xCellFamily->getByName( sStyleName ) );
}
catch( Exception& )
{
TOOLS_WARN_EXCEPTION("xmloff.table", "");
}
if( xTemplate.is() )
{
if( xTableFamily->hasByName( sTemplateName ) )
xTableFamily->replaceByName( sTemplateName, Any( xTemplate ) );
else
xTableFamily->insertByName( sTemplateName, Any( xTemplate ) );
}
}
catch( Exception& )
{
TOOLS_WARN_EXCEPTION("xmloff.table", "");
}
}
catch( Exception& )
{
TOOLS_WARN_EXCEPTION("xmloff.table", "");
}
}
XMLTableImportContext::XMLTableImportContext( const rtl::Reference< XMLTableImport >& xImporter, Reference< XColumnRowRange > const & xColumnRowRange )
: SvXMLImportContext( xImporter->mrImport )
, mxTable( xColumnRowRange, UNO_QUERY )
, mxColumns( xColumnRowRange->getColumns() )
, mxRows( xColumnRowRange->getRows() )
, mnCurrentRow( -1 )
, mnCurrentColumn( -1 )
{
}
SvXMLImportContextRef XMLTableImportContext::ImportColumn( const Reference< XFastAttributeList >& xAttrList )
{
if( mxColumns.is() && (mnCurrentRow == -1) ) try
{
auto xInfo = std::make_shared<ColumnInfo>();
sal_Int32 nRepeated = 1;
// read attributes for the table-column
for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
{
switch (aIter.getToken())
{
case XML_ELEMENT(TABLE, XML_NUMBER_COLUMNS_REPEATED):
nRepeated = aIter.toInt32();
break;
case XML_ELEMENT(TABLE, XML_STYLE_NAME):
xInfo->msStyleName = aIter.toString();
break;
case XML_ELEMENT(TABLE, XML_DEFAULT_CELL_STYLE_NAME):
xInfo->msDefaultCellStyleName = aIter.toString();
break;
case XML_ELEMENT(XML, XML_ID):
//FIXME: TODO
break;
}
}
if( nRepeated <= 1 )
{
maColumnInfos.push_back( xInfo );
}
else
{
maColumnInfos.insert( maColumnInfos.end(), nRepeated, xInfo );
}
}
catch( Exception& )
{
TOOLS_WARN_EXCEPTION("xmloff.table", "");
}
return nullptr;
}
void XMLTableImportContext::InitColumns()
{
if( !mxColumns.is() )
return;
try
{
const sal_Int32 nCount1 = mxColumns->getCount();
const sal_Int32 nCount2 = sal::static_int_cast< sal_Int32 >( maColumnInfos.size() );
if( nCount1 < nCount2 )
mxColumns->insertByIndex( nCount1, nCount2 - nCount1 );
SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
for( sal_Int32 nCol = 0; nCol < nCount2; nCol++ )
{
std::shared_ptr< ColumnInfo > xInfo( maColumnInfos[nCol] );
if( pAutoStyles && !xInfo->msStyleName.isEmpty() )
{
const XMLPropStyleContext* pStyle =
dynamic_cast< const XMLPropStyleContext* >(
pAutoStyles->FindStyleChildContext(XmlStyleFamily::TABLE_COLUMN, xInfo->msStyleName) );
if( pStyle )
{
Reference< XPropertySet > xColProps( mxColumns->getByIndex(nCol), UNO_QUERY_THROW );
const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xColProps );
}
}
}
}
catch( Exception& )
{
TOOLS_WARN_EXCEPTION("xmloff.table", "");
}
}
SvXMLImportContext * XMLTableImportContext::ImportRow( const Reference< XFastAttributeList >& xAttrList )
{
if( mxRows.is() )
{
mnCurrentRow++;
if( mnCurrentRow == 0 )
InitColumns(); // first init columns
mnCurrentColumn = -1;
const sal_Int32 nRowCount = mxRows->getCount();
if( ( nRowCount - 1) < mnCurrentRow )
{
const sal_Int32 nCount = mnCurrentRow - nRowCount + 1;
mxRows->insertByIndex( nRowCount, nCount );
}
Reference< XPropertySet > xRowSet( mxRows->getByIndex(mnCurrentRow), UNO_QUERY );
OUString sStyleName;
// read attributes for the table-row
for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
{
switch(aIter.getToken())
{
case XML_ELEMENT(TABLE, XML_STYLE_NAME):
sStyleName = aIter.toString();
break;
case XML_ELEMENT(TABLE, XML_DEFAULT_CELL_STYLE_NAME):
msDefaultCellStyleName = aIter.toString();
break;
case XML_ELEMENT(XML, XML_ID):
//FIXME: TODO
break;
}
}
if( !sStyleName.isEmpty() )
{
SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
if( pAutoStyles )
{
const XMLPropStyleContext* pStyle =
dynamic_cast< const XMLPropStyleContext* >(
pAutoStyles->FindStyleChildContext(XmlStyleFamily::TABLE_ROW, sStyleName) );
if( pStyle )
{
const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xRowSet );
}
}
}
}
SvXMLImportContextRef xThis( this );
return new XMLProxyContext( GetImport(), xThis );
}
SvXMLImportContextRef XMLTableImportContext::ImportCell( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttrList )
{
mnCurrentColumn++;
if( mxColumns.is() ) try
{
if( mxColumns->getCount() <= mnCurrentColumn )
mxColumns->insertByIndex( mxColumns->getCount(), mnCurrentColumn - mxColumns->getCount() + 1 );
Reference< XMergeableCell > xCell( mxTable->getCellByPosition( mnCurrentColumn, mnCurrentRow ), UNO_QUERY_THROW );
XMLCellImportContext* pCellContext = new XMLCellImportContext( GetImport(), xCell, GetDefaultCellStyleName(), nElement, xAttrList );
const sal_Int32 nColumnSpan = pCellContext->getColumnSpan();
const sal_Int32 nRowSpan = pCellContext->getRowSpan();
if( (nColumnSpan > 1) || (nRowSpan > 1) )
maMergeInfos.push_back( std::make_shared< MergeInfo >( mnCurrentColumn, mnCurrentRow, nColumnSpan, nRowSpan ) );
const sal_Int32 nRepeated = pCellContext->getRepeated();
if( nRepeated > 1 )
{
OSL_FAIL("xmloff::XMLTableImportContext::ImportCell(), import of repeated Cells not implemented (TODO)");
mnCurrentColumn += nRepeated - 1;
}
return pCellContext;
}
catch( Exception& )
{
TOOLS_WARN_EXCEPTION("xmloff.table", "");
}
return nullptr;
}
css::uno::Reference< css::xml::sax::XFastContextHandler > XMLTableImportContext::createFastChildContext(
sal_Int32 nElement,
const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
{
switch (nElement)
{
case XML_ELEMENT(TABLE, XML_TABLE_CELL):
case XML_ELEMENT(TABLE, XML_COVERED_TABLE_CELL):
return ImportCell( nElement, xAttrList );
case XML_ELEMENT(TABLE, XML_TABLE_COLUMN):
return ImportColumn( xAttrList );
case XML_ELEMENT(TABLE, XML_TABLE_ROW):
return ImportRow( xAttrList );
case XML_ELEMENT(TABLE, XML_TABLE_COLUMNS):
case XML_ELEMENT(TABLE, XML_TABLE_ROWS):
{
SvXMLImportContextRef xThis( this );
return new XMLProxyContext( GetImport(), xThis );
}
}
SAL_WARN("xmloff", "unknown element");
return nullptr;
}
void XMLTableImportContext::endFastElement(sal_Int32 )
{
for( const std::shared_ptr< MergeInfo >& xInfo : maMergeInfos )
{
if( xInfo ) try
{
Reference< XCellRange > xRange( mxTable->getCellRangeByPosition( xInfo->mnStartColumn, xInfo->mnStartRow, xInfo->mnEndColumn, xInfo->mnEndRow ) );
Reference< XMergeableCellRange > xCursor( mxTable->createCursorByRange( xRange ), UNO_QUERY_THROW );
xCursor->merge();
}
catch( Exception& )
{
TOOLS_WARN_EXCEPTION("xmloff.table", "");
}
}
}
OUString XMLTableImportContext::GetDefaultCellStyleName() const
{
OUString sStyleName( msDefaultCellStyleName );
// if there is still no style name, try default style name from column
if( (sStyleName.isEmpty()) && (mnCurrentColumn < sal::static_int_cast<sal_Int32>(maColumnInfos.size())) )
sStyleName = maColumnInfos[mnCurrentColumn]->msDefaultCellStyleName;
return sStyleName;
}
// XMLCellImportContext
XMLCellImportContext::XMLCellImportContext( SvXMLImport& rImport,
const Reference< XMergeableCell >& xCell,
const OUString& sDefaultCellStyleName,
sal_Int32 /*nElement*/,
const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
: SvXMLImportContext( rImport )
, mxCell( xCell )
, mbListContextPushed( false )
, mnColSpan( 1 )
, mnRowSpan( 1 )
, mnRepeated( 1 )
{
OUString sStyleName;
// read attributes for the table-cell
for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
{
switch (aIter.getToken())
{
case XML_ELEMENT(TABLE, XML_NUMBER_COLUMNS_REPEATED):
mnRepeated = aIter.toInt32();
break;
case XML_ELEMENT(TABLE, XML_NUMBER_COLUMNS_SPANNED):
mnColSpan = aIter.toInt32();
break;
case XML_ELEMENT(TABLE, XML_NUMBER_ROWS_SPANNED):
mnRowSpan = aIter.toInt32();
break;
case XML_ELEMENT(TABLE, XML_STYLE_NAME):
sStyleName = aIter.toString();
break;
case XML_ELEMENT(XML, XML_ID):
//FIXME: TODO
break;
//FIXME: RDFa (table:table-cell)
default:
XMLOFF_WARN_UNKNOWN("xmloff", aIter);
}
}
// if there is no style name at the cell, try default style name from row
if( sStyleName.isEmpty() )
sStyleName = sDefaultCellStyleName;
if( sStyleName.isEmpty() )
return;
SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
if( !pAutoStyles )
return;
const XMLPropStyleContext* pStyle =
dynamic_cast< const XMLPropStyleContext* >(
pAutoStyles->FindStyleChildContext(XmlStyleFamily::TABLE_CELL, sStyleName) );
if( pStyle )
{
Reference< XPropertySet > xCellSet( mxCell, UNO_QUERY );
if( xCellSet.is() )
const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xCellSet );
}
}
css::uno::Reference< css::xml::sax::XFastContextHandler > XMLCellImportContext::createFastChildContext(
sal_Int32 nElement,
const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
{
// create text cursor on demand
if( !mxCursor.is() )
{
Reference< XText > xText( mxCell, UNO_QUERY );
if( xText.is() )
{
rtl::Reference < XMLTextImportHelper > xTxtImport( GetImport().GetTextImport() );
mxOldCursor = xTxtImport->GetCursor();
mxCursor = xText->createTextCursor();
if( mxCursor.is() )
xTxtImport->SetCursor( mxCursor );
// remember old list item and block (#91964#) and reset them
// for the text frame
xTxtImport->PushListContext();
mbListContextPushed = true;
}
}
SvXMLImportContext * pContext = nullptr;
// if we have a text cursor, lets try to import some text
if( mxCursor.is() )
{
pContext = GetImport().GetTextImport()->CreateTextChildContext( GetImport(), nElement, xAttrList );
}
if (!pContext)
XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
return pContext;
}
void XMLCellImportContext::endFastElement(sal_Int32 )
{
if(mxCursor.is())
{
// delete addition newline
mxCursor->gotoEnd( false );
mxCursor->goLeft( 1, true );
mxCursor->setString( "" );
// reset cursor
GetImport().GetTextImport()->ResetCursor();
}
if(mxOldCursor.is())
GetImport().GetTextImport()->SetCursor( mxOldCursor );
// reinstall old list item (if necessary) #91964#
if (mbListContextPushed) {
GetImport().GetTextImport()->PopListContext();
}
}
XMLTableTemplateContext::XMLTableTemplateContext( SvXMLImport& rImport )
: SvXMLStyleContext( rImport, XmlStyleFamily::TABLE_TEMPLATE_ID, false )
{
}
void XMLTableTemplateContext::SetAttribute( sal_Int32 nElement,
const OUString& rValue )
{
if( nElement == XML_ELEMENT(TEXT, XML_STYLE_NAME)
// Writer specific: according to oasis odf 1.2 prefix should be "table" and element name should be "name"
|| nElement == XML_ELEMENT(TABLE, XML_NAME) )
{
msTemplateStyleName = rValue;
}
}
void XMLTableTemplateContext::endFastElement(sal_Int32 )
{
rtl::Reference< XMLTableImport > xTableImport( GetImport().GetShapeImport()->GetShapeTableImport() );
if( xTableImport.is() )
xTableImport->addTableTemplate( msTemplateStyleName, maTableTemplate );
}
void XMLTableTemplateContext::CreateAndInsert(bool bOverwrite)
{
rtl::Reference<XMLTableImport> xTableImport(GetImport().GetShapeImport()->GetShapeTableImport());
if(xTableImport.is())
xTableImport->insertTabletemplate(msTemplateStyleName, bOverwrite);
}
css::uno::Reference< css::xml::sax::XFastContextHandler > XMLTableTemplateContext::createFastChildContext(
sal_Int32 nElement,
const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
{
if( IsTokenInNamespace(nElement, XML_NAMESPACE_TABLE) )
{
const TableStyleElement* pElements = getTableStyleMap();
sal_Int32 nLocalName = nElement & TOKEN_MASK;
while( (pElements->meElement != XML_TOKEN_END) && pElements->meElement != nLocalName)
pElements++;
if( pElements->meElement != XML_TOKEN_END )
{
for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
{
switch (aIter.getToken())
{
case XML_ELEMENT(TEXT, XML_STYLE_NAME):
case XML_ELEMENT(TABLE, XML_STYLE_NAME):
maTableTemplate[pElements->msStyleName] = aIter.toString();
break;
default:
XMLOFF_WARN_UNKNOWN("xmloff", aIter);
}
}
}
} else if (IsTokenInNamespace(nElement, XML_NAMESPACE_LO_EXT)) // Writer specific cell styles
{
const TableStyleElement* pElements = getWriterSpecificTableStyleMap();
sal_Int32 nLocalName = nElement & TOKEN_MASK;
while( (pElements->meElement != XML_TOKEN_END) && pElements->meElement != nLocalName)
pElements++;
if (pElements->meElement != XML_TOKEN_END)
{
for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
{
switch (aIter.getToken())
{
case XML_ELEMENT(TEXT, XML_STYLE_NAME):
case XML_ELEMENT(TABLE, XML_STYLE_NAME):
maTableTemplate[pElements->msStyleName] = aIter.toString();
break;
default:
XMLOFF_WARN_UNKNOWN("xmloff", aIter);
}
}
}
}
return nullptr;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */