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