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