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