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