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