1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23 #include <DomainMapperTableHandler.hxx>
24 #include <DomainMapper_Impl.hxx>
25 #include <StyleSheetTable.hxx>
26 #include <com/sun/star/table/TableBorderDistances.hpp>
27 #include <com/sun/star/table/TableBorder.hpp>
28 #include <com/sun/star/text/HoriOrientation.hpp>
29 #include <dmapperLoggers.hxx>
30
31 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
32 #include <PropertyMapHelper.hxx>
33 #endif
34
35 namespace writerfilter {
36 namespace dmapper {
37
38 using namespace ::com::sun::star;
39 using namespace ::std;
40
41 #define DEF_BORDER_DIST 190 //0,19cm
42 #define DEFAULT_CELL_MARGIN 108 //default cell margin, not documented
43
44 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
lcl_printProperties(PropertyMapPtr pProps)45 static void lcl_printProperties( PropertyMapPtr pProps )
46 {
47 if( pProps.get() )
48 {
49 dmapper_logger->startElement("properties");
50
51 PropertyMap::const_iterator aMapIter = pProps->begin();
52 PropertyMap::const_iterator aEndIter = pProps->end();
53 PropertyNameSupplier& rPropSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
54 for( ; aMapIter != aEndIter; ++aMapIter )
55 {
56 rtl::OUString aOUStr = rPropSupplier.GetName( aMapIter->first.eId );
57 rtl::OString aOStr(aOUStr.getStr(), aOUStr.getLength(), RTL_TEXTENCODING_ASCII_US );
58 clog << aOStr.getStr();
59
60 table::BorderLine aLine;
61 sal_Int32 nColor;
62 if ( aMapIter->second >>= aLine )
63 {
64 dmapper_logger->startElement("borderline");
65 dmapper_logger->attribute("color", aLine.Color);
66 dmapper_logger->attribute("inner", aLine.InnerLineWidth);
67 dmapper_logger->attribute("outer", aLine.OuterLineWidth);
68 dmapper_logger->endElement("borderline");
69 }
70 else if ( aMapIter->second >>= nColor )
71 {
72 dmapper_logger->startElement("color");
73 dmapper_logger->attribute("number", nColor);
74 dmapper_logger->endElement("color");
75 }
76 }
77
78 dmapper_logger->endElement("properties");
79 }
80 }
81 #endif
82
DomainMapperTableHandler(TextReference_t xText,DomainMapper_Impl & rDMapper_Impl)83 DomainMapperTableHandler::DomainMapperTableHandler(TextReference_t xText, DomainMapper_Impl& rDMapper_Impl)
84 : m_xText(xText),
85 m_rDMapper_Impl( rDMapper_Impl ),
86 m_nCellIndex(0),
87 m_nRowIndex(0)
88 {
89 }
90
~DomainMapperTableHandler()91 DomainMapperTableHandler::~DomainMapperTableHandler()
92 {
93 }
94
startTable(unsigned int nRows,unsigned int,TablePropertyMapPtr pProps)95 void DomainMapperTableHandler::startTable(unsigned int nRows,
96 unsigned int /*nDepth*/,
97 TablePropertyMapPtr pProps)
98 {
99 m_aTableProperties = pProps;
100 m_pTableSeq = TableSequencePointer_t(new TableSequence_t(nRows));
101 m_nRowIndex = 0;
102
103 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
104 dmapper_logger->startElement("tablehandler.table");
105 dmapper_logger->attribute("rows", nRows);
106
107 if (pProps.get() != NULL)
108 dmapper_logger->addTag(pProps->toTag());
109 #endif
110 }
111
112 /*-- 22.02.2008 10:18:37---------------------------------------------------
113
114 -----------------------------------------------------------------------*/
lcl_SearchParentStyleSheetAndMergeProperties(const StyleSheetEntryPtr pStyleSheet,StyleSheetTablePtr pStyleSheetTable)115 PropertyMapPtr lcl_SearchParentStyleSheetAndMergeProperties(const StyleSheetEntryPtr pStyleSheet, StyleSheetTablePtr pStyleSheetTable)
116 {
117 PropertyMapPtr pRet;
118 if( pStyleSheet->sBaseStyleIdentifier.getLength())
119 {
120 const StyleSheetEntryPtr pParentStyleSheet = pStyleSheetTable->FindStyleSheetByISTD( pStyleSheet->sBaseStyleIdentifier );
121 pRet = lcl_SearchParentStyleSheetAndMergeProperties( pParentStyleSheet, pStyleSheetTable );
122 }
123 else
124 {
125 pRet.reset( new PropertyMap );
126 }
127
128 pRet->insert( pStyleSheet->pProperties, true );
129
130 return pRet;
131 }
132
lcl_mergeBorder(PropertyIds nId,PropertyMapPtr pOrig,PropertyMapPtr pDest)133 void lcl_mergeBorder( PropertyIds nId, PropertyMapPtr pOrig, PropertyMapPtr pDest )
134 {
135 PropertyDefinition aDef( nId, false );
136 PropertyMap::iterator pOrigIt = pOrig->find( aDef );
137
138 if ( pOrigIt != pOrig->end( ) )
139 {
140 pDest->Insert( nId, false, pOrigIt->second, false );
141 }
142 }
143
lcl_computeCellBorders(PropertyMapPtr pTableBorders,PropertyMapPtr pCellProps,sal_Int32 nCell,sal_Int32 nRow,bool bIsEndCol,bool bIsEndRow)144 void lcl_computeCellBorders( PropertyMapPtr pTableBorders, PropertyMapPtr pCellProps,
145 sal_Int32 nCell, sal_Int32 nRow, bool bIsEndCol, bool bIsEndRow )
146 {
147 PropertyDefinition aVertPDef( META_PROP_VERTICAL_BORDER, false );
148 PropertyDefinition aHorizPDef( META_PROP_HORIZONTAL_BORDER, false );
149
150 PropertyMap::iterator aVerticalIter = pCellProps->find( aVertPDef );
151 PropertyMap::iterator aHorizontalIter = pCellProps->find( aHorizPDef );
152
153 // Handle the vertical and horizontal borders
154 bool bHasVert = ( aVerticalIter != pCellProps->end( ) );
155 uno::Any aVertProp;
156 if ( !bHasVert )
157 {
158 aVerticalIter = pTableBorders->find( aVertPDef );
159 bHasVert = ( aVerticalIter != pTableBorders->end( ) );
160 if ( bHasVert )
161 aVertProp = aVerticalIter->second;
162 }
163 else
164 {
165 aVertProp = aVerticalIter->second;
166 pCellProps->erase( aVerticalIter );
167 }
168
169 bool bHasHoriz = ( aHorizontalIter != pCellProps->end( ) );
170 uno::Any aHorizProp;
171 if ( !bHasHoriz )
172 {
173 aHorizontalIter = pTableBorders->find( aHorizPDef );
174 bHasHoriz = ( aHorizontalIter != pTableBorders->end( ) );
175 if ( bHasHoriz )
176 aHorizProp = aHorizontalIter->second;
177 }
178 else
179 {
180 aHorizProp = aHorizontalIter->second;
181 pCellProps->erase( aHorizontalIter );
182 }
183
184 if ( nCell == 0 )
185 {
186 lcl_mergeBorder( PROP_LEFT_BORDER, pTableBorders, pCellProps );
187 if ( bHasVert )
188 pCellProps->Insert( PROP_RIGHT_BORDER, false, aVertProp, false );
189 }
190
191 if ( bIsEndCol )
192 {
193 lcl_mergeBorder( PROP_RIGHT_BORDER, pTableBorders, pCellProps );
194 if ( bHasVert )
195 pCellProps->Insert( PROP_LEFT_BORDER, false, aVertProp, false );
196 }
197
198 if ( nCell > 0 && !bIsEndCol )
199 {
200 if ( bHasVert )
201 {
202 pCellProps->Insert( PROP_RIGHT_BORDER, false, aVertProp, false );
203 pCellProps->Insert( PROP_LEFT_BORDER, false, aVertProp, false );
204 }
205 }
206
207 if ( nRow == 0 )
208 {
209 lcl_mergeBorder( PROP_TOP_BORDER, pTableBorders, pCellProps );
210 if ( bHasHoriz )
211 pCellProps->Insert( PROP_BOTTOM_BORDER, false, aHorizProp, false );
212 }
213
214 if ( bIsEndRow )
215 {
216 lcl_mergeBorder( PROP_BOTTOM_BORDER, pTableBorders, pCellProps );
217 if ( bHasHoriz )
218 pCellProps->Insert( PROP_TOP_BORDER, false, aHorizProp, false );
219 }
220
221 if ( nRow > 0 && !bIsEndRow )
222 {
223 if ( bHasHoriz )
224 {
225 pCellProps->Insert( PROP_TOP_BORDER, false, aHorizProp, false );
226 pCellProps->Insert( PROP_BOTTOM_BORDER, false, aHorizProp, false );
227 }
228 }
229 }
230
231 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
232
lcl_debug_BorderLine(table::BorderLine & rLine)233 void lcl_debug_BorderLine(table::BorderLine & rLine)
234 {
235 dmapper_logger->startElement("BorderLine");
236 dmapper_logger->attribute("Color", rLine.Color);
237 dmapper_logger->attribute("InnerLineWidth", rLine.InnerLineWidth);
238 dmapper_logger->attribute("OuterLineWidth", rLine.OuterLineWidth);
239 dmapper_logger->attribute("LineDistance", rLine.LineDistance);
240 dmapper_logger->endElement("BorderLine");
241 }
242
lcl_debug_TableBorder(table::TableBorder & rBorder)243 void lcl_debug_TableBorder(table::TableBorder & rBorder)
244 {
245 dmapper_logger->startElement("TableBorder");
246 lcl_debug_BorderLine(rBorder.TopLine);
247 dmapper_logger->attribute("IsTopLineValid", rBorder.IsTopLineValid);
248 lcl_debug_BorderLine(rBorder.BottomLine);
249 dmapper_logger->attribute("IsBottomLineValid", rBorder.IsBottomLineValid);
250 lcl_debug_BorderLine(rBorder.LeftLine);
251 dmapper_logger->attribute("IsLeftLineValid", rBorder.IsLeftLineValid);
252 lcl_debug_BorderLine(rBorder.RightLine);
253 dmapper_logger->attribute("IsRightLineValid", rBorder.IsRightLineValid);
254 lcl_debug_BorderLine(rBorder.VerticalLine);
255 dmapper_logger->attribute("IsVerticalLineValid", rBorder.IsVerticalLineValid);
256 lcl_debug_BorderLine(rBorder.HorizontalLine);
257 dmapper_logger->attribute("IsHorizontalLineValid", rBorder.IsHorizontalLineValid);
258 dmapper_logger->attribute("Distance", rBorder.Distance);
259 dmapper_logger->attribute("IsDistanceValid", rBorder.IsDistanceValid);
260 dmapper_logger->endElement("TableBorder");
261 }
262 #endif
263
264 struct WRITERFILTER_DLLPRIVATE TableInfo
265 {
266 sal_Int32 nLeftBorderDistance;
267 sal_Int32 nRightBorderDistance;
268 sal_Int32 nTopBorderDistance;
269 sal_Int32 nBottomBorderDistance;
270 PropertyMapPtr pTableDefaults;
271 PropertyMapPtr pTableBorders;
272 TableStyleSheetEntry* pTableStyle;
273 TablePropertyValues_t aTableProperties;
274
TableInfowriterfilter::dmapper::TableInfo275 TableInfo()
276 : nLeftBorderDistance(DEF_BORDER_DIST)
277 , nRightBorderDistance(DEF_BORDER_DIST)
278 , nTopBorderDistance(0)
279 , nBottomBorderDistance(0)
280 , pTableDefaults(new PropertyMap)
281 , pTableBorders(new PropertyMap)
282 , pTableStyle(NULL)
283 {
284 }
285
286 };
287
endTableGetTableStyle(TableInfo & rInfo,const bool bAdjustLeftMarginByDefaultValue)288 TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(
289 TableInfo & rInfo,
290 const bool bAdjustLeftMarginByDefaultValue )
291 {
292 // will receive the table style if any
293 TableStyleSheetEntry* pTableStyle = NULL;
294
295 if( m_aTableProperties.get() )
296 {
297 //create properties from the table attributes
298 //...pPropMap->Insert( PROP_LEFT_MARGIN, false, uno::makeAny( m_nLeftMargin - m_nGapHalf ));
299 //pPropMap->Insert( PROP_HORI_ORIENT, false, uno::makeAny( text::HoriOrientation::RIGHT ));
300 sal_Int32 nGapHalf = 0;
301 sal_Int32 nLeftMargin = 0;
302 sal_Int32 nTableWidth = 0;
303
304 PropertyMap::iterator aTableStyleIter =
305 m_aTableProperties->find( PropertyDefinition( META_PROP_TABLE_STYLE_NAME, false ) );
306 if(aTableStyleIter != m_aTableProperties->end())
307 {
308 // Apply table style properties recursively
309 ::rtl::OUString sTableStyleName;
310 aTableStyleIter->second >>= sTableStyleName;
311 StyleSheetTablePtr pStyleSheetTable = m_rDMapper_Impl.GetStyleSheetTable();
312 const StyleSheetEntryPtr pStyleSheet = pStyleSheetTable->FindStyleSheetByISTD( sTableStyleName );
313 pTableStyle = dynamic_cast<TableStyleSheetEntry*>( pStyleSheet.get( ) );
314 m_aTableProperties->erase( aTableStyleIter );
315
316 if( pStyleSheet )
317 {
318 // First get the style properties, then the table ones
319 PropertyMapPtr pTableProps( m_aTableProperties );
320 TablePropertyMapPtr pEmptyProps( new TablePropertyMap );
321
322 m_aTableProperties = pEmptyProps;
323
324 PropertyMapPtr pMergedProperties = lcl_SearchParentStyleSheetAndMergeProperties(pStyleSheet, pStyleSheetTable);
325
326 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
327 dmapper_logger->startElement("mergedProps");
328 dmapper_logger->addTag(pMergedProperties->toTag());
329 dmapper_logger->endElement("mergedProps");
330 #endif
331
332 m_aTableProperties->insert( pMergedProperties );
333 m_aTableProperties->insert( pTableProps );
334
335 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
336 dmapper_logger->startElement("TableProperties");
337 dmapper_logger->addTag(m_aTableProperties->toTag());
338 dmapper_logger->endElement("TableProperties");
339 #endif
340 }
341 }
342
343 // Set the table default attributes for the cells
344 rInfo.pTableDefaults->insert( m_aTableProperties );
345
346 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
347 dmapper_logger->startElement("TableDefaults");
348 dmapper_logger->addTag(rInfo.pTableDefaults->toTag());
349 dmapper_logger->endElement("TableDefaults");
350 #endif
351
352 m_aTableProperties->getValue( TablePropertyMap::GAP_HALF, nGapHalf );
353 m_aTableProperties->getValue( TablePropertyMap::LEFT_MARGIN, nLeftMargin );
354
355 m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_LEFT,
356 rInfo.nLeftBorderDistance );
357 m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_RIGHT,
358 rInfo.nRightBorderDistance );
359 m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_TOP,
360 rInfo.nTopBorderDistance );
361 m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_BOTTOM,
362 rInfo.nBottomBorderDistance );
363
364 table::TableBorderDistances aDistances;
365 aDistances.IsTopDistanceValid =
366 aDistances.IsBottomDistanceValid =
367 aDistances.IsLeftDistanceValid =
368 aDistances.IsRightDistanceValid = sal_True;
369 aDistances.TopDistance = static_cast<sal_Int16>( rInfo.nTopBorderDistance );
370 aDistances.BottomDistance = static_cast<sal_Int16>( rInfo.nBottomBorderDistance );
371 aDistances.LeftDistance = static_cast<sal_Int16>( rInfo.nLeftBorderDistance );
372 aDistances.RightDistance = static_cast<sal_Int16>( rInfo.nRightBorderDistance );
373
374 m_aTableProperties->Insert( PROP_TABLE_BORDER_DISTANCES, false, uno::makeAny( aDistances ) );
375
376 //table border settings
377 table::TableBorder aTableBorder;
378
379 PropertyMap::iterator aTblBorderIter = m_aTableProperties->find( PropertyDefinition(PROP_TOP_BORDER, false) );
380 if( aTblBorderIter != m_aTableProperties->end() )
381 {
382 aTblBorderIter->second >>= aTableBorder.TopLine;
383 aTableBorder.IsTopLineValid = true;
384 m_aTableProperties->erase( aTblBorderIter );
385
386 rInfo.pTableBorders->Insert( PROP_TOP_BORDER, false,
387 uno::makeAny( aTableBorder.TopLine ) );
388 PropertyMap::iterator pIt = rInfo.pTableDefaults->find( PropertyDefinition( PROP_TOP_BORDER, false ) );
389 if ( pIt != rInfo.pTableDefaults->end( ) )
390 rInfo.pTableDefaults->erase( pIt );
391 }
392 aTblBorderIter = m_aTableProperties->find( PropertyDefinition(PROP_BOTTOM_BORDER, false) );
393 if( aTblBorderIter != m_aTableProperties->end() )
394 {
395 aTblBorderIter->second >>= aTableBorder.BottomLine;
396 aTableBorder.IsBottomLineValid = true;
397 m_aTableProperties->erase( aTblBorderIter );
398
399 rInfo.pTableBorders->Insert( PROP_BOTTOM_BORDER, false,
400 uno::makeAny( aTableBorder.BottomLine));
401 PropertyMap::iterator pIt = rInfo.pTableDefaults->find( PropertyDefinition( PROP_BOTTOM_BORDER, false ) );
402 if ( pIt != rInfo.pTableDefaults->end( ) )
403 rInfo.pTableDefaults->erase( pIt );
404 }
405 aTblBorderIter = m_aTableProperties->find( PropertyDefinition(PROP_LEFT_BORDER, false) );
406 if( aTblBorderIter != m_aTableProperties->end() )
407 {
408 aTblBorderIter->second >>= aTableBorder.LeftLine;
409 aTableBorder.IsLeftLineValid = true;
410 m_aTableProperties->erase( aTblBorderIter );
411
412 rInfo.pTableBorders->Insert( PROP_LEFT_BORDER, false,
413 uno::makeAny( aTableBorder.LeftLine ) );
414 PropertyMap::iterator pIt = rInfo.pTableDefaults->find( PropertyDefinition( PROP_LEFT_BORDER, false ) );
415 if ( pIt != rInfo.pTableDefaults->end( ) )
416 rInfo.pTableDefaults->erase( pIt );
417 }
418 aTblBorderIter = m_aTableProperties->find( PropertyDefinition(PROP_RIGHT_BORDER, false) );
419 if( aTblBorderIter != m_aTableProperties->end() )
420 {
421 aTblBorderIter->second >>= aTableBorder.RightLine;
422 aTableBorder.IsRightLineValid = true;
423 m_aTableProperties->erase( aTblBorderIter );
424
425 rInfo.pTableBorders->Insert( PROP_RIGHT_BORDER, false,
426 uno::makeAny( aTableBorder.RightLine ) );
427 PropertyMap::iterator pIt = rInfo.pTableDefaults->find( PropertyDefinition( PROP_RIGHT_BORDER, false ) );
428 if ( pIt != rInfo.pTableDefaults->end( ) )
429 rInfo.pTableDefaults->erase( pIt );
430 }
431 aTblBorderIter = m_aTableProperties->find( PropertyDefinition(META_PROP_HORIZONTAL_BORDER, false) );
432 if( aTblBorderIter != m_aTableProperties->end() )
433 {
434 aTblBorderIter->second >>= aTableBorder.HorizontalLine;
435 aTableBorder.IsHorizontalLineValid = true;
436 m_aTableProperties->erase( aTblBorderIter );
437
438 rInfo.pTableBorders->Insert
439 (META_PROP_HORIZONTAL_BORDER, false,
440 uno::makeAny( aTableBorder.HorizontalLine ) );
441 PropertyMap::iterator pIt = rInfo.pTableDefaults->find( PropertyDefinition( META_PROP_HORIZONTAL_BORDER, false ) );
442 if ( pIt != rInfo.pTableDefaults->end( ) )
443 rInfo.pTableDefaults->erase( pIt );
444 }
445 aTblBorderIter = m_aTableProperties->find( PropertyDefinition(META_PROP_VERTICAL_BORDER, false) );
446 if( aTblBorderIter != m_aTableProperties->end() )
447 {
448 aTblBorderIter->second >>= aTableBorder.VerticalLine;
449 aTableBorder.IsVerticalLineValid = true;
450 m_aTableProperties->erase( aTblBorderIter );
451
452 rInfo.pTableBorders->Insert
453 (META_PROP_VERTICAL_BORDER, false,
454 uno::makeAny( aTableBorder.VerticalLine ) );
455 PropertyMap::iterator pIt = rInfo.pTableDefaults->find( PropertyDefinition( META_PROP_VERTICAL_BORDER, false ) );
456 if ( pIt != rInfo.pTableDefaults->end( ) )
457 rInfo.pTableDefaults->erase( pIt );
458 }
459 aTableBorder.Distance = 0;
460 aTableBorder.IsDistanceValid = false;
461
462 m_aTableProperties->Insert( PROP_TABLE_BORDER, false, uno::makeAny( aTableBorder ) );
463
464 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
465 lcl_debug_TableBorder(aTableBorder);
466 #endif
467
468 m_aTableProperties->Insert(
469 PROP_LEFT_MARGIN,
470 false,
471 uno::makeAny( nLeftMargin - nGapHalf - ( bAdjustLeftMarginByDefaultValue ? rInfo.nLeftBorderDistance : 0 ) ) );
472
473 // no bottom margin - set it explicitly to avoid inheritance from a set dynamic pool default
474 // which might be provided via document default paragraph properties.
475 m_aTableProperties->Insert( PROP_BOTTOM_MARGIN, false, uno::makeAny( (sal_Int32)0 ) );
476
477 m_aTableProperties->getValue( TablePropertyMap::TABLE_WIDTH, nTableWidth );
478 if( nTableWidth > 0 )
479 m_aTableProperties->Insert( PROP_WIDTH, false, uno::makeAny( nTableWidth ));
480
481 sal_Int32 nHoriOrient = text::HoriOrientation::LEFT_AND_WIDTH;
482 m_aTableProperties->getValue( TablePropertyMap::HORI_ORIENT, nHoriOrient ) ;
483 m_aTableProperties->Insert( PROP_HORI_ORIENT, false, uno::makeAny( sal_Int16(nHoriOrient) ) );
484
485 //fill default value - if not available
486 const PropertyMap::const_iterator aRepeatIter =
487 m_aTableProperties->find( PropertyDefinition( PROP_HEADER_ROW_COUNT, false ) );
488 if( aRepeatIter == m_aTableProperties->end() )
489 m_aTableProperties->Insert( PROP_HEADER_ROW_COUNT, false, uno::makeAny( (sal_Int32)0 ));
490
491 // Remove the PROP_HEADER_ROW_COUNT from the table default to avoid
492 // propagating it to the cells
493 PropertyMap::iterator aDefaultRepeatIt =
494 rInfo.pTableDefaults->find( PropertyDefinition( PROP_HEADER_ROW_COUNT, false ) );
495 if ( aDefaultRepeatIt != rInfo.pTableDefaults->end( ) )
496 rInfo.pTableDefaults->erase( aDefaultRepeatIt );
497
498 rInfo.aTableProperties = m_aTableProperties->GetPropertyValues();
499
500 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
501 dmapper_logger->startElement("debug.tableprops");
502 dmapper_logger->addTag(m_aTableProperties->toTag());
503 dmapper_logger->endElement("debug.tableprops");
504 #endif
505
506 }
507
508 return pTableStyle;
509 }
510
endTableGetCellProperties(TableInfo & rInfo)511 CellPropertyValuesSeq_t DomainMapperTableHandler::endTableGetCellProperties(TableInfo & rInfo)
512 {
513 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
514 dmapper_logger->startElement("getCellProperties");
515 #endif
516
517 CellPropertyValuesSeq_t aCellProperties( m_aCellProperties.size() );
518
519 if ( ! m_aCellProperties.empty())
520 {
521
522 // std::vector< std::vector<PropertyMapPtr> > m_aCellProperties
523 PropertyMapVector2::const_iterator aRowOfCellsIterator = m_aCellProperties.begin();
524 PropertyMapVector2::const_iterator aRowOfCellsIteratorEnd = m_aCellProperties.end();
525 PropertyMapVector2::const_iterator aLastRowIterator = m_aCellProperties.end() - 1;
526 sal_Int32 nRow = 0;
527
528 //it's a uno::Sequence< beans::PropertyValues >*
529 RowPropertyValuesSeq_t* pCellProperties = aCellProperties.getArray();
530 while( aRowOfCellsIterator != aRowOfCellsIteratorEnd )
531 {
532 if ( ! aRowOfCellsIterator->empty())
533 {
534 //aRowOfCellsIterator points to a vector of PropertyMapPtr
535 PropertyMapVector1::const_iterator aCellIterator = aRowOfCellsIterator->begin();
536 PropertyMapVector1::const_iterator aCellIteratorEnd = aRowOfCellsIterator->end();
537 PropertyMapVector1::const_iterator aLastCellIterator = aRowOfCellsIterator->end() - 1;
538
539 // Get the row style properties
540 sal_Int32 nRowStyleMask = sal_Int32( 0 );
541 PropertyMapPtr pRowProps = m_aRowProperties[nRow];
542 if ( pRowProps.get( ) )
543 {
544 PropertyMap::iterator pTcCnfStyleIt = pRowProps->find( PropertyDefinition( PROP_CNF_STYLE, true ) );
545 if ( pTcCnfStyleIt != pRowProps->end( ) )
546 {
547 if ( rInfo.pTableStyle )
548 {
549 rtl::OUString sMask;
550 pTcCnfStyleIt->second >>= sMask;
551 nRowStyleMask = sMask.toInt32( 2 );
552 }
553 pRowProps->erase( pTcCnfStyleIt );
554 }
555 }
556
557 sal_Int32 nCell = 0;
558 pCellProperties[nRow].realloc( aRowOfCellsIterator->size() );
559 beans::PropertyValues* pSingleCellProperties = pCellProperties[nRow].getArray();
560 while( aCellIterator != aCellIteratorEnd )
561 {
562 PropertyMapPtr pAllCellProps( new PropertyMap );
563
564 bool bIsEndCol = aCellIterator == aLastCellIterator;
565 bool bIsEndRow = aRowOfCellsIterator == aLastRowIterator;
566
567 //aCellIterator points to a PropertyMapPtr;
568 if( aCellIterator->get() )
569 {
570 if ( rInfo.pTableDefaults->size( ) )
571 pAllCellProps->insert( rInfo.pTableDefaults );
572
573 // Fill the cell properties with the ones of the style
574 sal_Int32 nCellStyleMask = 0;
575 const PropertyMap::iterator aCnfStyleIter =
576 aCellIterator->get()->find( PropertyDefinition( PROP_CNF_STYLE, false ) );
577 if ( aCnfStyleIter != aCellIterator->get( )->end( ) )
578 {
579 if ( rInfo.pTableStyle ) {
580 rtl::OUString sMask;
581 aCnfStyleIter->second >>= sMask;
582 nCellStyleMask = sMask.toInt32( 2 );
583 }
584 aCellIterator->get( )->erase( aCnfStyleIter );
585 }
586
587 if ( rInfo.pTableStyle )
588 {
589 PropertyMapPtr pStyleProps = rInfo.pTableStyle->GetProperties( nCellStyleMask + nRowStyleMask );
590 pAllCellProps->insert( pStyleProps );
591 }
592
593 // Then add the cell properties
594 pAllCellProps->insert( *aCellIterator );
595 aCellIterator->get( )->swap( *pAllCellProps.get( ) );
596
597 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
598 dmapper_logger->startElement("cell");
599 dmapper_logger->attribute("cell", nCell);
600 dmapper_logger->attribute("row", nRow);
601 #endif
602
603 lcl_computeCellBorders( rInfo.pTableBorders, *aCellIterator, nCell, nRow, bIsEndCol, bIsEndRow );
604
605 //now set the default left+right border distance TODO: there's an sprm containing the default distance!
606 const PropertyMap::const_iterator aLeftDistanceIter =
607 aCellIterator->get()->find( PropertyDefinition(PROP_LEFT_BORDER_DISTANCE, false) );
608 if( aLeftDistanceIter == aCellIterator->get()->end() )
609 aCellIterator->get()->Insert( PROP_LEFT_BORDER_DISTANCE, false,
610 uno::makeAny(rInfo.nLeftBorderDistance ) );
611 const PropertyMap::const_iterator aRightDistanceIter =
612 aCellIterator->get()->find( PropertyDefinition(PROP_RIGHT_BORDER_DISTANCE, false) );
613 if( aRightDistanceIter == aCellIterator->get()->end() )
614 aCellIterator->get()->Insert( PROP_RIGHT_BORDER_DISTANCE, false,
615 uno::makeAny((sal_Int32) rInfo.nRightBorderDistance ) );
616
617 const PropertyMap::const_iterator aTopDistanceIter =
618 aCellIterator->get()->find( PropertyDefinition(PROP_TOP_BORDER_DISTANCE, false) );
619 if( aTopDistanceIter == aCellIterator->get()->end() )
620 aCellIterator->get()->Insert( PROP_TOP_BORDER_DISTANCE, false,
621 uno::makeAny((sal_Int32) rInfo.nTopBorderDistance ) );
622
623 const PropertyMap::const_iterator aBottomDistanceIter =
624 aCellIterator->get()->find( PropertyDefinition(PROP_BOTTOM_BORDER_DISTANCE, false) );
625 if( aBottomDistanceIter == aCellIterator->get()->end() )
626 aCellIterator->get()->Insert( PROP_BOTTOM_BORDER_DISTANCE, false,
627 uno::makeAny((sal_Int32) rInfo.nBottomBorderDistance ) );
628
629 pSingleCellProperties[nCell] = aCellIterator->get()->GetPropertyValues();
630 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
631 dmapper_logger->endElement("cell");
632 #endif
633 }
634 ++nCell;
635 ++aCellIterator;
636 }
637 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
638 //-->debug cell properties
639 {
640 ::rtl::OUString sNames;
641 const uno::Sequence< beans::PropertyValues > aDebugCurrentRow = aCellProperties[nRow];
642 sal_Int32 nDebugCells = aDebugCurrentRow.getLength();
643 (void) nDebugCells;
644 for( sal_Int32 nDebugCell = 0; nDebugCell < nDebugCells; ++nDebugCell)
645 {
646 const uno::Sequence< beans::PropertyValue >& aDebugCellProperties = aDebugCurrentRow[nDebugCell];
647 sal_Int32 nDebugCellProperties = aDebugCellProperties.getLength();
648 for( sal_Int32 nDebugProperty = 0; nDebugProperty < nDebugCellProperties; ++nDebugProperty)
649 {
650 const ::rtl::OUString sName = aDebugCellProperties[nDebugProperty].Name;
651 sNames += sName;
652 sNames += ::rtl::OUString('-');
653 }
654 sNames += ::rtl::OUString('\n');
655 }
656 (void)sNames;
657 }
658 //--<
659 #endif
660 ++nRow;
661 ++aRowOfCellsIterator;
662 }
663 }
664 }
665
666 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
667 dmapper_logger->endElement("getCellProperties");
668 #endif
669
670 return aCellProperties;
671 }
672
endTableGetRowProperties()673 RowPropertyValuesSeq_t DomainMapperTableHandler::endTableGetRowProperties()
674 {
675 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
676 dmapper_logger->startElement("getRowProperties");
677 #endif
678
679 RowPropertyValuesSeq_t aRowProperties( m_aRowProperties.size() );
680 PropertyMapVector1::const_iterator aRowIter = m_aRowProperties.begin();
681 PropertyMapVector1::const_iterator aRowIterEnd = m_aRowProperties.end();
682 sal_Int32 nRow = 0;
683 while( aRowIter != aRowIterEnd )
684 {
685 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
686 dmapper_logger->startElement("rowProps.row");
687 #endif
688 if( aRowIter->get() )
689 {
690 //set default to 'break across pages"
691 if( aRowIter->get()->find( PropertyDefinition( PROP_IS_SPLIT_ALLOWED, false )) == aRowIter->get()->end())
692 aRowIter->get()->Insert( PROP_IS_SPLIT_ALLOWED, false, uno::makeAny(sal_True ) );
693
694 aRowProperties[nRow] = (*aRowIter)->GetPropertyValues();
695 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
696 dmapper_logger->addTag((*aRowIter)->toTag());
697 dmapper_logger->addTag(lcl_PropertyValuesToTag(aRowProperties[nRow]));
698 #endif
699 }
700 ++nRow;
701 ++aRowIter;
702 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
703 dmapper_logger->endElement("rowProps.row");
704 #endif
705 }
706
707 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
708 dmapper_logger->endElement("getRowProperties");
709 #endif
710
711 return aRowProperties;
712 }
713
endTable(const unsigned int nDepth)714 void DomainMapperTableHandler::endTable(
715 const unsigned int nDepth )
716 {
717 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
718 dmapper_logger->startElement("tablehandler.endTable");
719 #endif
720
721 TableInfo aTableInfo;
722 // adjust left margin only for tables in the body text, not for sub tables.
723 const bool bAdjustLeftMarginByDefaultValue = (nDepth == 0);
724 aTableInfo.pTableStyle =
725 endTableGetTableStyle( aTableInfo, bAdjustLeftMarginByDefaultValue );
726 // expands to uno::Sequence< Sequence< beans::PropertyValues > >
727
728 CellPropertyValuesSeq_t aCellProperties = endTableGetCellProperties(aTableInfo);
729
730 RowPropertyValuesSeq_t aRowProperties = endTableGetRowProperties();
731
732 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
733 dmapper_logger->addTag(lcl_PropertyValueSeqToTag(aRowProperties));
734 #endif
735
736 if (m_pTableSeq->getLength() > 0)
737 {
738 try
739 {
740 uno::Reference< text::XTextTable > xTable =
741 m_xText->convertToTable(
742 *m_pTableSeq,
743 aCellProperties,
744 aRowProperties,
745 aTableInfo.aTableProperties );
746
747 m_xTableRange = xTable->getAnchor( );
748 }
749 catch (lang::IllegalArgumentException e)
750 {
751 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
752 dmapper_logger->chars("failed to import table!");
753 #endif
754 }
755 catch ( uno::Exception e )
756 {
757 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
758 dmapper_logger->startElement("exception");
759 dmapper_logger->chars(rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr( ));
760 dmapper_logger->endElement("exeception");
761 #endif
762 }
763 }
764
765 m_aTableProperties.reset();
766 m_aCellProperties.clear();
767 m_aRowProperties.clear();
768
769 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
770 dmapper_logger->endElement("tablehandler.endTable");
771 dmapper_logger->endElement("tablehandler.table");
772 #endif
773 }
774
startRow(unsigned int nCells,TablePropertyMapPtr pProps)775 void DomainMapperTableHandler::startRow(unsigned int nCells,
776 TablePropertyMapPtr pProps)
777 {
778 m_aRowProperties.push_back( pProps );
779 m_aCellProperties.push_back( PropertyMapVector1() );
780
781 #if DEBUG_DMAPPER_TABLE_HANDLER
782 dmapper_logger->startElement("table.row");
783 dmapper_logger->attribute("cells", nCells);
784 if (pProps != NULL)
785 dmapper_logger->addTag(pProps->toTag());
786 #endif
787
788 m_pRowSeq = RowSequencePointer_t(new RowSequence_t(nCells));
789 m_nCellIndex = 0;
790 }
791
endRow()792 void DomainMapperTableHandler::endRow()
793 {
794 (*m_pTableSeq)[m_nRowIndex] = *m_pRowSeq;
795 ++m_nRowIndex;
796 m_nCellIndex = 0;
797 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
798 dmapper_logger->endElement("table.row");
799 #endif
800 }
801
startCell(const Handle_t & start,TablePropertyMapPtr pProps)802 void DomainMapperTableHandler::startCell(const Handle_t & start,
803 TablePropertyMapPtr pProps )
804 {
805 sal_uInt32 nRow = m_aRowProperties.size();
806 if ( pProps.get( ) )
807 m_aCellProperties[nRow - 1].push_back( pProps );
808 else
809 {
810 // Adding an empty cell properties map to be able to get
811 // the table defaults properties
812 TablePropertyMapPtr pEmptyProps( new TablePropertyMap( ) );
813 m_aCellProperties[nRow - 1].push_back( pEmptyProps );
814 }
815
816 #if DEBUG_DMAPPER_TABLE_HANDLER
817 dmapper_logger->startElement("table.cell");
818 dmapper_logger->startElement("table.cell.start");
819 dmapper_logger->chars(toString(start));
820 dmapper_logger->endElement("table.cell.start");
821 lcl_printProperties( pProps );
822 #endif
823
824 //add a new 'row' of properties
825 // if( m_pCellProperties.size() <= sal::static_int_cast< sal_uInt32, sal_Int32>(m_nRowIndex) )
826 // m_pCellProperties.push_back( RowProperties_t() );
827 // m_pCellProperties[m_nRowIndex].push_back( pProps );
828 m_pCellSeq = CellSequencePointer_t(new CellSequence_t(2));
829 if (!start.get())
830 return;
831 (*m_pCellSeq)[0] = start->getStart();
832 }
833
endCell(const Handle_t & end)834 void DomainMapperTableHandler::endCell(const Handle_t & end)
835 {
836 #ifdef DEBUG_DMAPPER_TABLE_HANDLER
837 dmapper_logger->startElement("table.cell.end");
838 dmapper_logger->chars(toString(end));
839 dmapper_logger->endElement("table.cell.end");
840 dmapper_logger->endElement("table.cell");
841 clog << "</table.cell>" << endl;
842 #endif
843
844 if (!end.get())
845 return;
846 (*m_pCellSeq)[1] = end->getEnd();
847 (*m_pRowSeq)[m_nCellIndex] = *m_pCellSeq;
848 ++m_nCellIndex;
849 }
850
851 }}
852