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