LibreOffice Module xmloff (master) 1
XMLTableImport.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
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>
35
36#include <utility>
38#include <xmloff/xmltypes.hxx>
39#include <xmloff/maptype.hxx>
40#include <xmloff/xmlprmap.hxx>
41#include <xmloff/txtimp.hxx>
42#include <xmloff/xmlimp.hxx>
44#include <xmloff/xmlstyle.hxx>
45#include <xmloff/prstylei.hxx>
46
48#include <xmloff/xmluconv.hxx>
49#include "table.hxx"
50
51#include <sal/log.hxx>
52
53#include <memory>
54
55using namespace ::xmloff::token;
56using namespace ::com::sun::star::beans;
57using namespace ::com::sun::star::uno;
58using namespace ::com::sun::star::table;
59using namespace ::com::sun::star::xml::sax;
60using namespace ::com::sun::star::text;
61using namespace ::com::sun::star::style;
62using namespace ::com::sun::star::lang;
63using namespace ::com::sun::star::container;
64
65namespace {
66
67struct ColumnInfo
68{
69 OUString msStyleName;
70 OUString msDefaultCellStyleName;
71};
72
73class XMLProxyContext : public SvXMLImportContext
74{
75public:
76 XMLProxyContext( SvXMLImport& rImport, SvXMLImportContextRef xParent );
77
78 virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
79 sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
80
81private:
83};
84
85struct MergeInfo
86{
87 sal_Int32 mnStartColumn;
88 sal_Int32 mnStartRow;
89 sal_Int32 mnEndColumn;
90 sal_Int32 mnEndRow;
91
92 MergeInfo( sal_Int32 nStartColumn, sal_Int32 nStartRow, sal_Int32 nColumnSpan, sal_Int32 nRowSpan )
93 : mnStartColumn( nStartColumn ), mnStartRow( nStartRow ), mnEndColumn( nStartColumn + nColumnSpan - 1 ), mnEndRow( nStartRow + nRowSpan - 1 ) {};
94};
95
96class XMLCellImportPropertyMapper : public SvXMLImportPropertyMapper
97{
98public:
100
102 XMLPropertyState& rProperty,
103 std::vector< XMLPropertyState >& rProperties,
104 const OUString& rValue,
105 const SvXMLUnitConverter& rUnitConverter,
106 const SvXMLNamespaceMap& /*rNamespaceMap*/) const override
107 {
108 assert(getPropertySetMapper()->GetEntryXMLName(rProperty.mnIndex) == GetXMLToken(XML_BACKGROUND_COLOR));
109 (void)rProperty;
110
112 XMLPropertyState aFillProperty(nIndex);
113
114 if (IsXMLToken(rValue, XML_TRANSPARENT))
115 {
116 getPropertySetMapper()->importXML(GetXMLToken(XML_NONE), aFillProperty, rUnitConverter);
117 rProperties.push_back(aFillProperty);
118 }
119 else
120 {
121 getPropertySetMapper()->importXML(GetXMLToken(XML_SOLID), aFillProperty, rUnitConverter);
122 rProperties.push_back(aFillProperty);
123
125 XMLPropertyState aColorProperty(nIndex);
126 getPropertySetMapper()->importXML(rValue, aColorProperty, rUnitConverter);
127 rProperties.push_back(aColorProperty);
128 }
129
130 return false;
131 }
132};
133
134}
135
137{
138public:
139 XMLTableImportContext( const rtl::Reference< XMLTableImport >& xThis, Reference< XColumnRowRange > const & xColumnRowRange );
140
141 virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
142 sal_Int32 nElement,
143 const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
144
145 virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
146
147 void InitColumns();
148
149 SvXMLImportContextRef ImportColumn( const Reference< XFastAttributeList >& xAttrList );
150 SvXMLImportContext * ImportRow( const Reference< XFastAttributeList >& xAttrList );
151 SvXMLImportContextRef ImportCell( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttrList );
152
153 OUString GetDefaultCellStyleName() const;
154
155 css::uno::Reference< css::table::XTable > mxTable;
156 Reference< XTableColumns > mxColumns;
157 Reference< XTableRows > mxRows;
158
159 std::vector< std::shared_ptr< ColumnInfo > > maColumnInfos;
160 sal_Int32 mnCurrentRow;
162
163 // default cell style name for the current row
165
166 std::vector< std::shared_ptr< MergeInfo > > maMergeInfos;
167};
168
169namespace {
170
171class XMLCellImportContext : public SvXMLImportContext
172{
173public:
174 XMLCellImportContext( SvXMLImport& rImport,
175 const Reference< XMergeableCell >& xCell,
176 const OUString& sDefaultCellStyleName,
177 sal_Int32 nElement,
178 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList );
179
180 virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
181 sal_Int32 nElement,
182 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
183
184 virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
185
186 sal_Int32 getColumnSpan() const { return mnColSpan; }
187 sal_Int32 getRowSpan() const { return mnRowSpan; }
188 sal_Int32 getRepeated() const { return mnRepeated; }
189
190 Reference< XMergeableCell > mxCell;
191 Reference< XTextCursor > mxCursor;
192 Reference< XTextCursor > mxOldCursor;
193 bool mbListContextPushed;
194
195 sal_Int32 mnColSpan, mnRowSpan, mnRepeated;
196};
197
198class XMLTableTemplateContext : public SvXMLStyleContext
199{
200public:
201 XMLTableTemplateContext( SvXMLImport& rImport );
202
203 // Create child element.
204 virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
205 sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& AttrList ) override;
206
207 virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
208
209 virtual void CreateAndInsert( bool bOverwrite ) override;
210protected:
211 virtual void SetAttribute( sal_Int32 nElement,
212 const OUString& rValue ) override;
213private:
214 XMLTableTemplate maTableTemplate;
215 OUString msTemplateStyleName;
216};
217
218}
219
220
221XMLProxyContext::XMLProxyContext( SvXMLImport& rImport, SvXMLImportContextRef xParent )
222: SvXMLImportContext( rImport )
223, mxParent(std::move( xParent ))
224{
225}
226
227css::uno::Reference< css::xml::sax::XFastContextHandler > XMLProxyContext::createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttrList )
228{
229 if( mxParent.is() )
230 return mxParent->createFastChildContext( nElement, xAttrList );
231 return nullptr;
232}
233
234
235XMLTableImport::XMLTableImport( SvXMLImport& rImport, const rtl::Reference< XMLPropertySetMapper >& xCellPropertySetMapper, const rtl::Reference< XMLPropertyHandlerFactory >& xFactoryRef )
236: mrImport( rImport )
237{
238 bool bWriter = false;
239 // check if called by Writer
240 Reference<XMultiServiceFactory> xFac(rImport.GetModel(), UNO_QUERY);
241 if (xFac.is()) try
242 {
243 Sequence<OUString> sSNS = xFac->getAvailableServiceNames();
244 bWriter = comphelper::findValue(sSNS, "com.sun.star.style.TableStyle") != -1;
245 }
246 catch(const Exception&)
247 {
248 SAL_WARN("xmloff.table", "Error while checking available service names");
249 }
250
251 if (bWriter)
252 {
254 }
255 else
256 {
257 mxCellImportPropertySetMapper = new SvXMLImportPropertyMapper( xCellPropertySetMapper, rImport );
259 mxCellImportPropertySetMapper->ChainImportMapper(new XMLCellImportPropertyMapper(new XMLPropertySetMapper(getCellPropertiesMap(), xFactoryRef, true), rImport));
260 }
261
263 mxRowImportPropertySetMapper = new SvXMLImportPropertyMapper( xRowMapper, rImport );
264
267}
268
270{
271}
272
273SvXMLImportContext* XMLTableImport::CreateTableContext( Reference< XColumnRowRange > const & xColumnRowRange )
274{
276 return new XMLTableImportContext( xThis, xColumnRowRange );
277}
278
279SvXMLStyleContext* XMLTableImport::CreateTableTemplateContext( sal_Int32 /*nElement*/, const Reference< XFastAttributeList >& /*xAttrList*/ )
280{
281 return new XMLTableTemplateContext( mrImport );
282}
283
284void XMLTableImport::addTableTemplate( const OUString& rsStyleName, XMLTableTemplate& xTableTemplate )
285{
286 auto xPtr = std::make_shared<XMLTableTemplate>();
287 xPtr->swap( xTableTemplate );
288 maTableTemplates.emplace_back(rsStyleName, xPtr);
289}
290
291void XMLTableImport::insertTabletemplate(const OUString& rsStyleName, bool bOverwrite)
292{
293 // FIXME: All templates will be inserted eventually, but
294 // instead of simply iterating them, like in finishStyles(),
295 // we search here by name again and again.
296 auto it = std::find_if(maTableTemplates.begin(), maTableTemplates.end(),
297 [&rsStyleName](const auto& item) { return rsStyleName == item.first; });
298 if (it == maTableTemplates.end())
299 return;
300
301 try
302 {
303 Reference<XStyleFamiliesSupplier> xFamiliesSupp(mrImport.GetModel(), UNO_QUERY_THROW);
304 Reference<XNameAccess> xFamilies(xFamiliesSupp->getStyleFamilies());
305
306 Reference<XNameContainer> xTableFamily(xFamilies->getByName("TableStyles"), UNO_QUERY_THROW);
307 Reference<XIndexAccess> xCellFamily(xFamilies->getByName("CellStyles"), UNO_QUERY_THROW);
308
309 const OUString sTemplateName(it->first);
310 Reference<XMultiServiceFactory> xFactory(mrImport.GetModel(), UNO_QUERY_THROW);
311 Reference<XNameReplace> xTemplate(xFactory->createInstance("com.sun.star.style.TableStyle"), UNO_QUERY_THROW);
312
313 std::shared_ptr<XMLTableTemplate> xT(it->second);
314
315 for (const auto& rStyle : *xT) try
316 {
317 const OUString sPropName(rStyle.first);
318 const OUString sStyleName(rStyle.second);
319 // Internally unassigned cell styles are stored by display name.
320 // However table-template elements reference cell styles by its encoded name.
321 // This loop is looking for cell style by their encoded names.
322 sal_Int32 nCount = xCellFamily->getCount();
323 for (sal_Int32 i=0; i < nCount; ++i)
324 {
325 Any xCellStyle = xCellFamily->getByIndex(i);
326 OUString sEncodedStyleName = mrImport.GetMM100UnitConverter().encodeStyleName(
327 xCellStyle.get<Reference<XStyle>>()->getName());
328 if (sEncodedStyleName == sStyleName)
329 {
330 xTemplate->replaceByName(sPropName, xCellStyle);
331 break;
332 }
333 }
334 }
335 catch (Exception const &)
336 {
337 TOOLS_WARN_EXCEPTION("xmloff.table", "XMLTableImport::insertTabletemplate()");
338 }
339
340 if (xTemplate.is())
341 {
342 if (xTableFamily->hasByName(sTemplateName) && bOverwrite)
343 xTableFamily->replaceByName(sTemplateName, Any(xTemplate));
344 else
345 xTableFamily->insertByName(sTemplateName, Any(xTemplate));
346 }
347 }
348 catch (Exception&)
349 {
350 TOOLS_WARN_EXCEPTION("xmloff.table", "XMLTableImport::insertTabletemplate()");
351 }
352}
353
355{
356 if( maTableTemplates.empty() )
357 return;
358
359 try
360 {
361 Reference< XStyleFamiliesSupplier > xFamiliesSupp( mrImport.GetModel(), UNO_QUERY_THROW );
362 Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
363
364 Reference< XNameContainer > xTableFamily( xFamilies->getByName( "table" ), UNO_QUERY_THROW );
365 Reference< XNameAccess > xCellFamily( xFamilies->getByName( "cell" ), UNO_QUERY_THROW );
366
367 Reference< XSingleServiceFactory > xFactory( xTableFamily, UNO_QUERY_THROW );
368
369 for( const auto& rTemplate : maTableTemplates ) try
370 {
371 const OUString sTemplateName( rTemplate.first );
372 Reference< XNameReplace > xTemplate( xFactory->createInstance(), UNO_QUERY_THROW );
373
374 std::shared_ptr< XMLTableTemplate > xT( rTemplate.second );
375
376 for( const auto& rStyle : *xT ) try
377 {
378 const OUString sPropName( rStyle.first );
379 const OUString sStyleName( rStyle.second );
380 xTemplate->replaceByName( sPropName, xCellFamily->getByName( sStyleName ) );
381 }
382 catch( Exception& )
383 {
384 TOOLS_WARN_EXCEPTION("xmloff.table", "");
385 }
386
387 if( xTemplate.is() )
388 {
389 if( xTableFamily->hasByName( sTemplateName ) )
390 xTableFamily->replaceByName( sTemplateName, Any( xTemplate ) );
391 else
392 xTableFamily->insertByName( sTemplateName, Any( xTemplate ) );
393 }
394
395 }
396 catch( Exception& )
397 {
398 TOOLS_WARN_EXCEPTION("xmloff.table", "");
399 }
400 }
401 catch( Exception& )
402 {
403 TOOLS_WARN_EXCEPTION("xmloff.table", "");
404 }
405}
406
407
408XMLTableImportContext::XMLTableImportContext( const rtl::Reference< XMLTableImport >& xImporter, Reference< XColumnRowRange > const & xColumnRowRange )
409: SvXMLImportContext( xImporter->mrImport )
410, mxTable( xColumnRowRange, UNO_QUERY )
411, mxColumns( xColumnRowRange->getColumns() )
412, mxRows( xColumnRowRange->getRows() )
413, mnCurrentRow( -1 )
414, mnCurrentColumn( -1 )
415{
416}
417
418SvXMLImportContextRef XMLTableImportContext::ImportColumn( const Reference< XFastAttributeList >& xAttrList )
419{
420 if( mxColumns.is() && (mnCurrentRow == -1) ) try
421 {
422 auto xInfo = std::make_shared<ColumnInfo>();
423
424 sal_Int32 nRepeated = 1;
425
426 // read attributes for the table-column
427 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
428 {
429 switch (aIter.getToken())
430 {
432 nRepeated = aIter.toInt32();
433 break;
435 xInfo->msStyleName = aIter.toString();
436 break;
438 xInfo->msDefaultCellStyleName = aIter.toString();
439 break;
440 case XML_ELEMENT(XML, XML_ID):
441 //FIXME: TODO
442 break;
443 }
444 }
445
446 if( nRepeated <= 1 )
447 {
448 maColumnInfos.push_back( xInfo );
449 }
450 else
451 {
452 maColumnInfos.insert( maColumnInfos.end(), nRepeated, xInfo );
453 }
454 }
455 catch( Exception& )
456 {
457 TOOLS_WARN_EXCEPTION("xmloff.table", "");
458 }
459
460 return nullptr;
461}
462
464{
465 if( !mxColumns.is() )
466 return;
467
468 try
469 {
470 const sal_Int32 nCount1 = mxColumns->getCount();
471 const sal_Int32 nCount2 = sal::static_int_cast< sal_Int32 >( maColumnInfos.size() );
472 if( nCount1 < nCount2 )
473 mxColumns->insertByIndex( nCount1, nCount2 - nCount1 );
474
475 SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
476
477 for( sal_Int32 nCol = 0; nCol < nCount2; nCol++ )
478 {
479 std::shared_ptr< ColumnInfo > xInfo( maColumnInfos[nCol] );
480
481 if( pAutoStyles && !xInfo->msStyleName.isEmpty() )
482 {
483 const XMLPropStyleContext* pStyle =
484 dynamic_cast< const XMLPropStyleContext* >(
485 pAutoStyles->FindStyleChildContext(XmlStyleFamily::TABLE_COLUMN, xInfo->msStyleName) );
486
487 if( pStyle )
488 {
489 Reference< XPropertySet > xColProps( mxColumns->getByIndex(nCol), UNO_QUERY_THROW );
490 const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xColProps );
491 }
492 }
493
494 }
495 }
496 catch( Exception& )
497 {
498 TOOLS_WARN_EXCEPTION("xmloff.table", "");
499 }
500}
501
502SvXMLImportContext * XMLTableImportContext::ImportRow( const Reference< XFastAttributeList >& xAttrList )
503{
504 if( mxRows.is() )
505 {
506 mnCurrentRow++;
507 if( mnCurrentRow == 0 )
508 InitColumns(); // first init columns
509
510 mnCurrentColumn = -1;
511
512 const sal_Int32 nRowCount = mxRows->getCount();
513 if( ( nRowCount - 1) < mnCurrentRow )
514 {
515 const sal_Int32 nCount = mnCurrentRow - nRowCount + 1;
516 mxRows->insertByIndex( nRowCount, nCount );
517 }
518
519 Reference< XPropertySet > xRowSet( mxRows->getByIndex(mnCurrentRow), UNO_QUERY );
520
521 OUString sStyleName;
522
523 // read attributes for the table-row
524 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
525 {
526 switch(aIter.getToken())
527 {
529 sStyleName = aIter.toString();
530 break;
532 msDefaultCellStyleName = aIter.toString();
533 break;
534 case XML_ELEMENT(XML, XML_ID):
535 //FIXME: TODO
536 break;
537 }
538 }
539
540 if( !sStyleName.isEmpty() )
541 {
542 SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
543 if( pAutoStyles )
544 {
545 const XMLPropStyleContext* pStyle =
546 dynamic_cast< const XMLPropStyleContext* >(
547 pAutoStyles->FindStyleChildContext(XmlStyleFamily::TABLE_ROW, sStyleName) );
548
549 if( pStyle )
550 {
551 const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xRowSet );
552 }
553 }
554 }
555 }
556
557 SvXMLImportContextRef xThis( this );
558 return new XMLProxyContext( GetImport(), xThis );
559}
560
561SvXMLImportContextRef XMLTableImportContext::ImportCell( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttrList )
562{
564 if( mxColumns.is() ) try
565 {
566 if( mxColumns->getCount() <= mnCurrentColumn )
567 mxColumns->insertByIndex( mxColumns->getCount(), mnCurrentColumn - mxColumns->getCount() + 1 );
568
569 Reference< XMergeableCell > xCell( mxTable->getCellByPosition( mnCurrentColumn, mnCurrentRow ), UNO_QUERY_THROW );
570 XMLCellImportContext* pCellContext = new XMLCellImportContext( GetImport(), xCell, GetDefaultCellStyleName(), nElement, xAttrList );
571
572 const sal_Int32 nColumnSpan = pCellContext->getColumnSpan();
573 const sal_Int32 nRowSpan = pCellContext->getRowSpan();
574 if( (nColumnSpan > 1) || (nRowSpan > 1) )
575 maMergeInfos.push_back( std::make_shared< MergeInfo >( mnCurrentColumn, mnCurrentRow, nColumnSpan, nRowSpan ) );
576
577 const sal_Int32 nRepeated = pCellContext->getRepeated();
578 if( nRepeated > 1 )
579 {
580 OSL_FAIL("xmloff::XMLTableImportContext::ImportCell(), import of repeated Cells not implemented (TODO)");
581 mnCurrentColumn += nRepeated - 1;
582 }
583
584 return pCellContext;
585 }
586 catch( Exception& )
587 {
588 TOOLS_WARN_EXCEPTION("xmloff.table", "");
589 }
590
591 return nullptr;
592}
593
594css::uno::Reference< css::xml::sax::XFastContextHandler > XMLTableImportContext::createFastChildContext(
595 sal_Int32 nElement,
596 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
597{
598 switch (nElement)
599 {
602 return ImportCell( nElement, xAttrList );
604 return ImportColumn( xAttrList );
606 return ImportRow( xAttrList );
609 {
610 SvXMLImportContextRef xThis( this );
611 return new XMLProxyContext( GetImport(), xThis );
612 }
613 }
614 SAL_WARN("xmloff", "unknown element");
615 return nullptr;
616}
617
619{
620 for( const std::shared_ptr< MergeInfo >& xInfo : maMergeInfos )
621 {
622 if( xInfo ) try
623 {
624 Reference< XCellRange > xRange( mxTable->getCellRangeByPosition( xInfo->mnStartColumn, xInfo->mnStartRow, xInfo->mnEndColumn, xInfo->mnEndRow ) );
625 Reference< XMergeableCellRange > xCursor( mxTable->createCursorByRange( xRange ), UNO_QUERY_THROW );
626 xCursor->merge();
627 }
628 catch( Exception& )
629 {
630 TOOLS_WARN_EXCEPTION("xmloff.table", "");
631 }
632 }
633}
634
636{
637 OUString sStyleName( msDefaultCellStyleName );
638
639 // if there is still no style name, try default style name from column
640 if( (sStyleName.isEmpty()) && (mnCurrentColumn < sal::static_int_cast<sal_Int32>(maColumnInfos.size())) )
641 sStyleName = maColumnInfos[mnCurrentColumn]->msDefaultCellStyleName;
642
643 return sStyleName;
644}
645
646// XMLCellImportContext
647
648XMLCellImportContext::XMLCellImportContext( SvXMLImport& rImport,
649 const Reference< XMergeableCell >& xCell,
650 const OUString& sDefaultCellStyleName,
651 sal_Int32 /*nElement*/,
652 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
653: SvXMLImportContext( rImport )
654, mxCell( xCell )
655, mbListContextPushed( false )
656, mnColSpan( 1 )
657, mnRowSpan( 1 )
658, mnRepeated( 1 )
659{
660 OUString sStyleName;
661
662 // read attributes for the table-cell
663 for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
664 {
665 switch (aIter.getToken())
666 {
668 mnRepeated = aIter.toInt32();
669 break;
671 mnColSpan = aIter.toInt32();
672 break;
674 mnRowSpan = aIter.toInt32();
675 break;
676 case XML_ELEMENT(TABLE, XML_STYLE_NAME):
677 sStyleName = aIter.toString();
678 break;
679 case XML_ELEMENT(XML, XML_ID):
680//FIXME: TODO
681 break;
682//FIXME: RDFa (table:table-cell)
683 default:
684 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
685 }
686 }
687
688 // if there is no style name at the cell, try default style name from row
689 if( sStyleName.isEmpty() )
690 sStyleName = sDefaultCellStyleName;
691
692 if( sStyleName.isEmpty() )
693 return;
694
695 SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
696 if( !pAutoStyles )
697 return;
698
699 const XMLPropStyleContext* pStyle =
700 dynamic_cast< const XMLPropStyleContext* >(
701 pAutoStyles->FindStyleChildContext(XmlStyleFamily::TABLE_CELL, sStyleName) );
702
703 if( pStyle )
704 {
705 Reference< XPropertySet > xCellSet( mxCell, UNO_QUERY );
706 if( xCellSet.is() )
707 const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xCellSet );
708 }
709}
710
711css::uno::Reference< css::xml::sax::XFastContextHandler > XMLCellImportContext::createFastChildContext(
712 sal_Int32 nElement,
713 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
714{
715 // create text cursor on demand
716 if( !mxCursor.is() )
717 {
718 Reference< XText > xText( mxCell, UNO_QUERY );
719 if( xText.is() )
720 {
721 rtl::Reference < XMLTextImportHelper > xTxtImport( GetImport().GetTextImport() );
722 mxOldCursor = xTxtImport->GetCursor();
723 mxCursor = xText->createTextCursor();
724 if( mxCursor.is() )
725 xTxtImport->SetCursor( mxCursor );
726
727 // remember old list item and block (#91964#) and reset them
728 // for the text frame
729 xTxtImport->PushListContext();
730 mbListContextPushed = true;
731 }
732 }
733
734 SvXMLImportContext * pContext = nullptr;
735
736 // if we have a text cursor, lets try to import some text
737 if( mxCursor.is() )
738 {
739 pContext = GetImport().GetTextImport()->CreateTextChildContext( GetImport(), nElement, xAttrList );
740 }
741
742 if (!pContext)
743 XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
744 return pContext;
745}
746
747void XMLCellImportContext::endFastElement(sal_Int32 )
748{
749 if(mxCursor.is())
750 {
751 // delete addition newline
752 mxCursor->gotoEnd( false );
753 mxCursor->goLeft( 1, true );
754 mxCursor->setString( "" );
755
756 // reset cursor
757 GetImport().GetTextImport()->ResetCursor();
758 }
759
760 if(mxOldCursor.is())
761 GetImport().GetTextImport()->SetCursor( mxOldCursor );
762
763 // reinstall old list item (if necessary) #91964#
764 if (mbListContextPushed) {
765 GetImport().GetTextImport()->PopListContext();
766 }
767}
768
769
770XMLTableTemplateContext::XMLTableTemplateContext( SvXMLImport& rImport )
772{
773}
774
775void XMLTableTemplateContext::SetAttribute( sal_Int32 nElement,
776 const OUString& rValue )
777{
778 if( nElement == XML_ELEMENT(TEXT, XML_STYLE_NAME)
779 // Writer specific: according to oasis odf 1.2 prefix should be "table" and element name should be "name"
780 || nElement == XML_ELEMENT(TABLE, XML_NAME) )
781 {
782 msTemplateStyleName = rValue;
783 }
784}
785
786void XMLTableTemplateContext::endFastElement(sal_Int32 )
787{
788 rtl::Reference< XMLTableImport > xTableImport( GetImport().GetShapeImport()->GetShapeTableImport() );
789 if( xTableImport.is() )
790 xTableImport->addTableTemplate( msTemplateStyleName, maTableTemplate );
791}
792
793void XMLTableTemplateContext::CreateAndInsert(bool bOverwrite)
794{
795 rtl::Reference<XMLTableImport> xTableImport(GetImport().GetShapeImport()->GetShapeTableImport());
796 if(xTableImport.is())
797 xTableImport->insertTabletemplate(msTemplateStyleName, bOverwrite);
798}
799
800css::uno::Reference< css::xml::sax::XFastContextHandler > XMLTableTemplateContext::createFastChildContext(
801 sal_Int32 nElement,
802 const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
803{
805 {
806 const TableStyleElement* pElements = getTableStyleMap();
807 sal_Int32 nLocalName = nElement & TOKEN_MASK;
808 while( (pElements->meElement != XML_TOKEN_END) && pElements->meElement != nLocalName)
809 pElements++;
810
811 if( pElements->meElement != XML_TOKEN_END )
812 {
813 for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
814 {
815 switch (aIter.getToken())
816 {
817 case XML_ELEMENT(TEXT, XML_STYLE_NAME):
819 maTableTemplate[pElements->msStyleName] = aIter.toString();
820 break;
821 default:
822 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
823 }
824 }
825 }
826 } else if (IsTokenInNamespace(nElement, XML_NAMESPACE_LO_EXT)) // Writer specific cell styles
827 {
829 sal_Int32 nLocalName = nElement & TOKEN_MASK;
830 while( (pElements->meElement != XML_TOKEN_END) && pElements->meElement != nLocalName)
831 pElements++;
832
833 if (pElements->meElement != XML_TOKEN_END)
834 {
835 for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
836 {
837 switch (aIter.getToken())
838 {
839 case XML_ELEMENT(TEXT, XML_STYLE_NAME):
841 maTableTemplate[pElements->msStyleName] = aIter.toString();
842 break;
843 default:
844 XMLOFF_WARN_UNKNOWN("xmloff", aIter);
845 }
846 }
847 }
848 }
849
850 return nullptr;
851}
852
853/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OUString msStyleName
std::map< OUString, OUString > XMLTableTemplate
WeakReference< XInterface > mxParent
constexpr OUStringLiteral sTemplateName
This class deliberately does not support XWeak, to improve performance when loading large documents.
Definition: xmlictxt.hxx:48
virtual void SAL_CALL endFastElement(sal_Int32 Element) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
Definition: xmlictxt.cxx:40
SvXMLImport & GetImport()
Definition: xmlictxt.hxx:60
virtual css::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > &Attribs) override
Definition: xmlictxt.cxx:59
virtual bool handleSpecialItem(XMLPropertyState &rProperty, ::std::vector< XMLPropertyState > &rProperties, const OUString &rValue, const SvXMLUnitConverter &rUnitConverter, const SvXMLNamespaceMap &rNamespaceMap) const
this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_IMPORT flag set
Definition: xmlimppr.cxx:347
const rtl::Reference< XMLPropertySetMapper > & getPropertySetMapper() const
Definition: xmlimppr.hxx:197
SvXMLImportPropertyMapper(SvXMLImportPropertyMapper const &)=delete
virtual void SetAttribute(sal_Int32 nElement, const OUString &rValue)
Definition: xmlstyle.cxx:69
virtual void CreateAndInsert(bool bOverwrite)
Definition: xmlstyle.cxx:135
const SvXMLStyleContext * FindStyleChildContext(XmlStyleFamily nFamily, const OUString &rName, bool bCreateIndex=false) const
Definition: xmlstyle.cxx:799
the SvXMLTypeConverter converts values of various types from their internal representation to the tex...
Definition: xmluconv.hxx:83
SvXMLImportContext * ImportRow(const Reference< XFastAttributeList > &xAttrList)
Reference< XTableRows > mxRows
XMLTableImportContext(const rtl::Reference< XMLTableImport > &xThis, Reference< XColumnRowRange > const &xColumnRowRange)
SvXMLImportContextRef ImportColumn(const Reference< XFastAttributeList > &xAttrList)
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &AttrList) override
OUString GetDefaultCellStyleName() const
css::uno::Reference< css::table::XTable > mxTable
std::vector< std::shared_ptr< ColumnInfo > > maColumnInfos
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
std::vector< std::shared_ptr< MergeInfo > > maMergeInfos
Reference< XTableColumns > mxColumns
SvXMLImportContextRef ImportCell(sal_Int32 nElement, const Reference< XFastAttributeList > &xAttrList)
virtual ~XMLTableImport() override
void finishStyles()
Inserts all table templates.
friend class XMLTableImportContext
SvXMLImportContext * CreateTableContext(css::uno::Reference< css::table::XColumnRowRange > const &xColumnRowRange)
XMLTableImport(SvXMLImport &rImport, const rtl::Reference< XMLPropertySetMapper > &xCellPropertySetMapper, const rtl::Reference< XMLPropertyHandlerFactory > &xFactoryRef)
XMLTableTemplateMap maTableTemplates
rtl::Reference< SvXMLImportPropertyMapper > mxCellImportPropertySetMapper
rtl::Reference< SvXMLImportPropertyMapper > mxColumnImportPropertySetMapper
SvXMLStyleContext * CreateTableTemplateContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
void addTableTemplate(const OUString &rsStyleName, XMLTableTemplate &xTableTemplate)
void insertTabletemplate(const OUString &rsStyleName, bool bOverwrite)
Inserts to the doc template with given name.
SvXMLImport & mrImport
rtl::Reference< SvXMLImportPropertyMapper > mxRowImportPropertySetMapper
static SvXMLImportPropertyMapper * CreateParaExtPropMapper(SvXMLImport &)
Definition: txtimp.cxx:560
static SvXMLImportPropertyMapper * CreateTableCellExtPropMapper(SvXMLImport &)
Definition: txtimp.cxx:599
int nCount
#define TOOLS_WARN_EXCEPTION(area, stream)
Reference< XSingleServiceFactory > xFactory
XmlStyleFamily
Definition: families.hxx:50
sal_Int32 nIndex
#define SAL_WARN(area, stream)
@ Exception
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
int i
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
OUString toString(OptionInfo const *info)
Handling of tokens in XML:
@ XML_COVERED_TABLE_CELL
Definition: xmltoken.hxx:539
@ XML_DEFAULT_CELL_STYLE_NAME
Definition: xmltoken.hxx:650
@ XML_NUMBER_COLUMNS_SPANNED
Definition: xmltoken.hxx:1408
@ XML_NUMBER_ROWS_SPANNED
Definition: xmltoken.hxx:1414
@ XML_NUMBER_COLUMNS_REPEATED
Definition: xmltoken.hxx:1407
@ XML_BACKGROUND_COLOR
Definition: xmltoken.hxx:312
bool IsXMLToken(std::u16string_view rString, enum XMLTokenEnum eToken)
compare eToken to the string
Definition: xmltoken.cxx:3583
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Definition: xmltoken.cxx:3527
sal_Int32 toInt32(std::u16string_view rStr)
::xmloff::token::XMLTokenEnum meElement
Definition: table.hxx:28
Smart struct to transport an Any with an index to the appropriate property-name.
Definition: maptype.hxx:140
sal_Int32 mnIndex
Definition: maptype.hxx:141
const XMLPropertyMapEntry * getColumnPropertiesMap()
const TableStyleElement * getTableStyleMap()
const TableStyleElement * getWriterSpecificTableStyleMap()
const XMLPropertyMapEntry * getRowPropertiesMap()
const XMLPropertyMapEntry * getCellPropertiesMap()
sal_Int32 mnColSpan
sal_Int32 mnRowSpan
TABLE
#define XMLOFF_WARN_UNKNOWN_ELEMENT(area, token)
Definition: xmlictxt.hxx:120
#define XMLOFF_WARN_UNKNOWN(area, rIter)
Definition: xmlictxt.hxx:114
#define XML_ELEMENT(prefix, name)
Definition: xmlimp.hxx:98
constexpr bool IsTokenInNamespace(sal_Int32 nToken, sal_uInt16 nNamespacePrefix)
Definition: xmlimp.hxx:105
constexpr sal_Int32 TOKEN_MASK
Definition: xmlimp.hxx:95
constexpr sal_uInt16 XML_NAMESPACE_DRAW
constexpr sal_uInt16 XML_NAMESPACE_TABLE
constexpr sal_uInt16 XML_NAMESPACE_LO_EXT