xref: /trunk/main/xmloff/source/table/XMLTableImport.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmloff.hxx"
30 
31 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
32 #include <com/sun/star/table/XTableRows.hpp>
33 #include <com/sun/star/table/XMergeableCell.hpp>
34 #include <com/sun/star/table/XMergeableCellRange.hpp>
35 #include <com/sun/star/table/XTable.hpp>
36 #include <com/sun/star/text/XText.hpp>
37 #include <com/sun/star/container/XNameContainer.hpp>
38 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
39 
40 #include "xmloff/table/XMLTableImport.hxx"
41 #include "xmloff/xmltkmap.hxx"
42 #include "xmloff/maptype.hxx"
43 #include "xmloff/xmlprmap.hxx"
44 #include "xmloff/txtimp.hxx"
45 #include "xmloff/xmlimp.hxx"
46 #include "xmloff/nmspmap.hxx"
47 #include "xmloff/xmlstyle.hxx"
48 #include "xmloff/prstylei.hxx"
49 #include "xmloff/xmlimp.hxx"
50 
51 #include "xmloff/xmlnmspe.hxx"
52 #include "table.hxx"
53 
54 #include <boost/shared_ptr.hpp>
55 
56 // --------------------------------------------------------------------
57 
58 using ::rtl::OUString;
59 using namespace ::xmloff::token;
60 using namespace ::com::sun::star::beans;
61 using namespace ::com::sun::star::uno;
62 using namespace ::com::sun::star::table;
63 using namespace ::com::sun::star::xml::sax;
64 using namespace ::com::sun::star::text;
65 using namespace ::com::sun::star::style;
66 using namespace ::com::sun::star::lang;
67 using namespace ::com::sun::star::container;
68 
69 // --------------------------------------------------------------------
70 
71 struct ColumnInfo
72 {
73     OUString msStyleName;
74     sal_Bool mbVisibility;
75     OUString msDefaultCellStyleName;
76 };
77 
78 // --------------------------------------------------------------------
79 
80 class XMLProxyContext : public SvXMLImportContext
81 {
82 public:
83     XMLProxyContext( SvXMLImport& rImport, const SvXMLImportContextRef& xParent, sal_uInt16 nPrfx, const OUString& rLName );
84 
85     virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList );
86 
87 private:
88     SvXMLImportContextRef mxParent;
89 };
90 
91 // --------------------------------------------------------------------
92 
93 struct MergeInfo
94 {
95     sal_Int32 mnStartColumn;
96     sal_Int32 mnStartRow;
97     sal_Int32 mnEndColumn;
98     sal_Int32 mnEndRow;
99 
100     MergeInfo( sal_Int32 nStartColumn, sal_Int32 nStartRow, sal_Int32 nColumnSpan, sal_Int32 nRowSpan )
101         : mnStartColumn( nStartColumn ), mnStartRow( nStartRow ), mnEndColumn( nStartColumn + nColumnSpan - 1 ), mnEndRow( nStartRow + nRowSpan - 1 ) {};
102 };
103 
104 typedef std::vector< boost::shared_ptr< MergeInfo > > MergeInfoVector;
105 
106 // --------------------------------------------------------------------
107 
108 class XMLTableImportContext : public SvXMLImportContext
109 {
110 public:
111     XMLTableImportContext( const rtl::Reference< XMLTableImport >& xThis, sal_uInt16 nPrfx, const OUString& rLName, Reference< XColumnRowRange >& xColumnRowRange );
112     virtual ~XMLTableImportContext();
113 
114     virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList );
115 
116     virtual void StartElement( const Reference< XAttributeList >& xAttrList );
117 
118     virtual void EndElement();
119 
120     void InitColumns();
121 
122     SvXMLImportContext * ImportColumn( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList );
123     SvXMLImportContext * ImportRow( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList );
124     SvXMLImportContext * ImportCell( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList );
125 
126     OUString GetDefaultCellStyleName() const;
127 
128     rtl::Reference< XMLTableImport > mxTableImporter;
129     ::com::sun::star::uno::Reference< ::com::sun::star::table::XTable > mxTable;
130     Reference< XTableColumns > mxColumns;
131     Reference< XTableRows > mxRows;
132 
133     std::vector< boost::shared_ptr< ColumnInfo > > maColumnInfos;
134     sal_Int32 mnCurrentRow;
135     sal_Int32 mnCurrentColumn;
136 
137     // default cell style name for the current row
138     OUString msDefaultCellStyleName;
139 
140     MergeInfoVector maMergeInfos;
141 };
142 
143 // --------------------------------------------------------------------
144 
145 class XMLCellImportContext : public SvXMLImportContext
146 {
147 public:
148     XMLCellImportContext( SvXMLImport& rImport,
149                           const Reference< XMergeableCell >& xCell,
150                           const OUString& sDefaultCellStyleName,
151                           sal_uInt16 nPrfx, const OUString& rLName,
152                           const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList );
153 
154     virtual ~XMLCellImportContext();
155 
156     virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList );
157 
158     virtual void EndElement();
159 
160     sal_Int32 getColumnSpan() const { return mnColSpan; }
161     sal_Int32 getRowSpan() const { return mnRowSpan; }
162     sal_Int32 getRepeated() const { return mnRepeated; }
163 
164     Reference< XMergeableCell > mxCell;
165     Reference< XTextCursor >    mxCursor;
166     Reference< XTextCursor >    mxOldCursor;
167     bool                        mbListContextPushed;
168 
169     sal_Int32 mnColSpan, mnRowSpan, mnRepeated;
170 };
171 
172 // --------------------------------------------------------------------
173 
174 class XMLTableTemplateContext : public SvXMLStyleContext
175 {
176 public:
177     XMLTableTemplateContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName, const Reference< XAttributeList >& xAttrList );
178 
179     virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList );
180 
181     virtual void StartElement( const Reference< XAttributeList >& xAttrList );
182 
183     virtual void EndElement();
184 
185 private:
186     XMLTableTemplate maTableTemplate;
187     OUString msTemplateStyleName;
188 };
189 
190 // --------------------------------------------------------------------
191 // class XMLProxyContext
192 // --------------------------------------------------------------------
193 
194 XMLProxyContext::XMLProxyContext( SvXMLImport& rImport, const SvXMLImportContextRef& xParent, sal_uInt16 nPrfx, const OUString& rLName )
195 : SvXMLImportContext( rImport, nPrfx, rLName )
196 , mxParent( xParent )
197 {
198 }
199 
200 // --------------------------------------------------------------------
201 
202 SvXMLImportContext * XMLProxyContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
203 {
204     if( mxParent.Is() )
205         return mxParent->CreateChildContext( nPrefix, rLocalName, xAttrList );
206     else
207         return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
208 }
209 
210 // --------------------------------------------------------------------
211 // class XMLTableImport
212 // --------------------------------------------------------------------
213 
214 XMLTableImport::XMLTableImport( SvXMLImport& rImport, const rtl::Reference< XMLPropertySetMapper >& xCellPropertySetMapper, const rtl::Reference< XMLPropertyHandlerFactory >& xFactoryRef )
215 : mrImport( rImport )
216 {
217     mxCellImportPropertySetMapper = new SvXMLImportPropertyMapper( xCellPropertySetMapper.get(), rImport );
218     mxCellImportPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(rImport));
219 
220 
221     UniReference < XMLPropertySetMapper > xRowMapper( new XMLPropertySetMapper( getRowPropertiesMap(), xFactoryRef.get() ) );
222     mxRowImportPropertySetMapper = new SvXMLImportPropertyMapper( xRowMapper, rImport );
223 
224     UniReference < XMLPropertySetMapper > xColMapper( new XMLPropertySetMapper( getColumnPropertiesMap(), xFactoryRef.get() ) );
225     mxColumnImportPropertySetMapper = new SvXMLImportPropertyMapper( xColMapper, rImport );
226 }
227 
228 // --------------------------------------------------------------------
229 
230 XMLTableImport::~XMLTableImport()
231 {
232 }
233 
234 // --------------------------------------------------------------------
235 
236 SvXMLImportContext* XMLTableImport::CreateTableContext( sal_uInt16 nPrfx, const OUString& rLName, Reference< XColumnRowRange >& xColumnRowRange )
237 {
238     rtl::Reference< XMLTableImport > xThis( this );
239     return new XMLTableImportContext( xThis, nPrfx, rLName, xColumnRowRange );
240 }
241 
242 // --------------------------------------------------------------------
243 
244 SvXMLStyleContext* XMLTableImport::CreateTableTemplateContext( sal_uInt16 nPrfx, const OUString& rLName, const Reference< XAttributeList >& xAttrList )
245 {
246     return new XMLTableTemplateContext( mrImport, nPrfx, rLName, xAttrList );
247 }
248 
249 // --------------------------------------------------------------------
250 
251 void XMLTableImport::addTableTemplate( const rtl::OUString& rsStyleName, XMLTableTemplate& xTableTemplate )
252 {
253     boost::shared_ptr< XMLTableTemplate > xPtr( new XMLTableTemplate );
254     xPtr->swap( xTableTemplate );
255     maTableTemplates[rsStyleName] = xPtr;
256 }
257 
258 // --------------------------------------------------------------------
259 
260 void XMLTableImport::finishStyles()
261 {
262     if( !maTableTemplates.empty() ) try
263     {
264         Reference< XStyleFamiliesSupplier > xFamiliesSupp( mrImport.GetModel(), UNO_QUERY_THROW );
265         Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
266         const OUString sFamilyName( RTL_CONSTASCII_USTRINGPARAM("table" ) );
267         const OUString sCellFamilyName( RTL_CONSTASCII_USTRINGPARAM("cell") );
268 
269         Reference< XNameContainer > xTableFamily( xFamilies->getByName( sFamilyName ), UNO_QUERY_THROW );
270         Reference< XNameAccess > xCellFamily( xFamilies->getByName( sCellFamilyName ), UNO_QUERY_THROW );
271 
272         Reference< XSingleServiceFactory > xFactory( xTableFamily, UNO_QUERY_THROW );
273 
274         for( XMLTableTemplateMap::iterator aTemplateIter( maTableTemplates.begin() ); aTemplateIter != maTableTemplates.end(); aTemplateIter++ ) try
275         {
276             const OUString sTemplateName( (*aTemplateIter).first );
277             Reference< XNameReplace > xTemplate( xFactory->createInstance(), UNO_QUERY_THROW );
278 
279             boost::shared_ptr< XMLTableTemplate > xT( (*aTemplateIter).second );
280 
281             for( XMLTableTemplate::iterator aStyleIter( xT->begin() ); aStyleIter != xT->end(); aStyleIter++ ) try
282             {
283                 const OUString sPropName( (*aStyleIter).first );
284                 const OUString sStyleName( (*aStyleIter).second );
285                 xTemplate->replaceByName( sPropName, xCellFamily->getByName( sStyleName ) );
286             }
287             catch( Exception& )
288             {
289                 DBG_ERROR("xmloff::XMLTableImport::finishStyles(), exception caught!");
290             }
291 
292             if( xTemplate.is() )
293             {
294                 if( xTableFamily->hasByName( sTemplateName ) )
295                     xTableFamily->replaceByName( sTemplateName, Any( xTemplate ) );
296                 else
297                     xTableFamily->insertByName( sTemplateName, Any( xTemplate ) );
298             }
299 
300         }
301         catch( Exception& )
302         {
303             DBG_ERROR("xmloff::XMLTableImport::finishStyles(), exception caught!");
304         }
305     }
306     catch( Exception& )
307     {
308         DBG_ERROR("xmloff::XMLTableImport::finishStyles(), exception caught!");
309     }
310 }
311 
312 // --------------------------------------------------------------------
313 // class XMLTableImport
314 // --------------------------------------------------------------------
315 
316 
317 XMLTableImportContext::XMLTableImportContext( const rtl::Reference< XMLTableImport >& xImporter, sal_uInt16 nPrfx, const OUString& rLName,  Reference< XColumnRowRange >& xColumnRowRange )
318 : SvXMLImportContext( xImporter->mrImport, nPrfx, rLName )
319 , mxTableImporter( xImporter )
320 , mxTable( xColumnRowRange, UNO_QUERY )
321 , mxColumns( xColumnRowRange->getColumns() )
322 , mxRows( xColumnRowRange->getRows() )
323 , mnCurrentRow( -1 )
324 , mnCurrentColumn( -1 )
325 {
326 }
327 
328 // --------------------------------------------------------------------
329 
330 XMLTableImportContext::~XMLTableImportContext()
331 {
332 }
333 
334 // --------------------------------------------------------------------
335 
336 SvXMLImportContext * XMLTableImportContext::ImportColumn( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
337 {
338     if( mxColumns.is() && (mnCurrentRow == -1) ) try
339     {
340         boost::shared_ptr< ColumnInfo > xInfo ( new ColumnInfo );
341 
342         sal_Int32 nRepeated = 1;
343 
344         // read attributes for the table-column
345         sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
346         for(sal_Int16 i=0; i < nAttrCount; i++)
347         {
348             const OUString sAttrName( xAttrList->getNameByIndex( i ) );
349             const OUString sValue( xAttrList->getValueByIndex( i ) );
350             OUString aLocalName;
351 
352             sal_uInt16 nPrefix2 = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
353             if( XML_NAMESPACE_TABLE == nPrefix2 )
354             {
355                 if( IsXMLToken( aLocalName, XML_NUMBER_COLUMNS_REPEATED ) )
356                 {
357                     nRepeated = sValue.toInt32();
358                 }
359                 else if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
360                 {
361                     xInfo->msStyleName = sValue;
362                 }
363                 else if( IsXMLToken( aLocalName, XML_DEFAULT_CELL_STYLE_NAME ) )
364                 {
365                     xInfo->msDefaultCellStyleName = sValue;
366                 }
367                 else if( IsXMLToken( aLocalName, XML_VISIBILITY ) )
368                 {
369                     xInfo->mbVisibility = IsXMLToken( sValue, XML_VISIBLE );
370                 }
371             }
372             else if ( (XML_NAMESPACE_XML == nPrefix2) &&
373                  IsXMLToken(aLocalName, XML_ID)   )
374             {
375                 (void) sValue;
376 //FIXME: TODO
377             }
378         }
379 
380         if( nRepeated <= 1 )
381         {
382             maColumnInfos.push_back( xInfo );
383         }
384         else
385         {
386             maColumnInfos.insert( maColumnInfos.end(), nRepeated, xInfo );
387         }
388     }
389     catch( Exception& )
390     {
391         DBG_ERROR("xmloff::XMLTableImportContext::ImportTableColumn(), exception caught!");
392     }
393 
394     return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList);
395 }
396 
397 // --------------------------------------------------------------------
398 
399 void XMLTableImportContext::InitColumns()
400 {
401     if( mxColumns.is() ) try
402     {
403         const sal_Int32 nCount1 = mxColumns->getCount();
404         const sal_Int32 nCount2 = sal::static_int_cast< sal_Int32 >( maColumnInfos.size() );
405         if( nCount1 < nCount2 )
406             mxColumns->insertByIndex( nCount1, nCount2 - nCount1 );
407 
408         SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
409 
410         for( sal_Int32 nCol = 0; nCol < nCount2; nCol++ )
411         {
412             boost::shared_ptr< ColumnInfo > xInfo( maColumnInfos[nCol] );
413 
414             if( pAutoStyles && xInfo->msStyleName.getLength() )
415             {
416                 const XMLPropStyleContext* pStyle =
417                     dynamic_cast< const XMLPropStyleContext* >(
418                         pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_TABLE_COLUMN, xInfo->msStyleName) );
419 
420                 if( pStyle )
421                 {
422                     Reference< XPropertySet > xColProps( mxColumns->getByIndex(nCol), UNO_QUERY_THROW );
423                     const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xColProps );
424                 }
425             }
426 
427         }
428     }
429     catch( Exception& )
430     {
431         DBG_ERROR("xmloff::XMLTableImportContext::ImportTableColumn(), exception caught!");
432     }
433 }
434 
435 // --------------------------------------------------------------------
436 
437 SvXMLImportContext * XMLTableImportContext::ImportRow( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
438 {
439     if( mxRows.is() )
440     {
441         mnCurrentRow++;
442         if( mnCurrentRow == 0 )
443             InitColumns();      // first init columns
444 
445         mnCurrentColumn = -1;
446 
447         const sal_Int32 nRowCount = mxRows->getCount();
448         if( ( nRowCount - 1) < mnCurrentRow )
449         {
450             const sal_Int32 nCount = mnCurrentRow - nRowCount + 1;
451             mxRows->insertByIndex( nRowCount, nCount );
452         }
453 
454         Reference< XPropertySet > xRowSet( mxRows->getByIndex(mnCurrentRow), UNO_QUERY );
455 
456         sal_Int32 nRepeated = 1;
457         OUString sStyleName;
458         sal_Bool bVisibility = sal_True;
459 
460         // read attributes for the table-row
461         sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
462         for(sal_Int16 i=0; i < nAttrCount; i++)
463         {
464             const OUString sAttrName( xAttrList->getNameByIndex( i ) );
465             const OUString sValue( xAttrList->getValueByIndex( i ) );
466             OUString aLocalName;
467 
468             sal_uInt16 nPrefix2 = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
469             if( nPrefix2 == XML_NAMESPACE_TABLE )
470             {
471                 if( IsXMLToken( aLocalName, XML_NUMBER_ROWS_REPEATED ) )
472                 {
473                     nRepeated = sValue.toInt32();
474                 }
475                 else if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
476                 {
477                     sStyleName = sValue;
478                 }
479                 else if( IsXMLToken( aLocalName, XML_DEFAULT_CELL_STYLE_NAME ) )
480                 {
481                     msDefaultCellStyleName = sValue;
482                 }
483                 else if( IsXMLToken( aLocalName, XML_VISIBILITY ) )
484                 {
485                     bVisibility = IsXMLToken( sValue, XML_VISIBLE );
486                 }
487             }
488             else if ( (XML_NAMESPACE_XML == nPrefix2) &&
489                  IsXMLToken(aLocalName, XML_ID)   )
490             {
491                 (void) sValue;
492 //FIXME: TODO
493             }
494         }
495 
496         if( sStyleName.getLength() )
497         {
498             SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
499             if( pAutoStyles )
500             {
501                 const XMLPropStyleContext* pStyle =
502                     dynamic_cast< const XMLPropStyleContext* >(
503                         pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_TABLE_ROW, sStyleName) );
504 
505                 if( pStyle )
506                 {
507                     const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xRowSet );
508                 }
509             }
510         }
511     }
512 
513     SvXMLImportContextRef xThis( this );
514     return new XMLProxyContext( GetImport(), xThis, nPrefix, rLocalName );
515 }
516 
517 // --------------------------------------------------------------------
518 
519 SvXMLImportContext * XMLTableImportContext::ImportCell( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
520 {
521     mnCurrentColumn++;
522     if( mxColumns.is() ) try
523     {
524         if( mxColumns->getCount() <= mnCurrentColumn )
525             mxColumns->insertByIndex( mxColumns->getCount(), mnCurrentColumn - mxColumns->getCount() + 1 );
526 
527         Reference< XMergeableCell > xCell( mxTable->getCellByPosition( mnCurrentColumn, mnCurrentRow ), UNO_QUERY_THROW );
528         XMLCellImportContext* pCellContext = new XMLCellImportContext( GetImport(), xCell, GetDefaultCellStyleName(), nPrefix, rLocalName, xAttrList );
529 
530         const sal_Int32 nColumnSpan = pCellContext->getColumnSpan();
531         const sal_Int32 nRowSpan = pCellContext->getRowSpan();
532         if( (nColumnSpan > 1) || (nRowSpan > 1) )
533             maMergeInfos.push_back( boost::shared_ptr< MergeInfo >( new MergeInfo( mnCurrentColumn, mnCurrentRow, nColumnSpan, nRowSpan ) ) );
534 
535         const sal_Int32 nRepeated = pCellContext->getRepeated();
536         if( nRepeated > 1 )
537         {
538             DBG_ERROR("xmloff::XMLTableImportContext::ImportCell(), import of repeated Cells not implemented (TODO)");
539             mnCurrentColumn  += nRepeated - 1;
540         }
541 
542         return pCellContext;
543     }
544     catch( Exception& )
545     {
546         DBG_ERROR("xmloff::XMLTableImportContext::ImportCell(), exception caught!");
547     }
548 
549     return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList);
550 }
551 
552 // --------------------------------------------------------------------
553 
554 SvXMLImportContext *XMLTableImportContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
555 {
556     if( nPrefix == XML_NAMESPACE_TABLE )
557     {
558         if( IsXMLToken( rLocalName, XML_TABLE_COLUMN ) )
559             return ImportColumn( nPrefix, rLocalName, xAttrList );
560         else if( IsXMLToken( rLocalName, XML_TABLE_ROW ) )
561             return ImportRow( nPrefix, rLocalName, xAttrList );
562         else if( IsXMLToken( rLocalName, XML_TABLE_CELL ) || IsXMLToken( rLocalName, XML_COVERED_TABLE_CELL ) )
563             return ImportCell( nPrefix, rLocalName, xAttrList );
564         else if( IsXMLToken( rLocalName, XML_TABLE_COLUMNS ) || IsXMLToken( rLocalName, XML_TABLE_ROWS ) )
565         {
566             SvXMLImportContextRef xThis( this );
567             return new XMLProxyContext( GetImport(), xThis, nPrefix, rLocalName );
568         }
569     }
570 
571     return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList);
572 }
573 
574 // --------------------------------------------------------------------
575 
576 void XMLTableImportContext::StartElement( const Reference< XAttributeList >& /*xAttrList*/ )
577 {
578 }
579 
580 // --------------------------------------------------------------------
581 
582 void XMLTableImportContext::EndElement()
583 {
584     if( !maMergeInfos.empty() )
585     {
586         MergeInfoVector::iterator aIter( maMergeInfos.begin() );
587         while( aIter != maMergeInfos.end() )
588         {
589             boost::shared_ptr< MergeInfo > xInfo( (*aIter++) );
590 
591             if( xInfo.get() ) try
592             {
593                 Reference< XCellRange > xRange( mxTable->getCellRangeByPosition( xInfo->mnStartColumn, xInfo->mnStartRow, xInfo->mnEndColumn, xInfo->mnEndRow ) );
594                 Reference< XMergeableCellRange > xCursor( mxTable->createCursorByRange( xRange ), UNO_QUERY_THROW );
595                 xCursor->merge();
596             }
597             catch( Exception& )
598             {
599                 DBG_ERROR("XMLTableImportContext::EndElement(), exception caught while merging cells!");
600             }
601         }
602     }
603 }
604 
605 // --------------------------------------------------------------------
606 
607 OUString XMLTableImportContext::GetDefaultCellStyleName() const
608 {
609     OUString sStyleName( msDefaultCellStyleName );
610 
611     // if there is still no style name, try default style name from column
612     if( (sStyleName.getLength() == 0) && (mnCurrentColumn < sal::static_int_cast<sal_Int32>(maColumnInfos.size())) )
613         sStyleName = maColumnInfos[mnCurrentColumn]->msDefaultCellStyleName;
614 
615     return sStyleName;
616 }
617 
618 // --------------------------------------------------------------------
619 // XMLCellImportContext
620 // --------------------------------------------------------------------
621 
622 XMLCellImportContext::XMLCellImportContext( SvXMLImport& rImport, const Reference< XMergeableCell >& xCell, const OUString& sDefaultCellStyleName, sal_uInt16 nPrfx, const OUString& rLName, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList )
623 : SvXMLImportContext( rImport, nPrfx, rLName )
624 , mxCell( xCell )
625 , mbListContextPushed( false )
626 , mnColSpan( 1 )
627 , mnRowSpan( 1 )
628 , mnRepeated( 1 )
629 {
630     OUString sStyleName;
631 
632     // read attributes for the table-cell
633     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
634     for(sal_Int16 i=0; i < nAttrCount; i++)
635     {
636         const OUString sAttrName( xAttrList->getNameByIndex( i ) );
637         const OUString sValue( xAttrList->getValueByIndex( i ) );
638         OUString aLocalName;
639 
640         sal_uInt16 nPrefix2 = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
641         if( XML_NAMESPACE_TABLE == nPrefix2 )
642         {
643             if( IsXMLToken( aLocalName, XML_NUMBER_COLUMNS_REPEATED ) )
644             {
645                 mnRepeated = sValue.toInt32();
646             }
647             else if( IsXMLToken( aLocalName, XML_NUMBER_COLUMNS_SPANNED ) )
648             {
649                 mnColSpan = sValue.toInt32();
650             }
651             else if( IsXMLToken( aLocalName, XML_NUMBER_ROWS_SPANNED ) )
652             {
653                 mnRowSpan = sValue.toInt32();
654             }
655             else if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
656             {
657                 sStyleName = sValue;
658             }
659         }
660         else if ( (XML_NAMESPACE_XML == nPrefix2) &&
661              IsXMLToken(aLocalName, XML_ID)   )
662         {
663             (void) sValue;
664 //FIXME: TODO
665         }
666 //FIXME: RDFa (table:table-cell)
667     }
668 
669     // if there is no style name at the cell, try default style name from row
670     if( sStyleName.getLength() == 0 )
671         sStyleName = sDefaultCellStyleName;
672 
673     if( sStyleName.getLength() )
674     {
675         SvXMLStylesContext * pAutoStyles = GetImport().GetShapeImport()->GetAutoStylesContext();
676         if( pAutoStyles )
677         {
678             const XMLPropStyleContext* pStyle =
679                 dynamic_cast< const XMLPropStyleContext* >(
680                     pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_TABLE_CELL, sStyleName) );
681 
682             if( pStyle )
683             {
684                 Reference< XPropertySet > xCellSet( mxCell, UNO_QUERY );
685                 if( xCellSet.is() )
686                     const_cast< XMLPropStyleContext* >( pStyle )->FillPropertySet( xCellSet );
687             }
688         }
689     }
690 }
691 
692 // --------------------------------------------------------------------
693 
694 XMLCellImportContext::~XMLCellImportContext()
695 {
696 }
697 
698 // --------------------------------------------------------------------
699 
700 SvXMLImportContext * XMLCellImportContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
701 {
702     // create text cursor on demand
703     if( !mxCursor.is() )
704     {
705         Reference< XText > xText( mxCell, UNO_QUERY );
706         if( xText.is() )
707         {
708             UniReference < XMLTextImportHelper > xTxtImport( GetImport().GetTextImport() );
709             mxOldCursor = xTxtImport->GetCursor();
710             mxCursor = xText->createTextCursor();
711             if( mxCursor.is() )
712                 xTxtImport->SetCursor( mxCursor );
713 
714             // remember old list item and block (#91964#) and reset them
715             // for the text frame
716             xTxtImport->PushListContext();
717             mbListContextPushed = true;
718         }
719     }
720 
721     SvXMLImportContext * pContext = 0;
722 
723     // if we have a text cursor, lets  try to import some text
724     if( mxCursor.is() )
725     {
726         pContext = GetImport().GetTextImport()->CreateTextChildContext( GetImport(), nPrefix, rLocalName, xAttrList );
727     }
728 
729     if( pContext )
730         return pContext;
731     else
732         return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList);
733 }
734 
735 // --------------------------------------------------------------------
736 
737 // --------------------------------------------------------------------
738 
739 void XMLCellImportContext::EndElement()
740 {
741     if(mxCursor.is())
742     {
743         // delete addition newline
744         const OUString aEmpty;
745         mxCursor->gotoEnd( sal_False );
746         mxCursor->goLeft( 1, sal_True );
747         mxCursor->setString( aEmpty );
748 
749         // reset cursor
750         GetImport().GetTextImport()->ResetCursor();
751     }
752 
753     if(mxOldCursor.is())
754         GetImport().GetTextImport()->SetCursor( mxOldCursor );
755 
756     // reinstall old list item (if necessary) #91964#
757     if (mbListContextPushed) {
758         GetImport().GetTextImport()->PopListContext();
759     }
760 }
761 
762 // --------------------------------------------------------------------
763 // class XMLTableTemplateContext
764 // --------------------------------------------------------------------
765 
766 XMLTableTemplateContext::XMLTableTemplateContext( SvXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName, const Reference< XAttributeList >& xAttrList )
767 : SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList, XML_STYLE_FAMILY_TABLE_TEMPLATE_ID, sal_False )
768 {
769 }
770 
771 // --------------------------------------------------------------------
772 
773 void XMLTableTemplateContext::StartElement( const Reference< XAttributeList >& xAttrList )
774 {
775     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
776     for(sal_Int16 i=0; i < nAttrCount; i++)
777     {
778         OUString sAttrName;
779         sal_uInt16 nAttrPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( i ), &sAttrName );
780         if( (nAttrPrefix == XML_NAMESPACE_TEXT ) && IsXMLToken( sAttrName, XML_STYLE_NAME ) )
781         {
782             msTemplateStyleName = xAttrList->getValueByIndex( i );
783             break;
784         }
785     }
786 }
787 
788 // --------------------------------------------------------------------
789 
790 void XMLTableTemplateContext::EndElement()
791 {
792     rtl::Reference< XMLTableImport > xTableImport( GetImport().GetShapeImport()->GetShapeTableImport() );
793     if( xTableImport.is() )
794         xTableImport->addTableTemplate( msTemplateStyleName, maTableTemplate );
795 }
796 
797 // --------------------------------------------------------------------
798 
799 SvXMLImportContext * XMLTableTemplateContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList )
800 {
801     if( nPrefix == XML_NAMESPACE_TABLE )
802     {
803         const TableStyleElement* pElements = getTableStyleMap();
804         while( (pElements->meElement != XML_TOKEN_END) && !IsXMLToken( rLocalName, pElements->meElement ) )
805             pElements++;
806 
807         if( pElements->meElement != XML_TOKEN_END )
808         {
809             sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
810             for(sal_Int16 i=0; i < nAttrCount; i++)
811             {
812                 OUString sAttrName;
813                 sal_uInt16 nAttrPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( i ), &sAttrName );
814                 if( (nAttrPrefix == XML_NAMESPACE_TEXT) && IsXMLToken( sAttrName, XML_STYLE_NAME ) )
815                 {
816                     maTableTemplate[pElements->msStyleName] = xAttrList->getValueByIndex( i );
817                     break;
818                 }
819             }
820         }
821     }
822 
823     return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
824 }
825 
826 // --------------------------------------------------------------------
827