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