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