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