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 : #include <DomainMapperTableHandler.hxx>
20 : #include <DomainMapper_Impl.hxx>
21 : #include <StyleSheetTable.hxx>
22 : #include <com/sun/star/beans/XPropertyState.hpp>
23 : #include <com/sun/star/container/XEnumerationAccess.hpp>
24 : #include <com/sun/star/table/TableBorderDistances.hpp>
25 : #include <com/sun/star/table/TableBorder.hpp>
26 : #include <com/sun/star/table/BorderLine2.hpp>
27 : #include <com/sun/star/table/XCellRange.hpp>
28 : #include <com/sun/star/text/HoriOrientation.hpp>
29 : #include <com/sun/star/text/RelOrientation.hpp>
30 : #include <com/sun/star/text/SizeType.hpp>
31 : #include <dmapperLoggers.hxx>
32 :
33 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
34 : #include <PropertyMapHelper.hxx>
35 : #include <rtl/ustring.hxx>
36 : #endif
37 :
38 : namespace writerfilter {
39 : namespace dmapper {
40 :
41 : using namespace ::com::sun::star;
42 : using namespace ::std;
43 :
44 : #define DEF_BORDER_DIST 190 //0,19cm
45 :
46 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
47 : static void lcl_printProperties( PropertyMapPtr pProps )
48 : {
49 : if( pProps.get() )
50 : {
51 : dmapper_logger->startElement("properties");
52 :
53 : PropertyMap::const_iterator aMapIter = pProps->begin();
54 : PropertyMap::const_iterator aEndIter = pProps->end();
55 : PropertyNameSupplier& rPropSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
56 : for( ; aMapIter != aEndIter; ++aMapIter )
57 : {
58 : SAL_INFO("writerfilter", rPropSupplier.GetName(aMapIter->first));
59 :
60 : table::BorderLine2 aLine;
61 : sal_Int32 nColor;
62 : if ( aMapIter->second.getValue() >>= 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();
69 : }
70 : else if ( aMapIter->second.getValue() >>= nColor )
71 : {
72 : dmapper_logger->startElement("color");
73 : dmapper_logger->attribute("number", nColor);
74 : dmapper_logger->endElement();
75 : }
76 : }
77 :
78 : dmapper_logger->endElement();
79 : }
80 : }
81 : #endif
82 :
83 0 : DomainMapperTableHandler::DomainMapperTableHandler(TextReference_t xText, DomainMapper_Impl& rDMapper_Impl)
84 : : m_xText(xText),
85 : m_rDMapper_Impl( rDMapper_Impl ),
86 : m_nCellIndex(0),
87 0 : m_nRowIndex(0)
88 : {
89 0 : }
90 :
91 0 : DomainMapperTableHandler::~DomainMapperTableHandler()
92 : {
93 0 : }
94 :
95 0 : void DomainMapperTableHandler::startTable(unsigned int nRows,
96 : unsigned int /*nDepth*/,
97 : TablePropertyMapPtr pProps)
98 : {
99 0 : m_aTableProperties = pProps;
100 0 : m_pTableSeq = TableSequencePointer_t(new TableSequence_t(nRows));
101 0 : 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 : pProps->dumpXml( dmapper_logger );
109 : #endif
110 0 : }
111 :
112 :
113 :
114 0 : PropertyMapPtr lcl_SearchParentStyleSheetAndMergeProperties(const StyleSheetEntryPtr pStyleSheet, StyleSheetTablePtr pStyleSheetTable)
115 : {
116 0 : PropertyMapPtr pRet;
117 0 : if(!pStyleSheet->sBaseStyleIdentifier.isEmpty())
118 : {
119 0 : const StyleSheetEntryPtr pParentStyleSheet = pStyleSheetTable->FindStyleSheetByISTD( pStyleSheet->sBaseStyleIdentifier );
120 0 : pRet = lcl_SearchParentStyleSheetAndMergeProperties( pParentStyleSheet, pStyleSheetTable );
121 : }
122 : else
123 : {
124 0 : pRet.reset( new PropertyMap );
125 : }
126 :
127 0 : pRet->InsertProps(pStyleSheet->pProperties);
128 :
129 0 : return pRet;
130 : }
131 :
132 0 : void lcl_mergeBorder( PropertyIds nId, PropertyMapPtr pOrig, PropertyMapPtr pDest )
133 : {
134 0 : PropertyMap::iterator pOrigIt = pOrig->find(nId);
135 :
136 0 : if ( pOrigIt != pOrig->end( ) )
137 : {
138 0 : pDest->Insert( nId, pOrigIt->second.getValue(), false );
139 : }
140 0 : }
141 :
142 0 : void lcl_computeCellBorders( PropertyMapPtr pTableBorders, PropertyMapPtr pCellProps,
143 : sal_Int32 nCell, sal_Int32 nRow, bool bIsEndCol, bool bIsEndRow )
144 : {
145 0 : PropertyMap::iterator aVerticalIter = pCellProps->find(META_PROP_VERTICAL_BORDER);
146 0 : PropertyMap::iterator aHorizontalIter = pCellProps->find(META_PROP_HORIZONTAL_BORDER);
147 :
148 : // Handle the vertical and horizontal borders
149 0 : bool bHasVert = ( aVerticalIter != pCellProps->end( ) );
150 0 : uno::Any aVertProp;
151 0 : if ( !bHasVert )
152 : {
153 0 : aVerticalIter = pTableBorders->find(META_PROP_VERTICAL_BORDER);
154 0 : bHasVert = ( aVerticalIter != pTableBorders->end( ) );
155 0 : if ( bHasVert )
156 0 : aVertProp = aVerticalIter->second.getValue();
157 : }
158 : else
159 : {
160 0 : aVertProp = aVerticalIter->second.getValue();
161 0 : pCellProps->erase( aVerticalIter );
162 : }
163 :
164 0 : bool bHasHoriz = ( aHorizontalIter != pCellProps->end( ) );
165 0 : uno::Any aHorizProp;
166 0 : if ( !bHasHoriz )
167 : {
168 0 : aHorizontalIter = pTableBorders->find(META_PROP_HORIZONTAL_BORDER);
169 0 : bHasHoriz = ( aHorizontalIter != pTableBorders->end( ) );
170 0 : if ( bHasHoriz )
171 0 : aHorizProp = aHorizontalIter->second.getValue();
172 : }
173 : else
174 : {
175 0 : aHorizProp = aHorizontalIter->second.getValue();
176 0 : pCellProps->erase( aHorizontalIter );
177 : }
178 :
179 0 : if ( nCell == 0 )
180 : {
181 0 : lcl_mergeBorder( PROP_LEFT_BORDER, pTableBorders, pCellProps );
182 0 : if ( bHasVert )
183 0 : pCellProps->Insert( PROP_RIGHT_BORDER, aVertProp, false );
184 : }
185 :
186 0 : if ( bIsEndCol )
187 : {
188 0 : lcl_mergeBorder( PROP_RIGHT_BORDER, pTableBorders, pCellProps );
189 0 : if ( bHasVert )
190 0 : pCellProps->Insert( PROP_LEFT_BORDER, aVertProp, false );
191 : }
192 :
193 0 : if ( nCell > 0 && !bIsEndCol )
194 : {
195 0 : if ( bHasVert )
196 : {
197 0 : pCellProps->Insert( PROP_RIGHT_BORDER, aVertProp, false );
198 0 : pCellProps->Insert( PROP_LEFT_BORDER, aVertProp, false );
199 : }
200 : }
201 :
202 0 : if ( nRow == 0 )
203 : {
204 0 : lcl_mergeBorder( PROP_TOP_BORDER, pTableBorders, pCellProps );
205 0 : if ( bHasHoriz )
206 0 : pCellProps->Insert( PROP_BOTTOM_BORDER, aHorizProp, false );
207 : }
208 :
209 0 : if ( bIsEndRow )
210 : {
211 0 : lcl_mergeBorder( PROP_BOTTOM_BORDER, pTableBorders, pCellProps );
212 0 : if ( bHasHoriz )
213 0 : pCellProps->Insert( PROP_TOP_BORDER, aHorizProp, false );
214 : }
215 :
216 0 : if ( nRow > 0 && !bIsEndRow )
217 : {
218 0 : if ( bHasHoriz )
219 : {
220 0 : pCellProps->Insert( PROP_TOP_BORDER, aHorizProp, false );
221 0 : pCellProps->Insert( PROP_BOTTOM_BORDER, aHorizProp, false );
222 : }
223 0 : }
224 0 : }
225 :
226 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
227 :
228 : void lcl_debug_BorderLine(table::BorderLine & rLine)
229 : {
230 : dmapper_logger->startElement("BorderLine");
231 : dmapper_logger->attribute("Color", rLine.Color);
232 : dmapper_logger->attribute("InnerLineWidth", rLine.InnerLineWidth);
233 : dmapper_logger->attribute("OuterLineWidth", rLine.OuterLineWidth);
234 : dmapper_logger->attribute("LineDistance", rLine.LineDistance);
235 : dmapper_logger->endElement();
236 : }
237 :
238 : void lcl_debug_TableBorder(table::TableBorder & rBorder)
239 : {
240 : dmapper_logger->startElement("TableBorder");
241 : lcl_debug_BorderLine(rBorder.TopLine);
242 : dmapper_logger->attribute("IsTopLineValid", rBorder.IsTopLineValid);
243 : lcl_debug_BorderLine(rBorder.BottomLine);
244 : dmapper_logger->attribute("IsBottomLineValid", rBorder.IsBottomLineValid);
245 : lcl_debug_BorderLine(rBorder.LeftLine);
246 : dmapper_logger->attribute("IsLeftLineValid", rBorder.IsLeftLineValid);
247 : lcl_debug_BorderLine(rBorder.RightLine);
248 : dmapper_logger->attribute("IsRightLineValid", rBorder.IsRightLineValid);
249 : lcl_debug_BorderLine(rBorder.VerticalLine);
250 : dmapper_logger->attribute("IsVerticalLineValid", rBorder.IsVerticalLineValid);
251 : lcl_debug_BorderLine(rBorder.HorizontalLine);
252 : dmapper_logger->attribute("IsHorizontalLineValid", rBorder.IsHorizontalLineValid);
253 : dmapper_logger->attribute("Distance", rBorder.Distance);
254 : dmapper_logger->attribute("IsDistanceValid", rBorder.IsDistanceValid);
255 : dmapper_logger->endElement();
256 : }
257 : #endif
258 :
259 0 : struct TableInfo
260 : {
261 : sal_Int32 nLeftBorderDistance;
262 : sal_Int32 nRightBorderDistance;
263 : sal_Int32 nTopBorderDistance;
264 : sal_Int32 nBottomBorderDistance;
265 : sal_Int32 nTblLook;
266 : sal_Int32 nNestLevel;
267 : PropertyMapPtr pTableDefaults;
268 : PropertyMapPtr pTableBorders;
269 : TableStyleSheetEntry* pTableStyle;
270 : TablePropertyValues_t aTableProperties;
271 :
272 0 : TableInfo()
273 : : nLeftBorderDistance(DEF_BORDER_DIST)
274 : , nRightBorderDistance(DEF_BORDER_DIST)
275 : , nTopBorderDistance(0)
276 : , nBottomBorderDistance(0)
277 : , nTblLook(0x4a0)
278 : , nNestLevel(0)
279 0 : , pTableDefaults(new PropertyMap)
280 0 : , pTableBorders(new PropertyMap)
281 0 : , pTableStyle(NULL)
282 : {
283 0 : }
284 :
285 : };
286 :
287 : namespace
288 : {
289 :
290 0 : bool lcl_extractTableBorderProperty(PropertyMapPtr pTableProperties, const PropertyIds nId, TableInfo& rInfo, table::BorderLine2& rLine)
291 : {
292 0 : PropertyMap::iterator aTblBorderIter = pTableProperties->find(nId);
293 0 : if( aTblBorderIter != pTableProperties->end() )
294 : {
295 0 : OSL_VERIFY(aTblBorderIter->second.getValue() >>= rLine);
296 :
297 0 : rInfo.pTableBorders->Insert( nId, uno::makeAny( rLine ) );
298 0 : PropertyMap::iterator pIt = rInfo.pTableDefaults->find(nId);
299 0 : if ( pIt != rInfo.pTableDefaults->end( ) )
300 0 : rInfo.pTableDefaults->erase( pIt );
301 :
302 0 : return true;
303 : }
304 :
305 0 : return false;
306 : }
307 :
308 : }
309 :
310 0 : void lcl_DecrementHoriOrientPosition(uno::Sequence<beans::PropertyValue>& rFrameProperties, sal_Int32 nAmount)
311 : {
312 : // Shifts the frame left by the given value.
313 0 : for (sal_Int32 i = 0; i < rFrameProperties.getLength(); ++i)
314 : {
315 0 : beans::PropertyValue& rPropertyValue = rFrameProperties[i];
316 0 : if (rPropertyValue.Name == "HoriOrientPosition")
317 : {
318 0 : sal_Int32 nValue = rPropertyValue.Value.get<sal_Int32>();
319 0 : nValue -= nAmount;
320 0 : rPropertyValue.Value <<= nValue;
321 0 : return;
322 : }
323 : }
324 : }
325 :
326 0 : TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo & rInfo, uno::Sequence<beans::PropertyValue>& rFrameProperties)
327 : {
328 : // will receive the table style if any
329 0 : TableStyleSheetEntry* pTableStyle = NULL;
330 :
331 0 : if( m_aTableProperties.get() )
332 : {
333 : //create properties from the table attributes
334 : //...pPropMap->Insert( PROP_LEFT_MARGIN, uno::makeAny( m_nLeftMargin - m_nGapHalf ));
335 : //pPropMap->Insert( PROP_HORI_ORIENT, uno::makeAny( text::HoriOrientation::RIGHT ));
336 0 : sal_Int32 nGapHalf = 0;
337 0 : sal_Int32 nLeftMargin = 0;
338 0 : sal_Int32 nTableWidth = 0;
339 0 : sal_Int32 nTableWidthType = text::SizeType::FIX;
340 :
341 : PropertyMap::iterator aTableStyleIter =
342 0 : m_aTableProperties->find(META_PROP_TABLE_STYLE_NAME);
343 0 : uno::Sequence< beans::PropertyValue > aGrabBag( 5 );
344 0 : sal_Int32 nGrabBagSize = 0;
345 0 : if(aTableStyleIter != m_aTableProperties->end())
346 : {
347 : // Apply table style properties recursively
348 0 : OUString sTableStyleName;
349 0 : aTableStyleIter->second.getValue() >>= sTableStyleName;
350 0 : StyleSheetTablePtr pStyleSheetTable = m_rDMapper_Impl.GetStyleSheetTable();
351 0 : const StyleSheetEntryPtr pStyleSheet = pStyleSheetTable->FindStyleSheetByISTD( sTableStyleName );
352 0 : pTableStyle = dynamic_cast<TableStyleSheetEntry*>( pStyleSheet.get( ) );
353 0 : m_aTableProperties->erase( aTableStyleIter );
354 :
355 0 : aGrabBag[0].Name = "TableStyleName";
356 0 : aGrabBag[0].Value = uno::makeAny( sTableStyleName );
357 0 : nGrabBagSize++;
358 :
359 0 : if( pStyleSheet )
360 : {
361 : // First get the style properties, then the table ones
362 0 : PropertyMapPtr pTableProps( m_aTableProperties );
363 0 : TablePropertyMapPtr pEmptyProps( new TablePropertyMap );
364 :
365 0 : m_aTableProperties = pEmptyProps;
366 :
367 0 : PropertyMapPtr pMergedProperties = lcl_SearchParentStyleSheetAndMergeProperties(pStyleSheet, pStyleSheetTable);
368 :
369 0 : table::BorderLine2 aBorderLine;
370 0 : TableInfo rStyleInfo;
371 0 : if (lcl_extractTableBorderProperty(pMergedProperties, PROP_TOP_BORDER, rStyleInfo, aBorderLine))
372 : {
373 0 : aGrabBag[1].Name = "TableStyleTopBorder";
374 0 : aGrabBag[1].Value = uno::makeAny( aBorderLine );
375 0 : nGrabBagSize++;
376 : }
377 0 : if (lcl_extractTableBorderProperty(pMergedProperties, PROP_BOTTOM_BORDER, rStyleInfo, aBorderLine))
378 : {
379 0 : aGrabBag[2].Name = "TableStyleBottomBorder";
380 0 : aGrabBag[2].Value = uno::makeAny( aBorderLine );
381 0 : nGrabBagSize++;
382 : }
383 0 : if (lcl_extractTableBorderProperty(pMergedProperties, PROP_LEFT_BORDER, rStyleInfo, aBorderLine))
384 : {
385 0 : aGrabBag[3].Name = "TableStyleLeftBorder";
386 0 : aGrabBag[3].Value = uno::makeAny( aBorderLine );
387 0 : nGrabBagSize++;
388 : }
389 0 : if (lcl_extractTableBorderProperty(pMergedProperties, PROP_RIGHT_BORDER, rStyleInfo, aBorderLine))
390 : {
391 0 : aGrabBag[4].Name = "TableStyleRightBorder";
392 0 : aGrabBag[4].Value = uno::makeAny( aBorderLine );
393 0 : nGrabBagSize++;
394 : }
395 :
396 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
397 : dmapper_logger->startElement("mergedProps");
398 : pMergedProperties->dumpXml( dmapper_logger );
399 : dmapper_logger->endElement();
400 : #endif
401 :
402 0 : m_aTableProperties->InsertProps(pMergedProperties);
403 0 : m_aTableProperties->InsertProps(pTableProps);
404 :
405 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
406 : dmapper_logger->startElement("TableProperties");
407 : m_aTableProperties->dumpXml( dmapper_logger );
408 : dmapper_logger->endElement();
409 : #endif
410 0 : }
411 : }
412 :
413 : PropertyMap::iterator const aTblLookIter =
414 0 : m_aTableProperties->find(PROP_TBL_LOOK);
415 0 : if(aTblLookIter != m_aTableProperties->end())
416 : {
417 0 : aTblLookIter->second.getValue() >>= rInfo.nTblLook;
418 0 : m_aTableProperties->erase( aTblLookIter );
419 : }
420 :
421 : // Set the table default attributes for the cells
422 0 : rInfo.pTableDefaults->InsertProps(m_aTableProperties);
423 :
424 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
425 : dmapper_logger->startElement("TableDefaults");
426 : rInfo.pTableDefaults->dumpXml( dmapper_logger );
427 : dmapper_logger->endElement();
428 : #endif
429 :
430 0 : if( nGrabBagSize > 0 )
431 : {
432 0 : aGrabBag.realloc( nGrabBagSize );
433 0 : m_aTableProperties->Insert( PROP_TABLE_INTEROP_GRAB_BAG, uno::makeAny( aGrabBag ) );
434 : }
435 :
436 0 : m_aTableProperties->getValue( TablePropertyMap::GAP_HALF, nGapHalf );
437 0 : m_aTableProperties->getValue( TablePropertyMap::LEFT_MARGIN, nLeftMargin );
438 :
439 : m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_LEFT,
440 0 : rInfo.nLeftBorderDistance );
441 : m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_RIGHT,
442 0 : rInfo.nRightBorderDistance );
443 : m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_TOP,
444 0 : rInfo.nTopBorderDistance );
445 : m_aTableProperties->getValue( TablePropertyMap::CELL_MAR_BOTTOM,
446 0 : rInfo.nBottomBorderDistance );
447 :
448 0 : table::TableBorderDistances aDistances;
449 : aDistances.IsTopDistanceValid =
450 : aDistances.IsBottomDistanceValid =
451 : aDistances.IsLeftDistanceValid =
452 0 : aDistances.IsRightDistanceValid = sal_True;
453 0 : aDistances.TopDistance = static_cast<sal_Int16>( rInfo.nTopBorderDistance );
454 0 : aDistances.BottomDistance = static_cast<sal_Int16>( rInfo.nBottomBorderDistance );
455 0 : aDistances.LeftDistance = static_cast<sal_Int16>( rInfo.nLeftBorderDistance );
456 0 : aDistances.RightDistance = static_cast<sal_Int16>( rInfo.nRightBorderDistance );
457 :
458 0 : m_aTableProperties->Insert( PROP_TABLE_BORDER_DISTANCES, uno::makeAny( aDistances ) );
459 :
460 0 : if (rFrameProperties.hasElements())
461 0 : lcl_DecrementHoriOrientPosition(rFrameProperties, rInfo.nLeftBorderDistance);
462 :
463 : // Set table above/bottom spacing to 0.
464 0 : m_aTableProperties->Insert( PROP_TOP_MARGIN, uno::makeAny( sal_Int32( 0 ) ) );
465 0 : m_aTableProperties->Insert( PROP_BOTTOM_MARGIN, uno::makeAny( sal_Int32( 0 ) ) );
466 :
467 : //table border settings
468 0 : table::TableBorder aTableBorder;
469 0 : table::BorderLine2 aBorderLine, aLeftBorder;
470 :
471 0 : if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_TOP_BORDER, rInfo, aBorderLine))
472 : {
473 0 : aTableBorder.TopLine = aBorderLine;
474 0 : aTableBorder.IsTopLineValid = sal_True;
475 : }
476 0 : if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_BOTTOM_BORDER, rInfo, aBorderLine))
477 : {
478 0 : aTableBorder.BottomLine = aBorderLine;
479 0 : aTableBorder.IsBottomLineValid = sal_True;
480 : }
481 0 : if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_LEFT_BORDER, rInfo, aLeftBorder))
482 : {
483 0 : aTableBorder.LeftLine = aLeftBorder;
484 0 : aTableBorder.IsLeftLineValid = sal_True;
485 : // Only top level table position depends on border width
486 0 : if (rInfo.nNestLevel == 1)
487 : {
488 0 : if (!rFrameProperties.hasElements())
489 0 : rInfo.nLeftBorderDistance += aLeftBorder.LineWidth * 0.5;
490 : else
491 0 : lcl_DecrementHoriOrientPosition(rFrameProperties, aLeftBorder.LineWidth * 0.5);
492 : }
493 : }
494 0 : if (lcl_extractTableBorderProperty(m_aTableProperties, PROP_RIGHT_BORDER, rInfo, aBorderLine))
495 : {
496 0 : aTableBorder.RightLine = aBorderLine;
497 0 : aTableBorder.IsRightLineValid = sal_True;
498 : }
499 0 : if (lcl_extractTableBorderProperty(m_aTableProperties, META_PROP_HORIZONTAL_BORDER, rInfo, aBorderLine))
500 : {
501 0 : aTableBorder.HorizontalLine = aBorderLine;
502 0 : aTableBorder.IsHorizontalLineValid = sal_True;
503 : }
504 0 : if (lcl_extractTableBorderProperty(m_aTableProperties, META_PROP_VERTICAL_BORDER, rInfo, aBorderLine))
505 : {
506 0 : aTableBorder.VerticalLine = aBorderLine;
507 0 : aTableBorder.IsVerticalLineValid = sal_True;
508 : }
509 :
510 0 : aTableBorder.Distance = 0;
511 0 : aTableBorder.IsDistanceValid = sal_False;
512 :
513 0 : m_aTableProperties->Insert( PROP_TABLE_BORDER, uno::makeAny( aTableBorder ) );
514 :
515 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
516 : lcl_debug_TableBorder(aTableBorder);
517 : #endif
518 :
519 : // Table position in Office is computed in 2 different ways :
520 : // - top level tables: the goal is to have in-cell text starting at table indent pos (tblInd),
521 : // so table's position depends on table's cells margin
522 : // - nested tables: the goal is to have left-most border starting at table_indent pos
523 0 : if (rInfo.nNestLevel > 1)
524 : {
525 0 : m_aTableProperties->Insert( PROP_LEFT_MARGIN, uno::makeAny( nLeftMargin - nGapHalf ));
526 : }
527 : else
528 : {
529 0 : m_aTableProperties->Insert( PROP_LEFT_MARGIN, uno::makeAny( nLeftMargin - nGapHalf - rInfo.nLeftBorderDistance ));
530 : }
531 :
532 0 : m_aTableProperties->getValue( TablePropertyMap::TABLE_WIDTH, nTableWidth );
533 0 : m_aTableProperties->getValue( TablePropertyMap::TABLE_WIDTH_TYPE, nTableWidthType );
534 0 : if( nTableWidthType == text::SizeType::FIX )
535 : {
536 0 : if( nTableWidth > 0 )
537 0 : m_aTableProperties->Insert( PROP_WIDTH, uno::makeAny( nTableWidth ));
538 : }
539 : else
540 : {
541 0 : m_aTableProperties->Insert( PROP_RELATIVE_WIDTH, uno::makeAny( sal_Int16( nTableWidth ) ) );
542 0 : m_aTableProperties->Insert( PROP_IS_WIDTH_RELATIVE, uno::makeAny( sal_Bool( sal_True ) ) );
543 : }
544 :
545 0 : sal_Int32 nHoriOrient = text::HoriOrientation::LEFT_AND_WIDTH;
546 0 : m_aTableProperties->getValue( TablePropertyMap::HORI_ORIENT, nHoriOrient ) ;
547 0 : m_aTableProperties->Insert( PROP_HORI_ORIENT, uno::makeAny( sal_Int16(nHoriOrient) ) );
548 : //fill default value - if not available
549 : const PropertyMap::const_iterator aRepeatIter =
550 0 : m_aTableProperties->find(PROP_HEADER_ROW_COUNT);
551 0 : if( aRepeatIter == m_aTableProperties->end() )
552 0 : m_aTableProperties->Insert( PROP_HEADER_ROW_COUNT, uno::makeAny( (sal_Int32)0 ));
553 :
554 0 : rInfo.aTableProperties = m_aTableProperties->GetPropertyValues();
555 :
556 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
557 : dmapper_logger->startElement("debug.tableprops");
558 : m_aTableProperties->dumpXml( dmapper_logger );
559 : dmapper_logger->endElement();
560 : #endif
561 :
562 : }
563 :
564 0 : return pTableStyle;
565 : }
566 :
567 : #define CNF_FIRST_ROW 0x800
568 : #define CNF_LAST_ROW 0x400
569 : #define CNF_FIRST_COLUMN 0x200
570 : #define CNF_LAST_COLUMN 0x100
571 : #define CNF_ODD_VBAND 0x080
572 : #define CNF_EVEN_VBAND 0x040
573 : #define CNF_ODD_HBAND 0x020
574 : #define CNF_EVEN_HBAND 0x010
575 : #define CNF_FIRST_ROW_LAST_COLUMN 0x008
576 : #define CNF_FIRST_ROW_FIRST_COLUMN 0x004
577 : #define CNF_LAST_ROW_LAST_COLUMN 0x002
578 : #define CNF_LAST_ROW_FIRST_COLUMN 0x001
579 :
580 0 : CellPropertyValuesSeq_t DomainMapperTableHandler::endTableGetCellProperties(TableInfo & rInfo, std::vector<HorizontallyMergedCell>& rMerges)
581 : {
582 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
583 : dmapper_logger->startElement("getCellProperties");
584 : #endif
585 :
586 0 : CellPropertyValuesSeq_t aCellProperties( m_aCellProperties.size() );
587 :
588 0 : if ( !m_aCellProperties.size() )
589 : {
590 : #ifdef DEBUG_DOMAINMAPPER
591 : dmapper_logger->endElement();
592 : #endif
593 0 : return aCellProperties;
594 : }
595 : // std::vector< std::vector<PropertyMapPtr> > m_aCellProperties
596 0 : PropertyMapVector2::const_iterator aRowOfCellsIterator = m_aCellProperties.begin();
597 0 : PropertyMapVector2::const_iterator aRowOfCellsIteratorEnd = m_aCellProperties.end();
598 0 : PropertyMapVector2::const_iterator aLastRowIterator = m_aCellProperties.end() - 1;
599 0 : sal_Int32 nRow = 0;
600 :
601 : //it's a uno::Sequence< beans::PropertyValues >*
602 0 : RowPropertyValuesSeq_t* pCellProperties = aCellProperties.getArray();
603 0 : PropertyMapVector1::const_iterator aRowIter = m_aRowProperties.begin();
604 0 : while( aRowOfCellsIterator != aRowOfCellsIteratorEnd )
605 : {
606 : //aRowOfCellsIterator points to a vector of PropertyMapPtr
607 0 : PropertyMapVector1::const_iterator aCellIterator = aRowOfCellsIterator->begin();
608 0 : PropertyMapVector1::const_iterator aCellIteratorEnd = aRowOfCellsIterator->end();
609 :
610 0 : sal_Int32 nRowStyleMask = 0;
611 :
612 0 : if (aRowOfCellsIterator==m_aCellProperties.begin())
613 : {
614 0 : if(rInfo.nTblLook&0x20)
615 0 : nRowStyleMask |= CNF_FIRST_ROW; // first row style used
616 : }
617 0 : else if (aRowOfCellsIterator==aLastRowIterator)
618 : {
619 0 : if(rInfo.nTblLook&0x40)
620 0 : nRowStyleMask |= CNF_LAST_ROW; // last row style used
621 : }
622 0 : else if (aRowIter->get() && aRowIter->get()->find(PROP_TBL_HEADER) != aRowIter->get()->end())
623 0 : nRowStyleMask |= CNF_FIRST_ROW; // table header implies first row
624 0 : if(!nRowStyleMask) // if no row style used yet
625 : {
626 : // banding used only if not first and or last row style used
627 0 : if(!(rInfo.nTblLook&0x200))
628 : { // hbanding used
629 0 : int n = nRow + 1;
630 0 : if(rInfo.nTblLook&0x20)
631 0 : n++;
632 0 : if(n & 1)
633 0 : nRowStyleMask = CNF_ODD_HBAND;
634 : else
635 0 : nRowStyleMask = CNF_EVEN_HBAND;
636 : }
637 : }
638 :
639 0 : sal_Int32 nCell = 0;
640 0 : pCellProperties[nRow].realloc( aRowOfCellsIterator->size() );
641 0 : beans::PropertyValues* pSingleCellProperties = pCellProperties[nRow].getArray();
642 0 : while( aCellIterator != aCellIteratorEnd )
643 : {
644 0 : PropertyMapPtr pAllCellProps( new PropertyMap );
645 :
646 0 : PropertyMapVector1::const_iterator aLastCellIterator = aRowOfCellsIterator->end() - 1;
647 0 : bool bIsEndCol = aCellIterator == aLastCellIterator;
648 0 : bool bIsEndRow = aRowOfCellsIterator == aLastRowIterator;
649 :
650 : //aCellIterator points to a PropertyMapPtr;
651 0 : if( aCellIterator->get() )
652 : {
653 0 : if ( rInfo.pTableDefaults->size( ) )
654 0 : pAllCellProps->InsertProps(rInfo.pTableDefaults);
655 :
656 0 : sal_Int32 nCellStyleMask = 0;
657 0 : if (aCellIterator==aRowOfCellsIterator->begin())
658 : {
659 0 : if(rInfo.nTblLook&0x80)
660 0 : nCellStyleMask = CNF_FIRST_COLUMN; // first col style used
661 : }
662 0 : else if (bIsEndCol)
663 : {
664 0 : if(rInfo.nTblLook&0x100)
665 0 : nCellStyleMask = CNF_LAST_COLUMN; // last col style used
666 : }
667 0 : if(!nCellStyleMask) // if no cell style is used yet
668 : {
669 0 : if(!(rInfo.nTblLook&0x400))
670 : { // vbanding used
671 0 : int n = nCell + 1;
672 0 : if(rInfo.nTblLook&0x80)
673 0 : n++;
674 0 : if(n & 1)
675 0 : nCellStyleMask = CNF_ODD_VBAND;
676 : else
677 0 : nCellStyleMask = CNF_EVEN_VBAND;
678 : }
679 : }
680 0 : sal_Int32 nCnfStyleMask = nCellStyleMask + nRowStyleMask;
681 0 : if(nCnfStyleMask == CNF_FIRST_COLUMN + CNF_FIRST_ROW)
682 0 : nCnfStyleMask |= CNF_FIRST_ROW_FIRST_COLUMN;
683 0 : else if(nCnfStyleMask == CNF_FIRST_COLUMN + CNF_LAST_ROW)
684 0 : nCnfStyleMask |= CNF_LAST_ROW_FIRST_COLUMN;
685 0 : else if(nCnfStyleMask == CNF_LAST_COLUMN + CNF_FIRST_ROW)
686 0 : nCnfStyleMask |= CNF_FIRST_ROW_LAST_COLUMN;
687 0 : else if(nCnfStyleMask == CNF_LAST_COLUMN + CNF_LAST_ROW)
688 0 : nCnfStyleMask |= CNF_LAST_ROW_LAST_COLUMN;
689 :
690 0 : if ( rInfo.pTableStyle )
691 : {
692 0 : PropertyMapPtr pStyleProps = rInfo.pTableStyle->GetProperties( nCnfStyleMask );
693 0 : pAllCellProps->InsertProps( pStyleProps );
694 : }
695 :
696 : // Remove properties from style/row that aren't allowed in cells
697 0 : PropertyMap::iterator aDefaultRepeatIt = pAllCellProps->find(PROP_HEADER_ROW_COUNT);
698 0 : if ( aDefaultRepeatIt != pAllCellProps->end( ) )
699 0 : pAllCellProps->erase( aDefaultRepeatIt );
700 :
701 0 : aDefaultRepeatIt = pAllCellProps->find(PROP_PARA_LINE_SPACING);
702 0 : if ( aDefaultRepeatIt != pAllCellProps->end( ) )
703 0 : pAllCellProps->erase( aDefaultRepeatIt );
704 :
705 0 : aDefaultRepeatIt = pAllCellProps->find(PROP_TBL_HEADER);
706 0 : if ( aDefaultRepeatIt != pAllCellProps->end( ) )
707 0 : pAllCellProps->erase( aDefaultRepeatIt );
708 :
709 : // Then add the cell properties
710 0 : pAllCellProps->InsertProps(*aCellIterator);
711 0 : aCellIterator->get( )->swap( *pAllCellProps.get( ) );
712 :
713 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
714 : dmapper_logger->startElement("cell");
715 : dmapper_logger->attribute("cell", nCell);
716 : dmapper_logger->attribute("row", nRow);
717 : #endif
718 :
719 0 : lcl_computeCellBorders( rInfo.pTableBorders, *aCellIterator, nCell, nRow, bIsEndCol, bIsEndRow );
720 :
721 : //now set the default left+right border distance TODO: there's an sprm containing the default distance!
722 : const PropertyMap::const_iterator aLeftDistanceIter =
723 0 : aCellIterator->get()->find(PROP_LEFT_BORDER_DISTANCE);
724 0 : if( aLeftDistanceIter == aCellIterator->get()->end() )
725 : aCellIterator->get()->Insert( PROP_LEFT_BORDER_DISTANCE,
726 0 : uno::makeAny(rInfo.nLeftBorderDistance ) );
727 : const PropertyMap::const_iterator aRightDistanceIter =
728 0 : aCellIterator->get()->find(PROP_RIGHT_BORDER_DISTANCE);
729 0 : if( aRightDistanceIter == aCellIterator->get()->end() )
730 : aCellIterator->get()->Insert( PROP_RIGHT_BORDER_DISTANCE,
731 0 : uno::makeAny((sal_Int32) rInfo.nRightBorderDistance ) );
732 :
733 : const PropertyMap::const_iterator aTopDistanceIter =
734 0 : aCellIterator->get()->find(PROP_TOP_BORDER_DISTANCE);
735 0 : if( aTopDistanceIter == aCellIterator->get()->end() )
736 : aCellIterator->get()->Insert( PROP_TOP_BORDER_DISTANCE,
737 0 : uno::makeAny((sal_Int32) rInfo.nTopBorderDistance ) );
738 :
739 : const PropertyMap::const_iterator aBottomDistanceIter =
740 0 : aCellIterator->get()->find(PROP_BOTTOM_BORDER_DISTANCE);
741 0 : if( aBottomDistanceIter == aCellIterator->get()->end() )
742 : aCellIterator->get()->Insert( PROP_BOTTOM_BORDER_DISTANCE,
743 0 : uno::makeAny((sal_Int32) rInfo.nBottomBorderDistance ) );
744 :
745 : // Horizontal merge is not an UNO property, extract that info here to rMerges, and then remove it from the map.
746 0 : const PropertyMap::const_iterator aHorizontalMergeIter = aCellIterator->get()->find(PROP_HORIZONTAL_MERGE);
747 0 : if (aHorizontalMergeIter != aCellIterator->get()->end())
748 : {
749 0 : if (aHorizontalMergeIter->second.getValue().get<sal_Bool>())
750 : {
751 : // first cell in a merge
752 0 : HorizontallyMergedCell aMerge(nRow, nCell);
753 0 : rMerges.push_back(aMerge);
754 : }
755 0 : else if (!rMerges.empty())
756 : {
757 : // resuming an earlier merge
758 0 : HorizontallyMergedCell& rMerge = rMerges.back();
759 0 : rMerge.m_nLastRow = nRow;
760 0 : rMerge.m_nLastCol = nCell;
761 : }
762 0 : aCellIterator->get()->erase(PROP_HORIZONTAL_MERGE);
763 : }
764 0 : pSingleCellProperties[nCell] = aCellIterator->get()->GetPropertyValues();
765 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
766 : dmapper_logger->endElement();
767 : #endif
768 : }
769 0 : ++nCell;
770 0 : ++aCellIterator;
771 0 : }
772 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
773 : //-->debug cell properties
774 : {
775 : OUString sNames;
776 : const uno::Sequence< beans::PropertyValues > aDebugCurrentRow = aCellProperties[nRow];
777 : sal_Int32 nDebugCells = aDebugCurrentRow.getLength();
778 : (void) nDebugCells;
779 : for( sal_Int32 nDebugCell = 0; nDebugCell < nDebugCells; ++nDebugCell)
780 : {
781 : const uno::Sequence< beans::PropertyValue >& aDebugCellProperties = aDebugCurrentRow[nDebugCell];
782 : sal_Int32 nDebugCellProperties = aDebugCellProperties.getLength();
783 : for( sal_Int32 nDebugProperty = 0; nDebugProperty < nDebugCellProperties; ++nDebugProperty)
784 : {
785 : const OUString sName = aDebugCellProperties[nDebugProperty].Name;
786 : sNames += sName;
787 : sNames += OUString('-');
788 : }
789 : sNames += OUString('\n');
790 : }
791 : (void)sNames;
792 : }
793 : //--<
794 : #endif
795 0 : ++nRow;
796 0 : ++aRowOfCellsIterator;
797 0 : ++aRowIter;
798 : }
799 :
800 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
801 : dmapper_logger->endElement();
802 : #endif
803 :
804 0 : return aCellProperties;
805 : }
806 :
807 0 : RowPropertyValuesSeq_t DomainMapperTableHandler::endTableGetRowProperties()
808 : {
809 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
810 : dmapper_logger->startElement("getRowProperties");
811 : #endif
812 :
813 0 : RowPropertyValuesSeq_t aRowProperties( m_aRowProperties.size() );
814 0 : PropertyMapVector1::const_iterator aRowIter = m_aRowProperties.begin();
815 0 : PropertyMapVector1::const_iterator aRowIterEnd = m_aRowProperties.end();
816 0 : sal_Int32 nRow = 0;
817 0 : while( aRowIter != aRowIterEnd )
818 : {
819 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
820 : dmapper_logger->startElement("rowProps.row");
821 : #endif
822 0 : if( aRowIter->get() )
823 : {
824 : //set default to 'break across pages"
825 0 : if( aRowIter->get()->find(PROP_IS_SPLIT_ALLOWED) == aRowIter->get()->end())
826 0 : aRowIter->get()->Insert( PROP_IS_SPLIT_ALLOWED, uno::makeAny(sal_True ) );
827 : // tblHeader is only our property, remove before the property map hits UNO
828 0 : PropertyMap::iterator const aIter = aRowIter->get()->find(PROP_TBL_HEADER);
829 0 : if (aIter != aRowIter->get()->end())
830 0 : aRowIter->get()->erase(aIter);
831 :
832 0 : aRowProperties[nRow] = (*aRowIter)->GetPropertyValues();
833 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
834 : ((*aRowIter)->dumpXml( dmapper_logger ));
835 : lcl_DumpPropertyValues(dmapper_logger, aRowProperties[nRow]);
836 : #endif
837 : }
838 0 : ++nRow;
839 0 : ++aRowIter;
840 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
841 : dmapper_logger->endElement();
842 : #endif
843 : }
844 :
845 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
846 : dmapper_logger->endElement();
847 : #endif
848 :
849 0 : return aRowProperties;
850 : }
851 :
852 : // Apply paragraph property to each paragraph within a cell.
853 0 : static void lcl_ApplyCellParaProps(uno::Reference<table::XCell> xCell, uno::Any aBottomMargin)
854 : {
855 0 : uno::Reference<container::XEnumerationAccess> xEnumerationAccess(xCell, uno::UNO_QUERY);
856 0 : uno::Reference<container::XEnumeration> xEnumeration = xEnumerationAccess->createEnumeration();
857 0 : while (xEnumeration->hasMoreElements())
858 : {
859 0 : uno::Reference<beans::XPropertySet> xParagraph(xEnumeration->nextElement(), uno::UNO_QUERY);
860 0 : uno::Reference<beans::XPropertyState> xPropertyState(xParagraph, uno::UNO_QUERY);
861 : // Don't apply in case direct formatting is already present.
862 : // TODO: probably paragraph style has priority over table style here.
863 0 : if (xPropertyState.is() && xPropertyState->getPropertyState("ParaBottomMargin") == beans::PropertyState_DEFAULT_VALUE)
864 0 : xParagraph->setPropertyValue("ParaBottomMargin", aBottomMargin);
865 0 : }
866 0 : }
867 :
868 0 : void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel)
869 : {
870 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
871 : dmapper_logger->startElement("tablehandler.endTable");
872 : #endif
873 :
874 : // If we want to make this table a floating one.
875 0 : uno::Sequence<beans::PropertyValue> aFrameProperties = m_rDMapper_Impl.getTableManager().getCurrentTablePosition();
876 0 : TableInfo aTableInfo;
877 0 : aTableInfo.nNestLevel = nestedTableLevel;
878 0 : aTableInfo.pTableStyle = endTableGetTableStyle(aTableInfo, aFrameProperties);
879 : // expands to uno::Sequence< Sequence< beans::PropertyValues > >
880 :
881 0 : std::vector<HorizontallyMergedCell> aMerges;
882 0 : CellPropertyValuesSeq_t aCellProperties = endTableGetCellProperties(aTableInfo, aMerges);
883 :
884 0 : RowPropertyValuesSeq_t aRowProperties = endTableGetRowProperties();
885 :
886 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
887 : lcl_DumpPropertyValueSeq(dmapper_logger, aRowProperties);
888 : #endif
889 :
890 0 : if (m_pTableSeq->getLength() > 0)
891 : {
892 0 : uno::Reference<text::XTextRange> xStart;
893 0 : uno::Reference<text::XTextRange> xEnd;
894 :
895 0 : bool bFloating = aFrameProperties.hasElements();
896 : // Additional checks: if we can do this.
897 0 : if (bFloating && (*m_pTableSeq)[0].getLength() > 0 && (*m_pTableSeq)[0][0].getLength() > 0)
898 : {
899 0 : xStart = (*m_pTableSeq)[0][0][0];
900 0 : uno::Sequence< uno::Sequence< uno::Reference<text::XTextRange> > >& rLastRow = (*m_pTableSeq)[m_pTableSeq->getLength() - 1];
901 0 : uno::Sequence< uno::Reference<text::XTextRange> >& rLastCell = rLastRow[rLastRow.getLength() - 1];
902 0 : xEnd = rLastCell[1];
903 : }
904 0 : uno::Reference<text::XTextTable> xTable;
905 : try
906 : {
907 0 : if (m_xText.is())
908 : {
909 0 : xTable = m_xText->convertToTable(*m_pTableSeq,
910 : aCellProperties,
911 : aRowProperties,
912 0 : aTableInfo.aTableProperties);
913 :
914 0 : if (xTable.is())
915 : {
916 0 : m_xTableRange = xTable->getAnchor( );
917 :
918 0 : if (!aMerges.empty())
919 : {
920 : // Perform horizontal merges in reverse order, so the fact that merging changes the position of cells won't cause a problem for us.
921 0 : for (std::vector<HorizontallyMergedCell>::reverse_iterator it = aMerges.rbegin(); it != aMerges.rend(); ++it)
922 : {
923 0 : uno::Reference<table::XCellRange> xCellRange(xTable, uno::UNO_QUERY_THROW);
924 0 : uno::Reference<beans::XPropertySet> xCell(xCellRange->getCellByPosition(it->m_nFirstCol, it->m_nFirstRow), uno::UNO_QUERY_THROW);
925 0 : OUString aFirst = xCell->getPropertyValue("CellName").get<OUString>();
926 0 : xCell.set(xCellRange->getCellByPosition(it->m_nLastCol, it->m_nLastRow), uno::UNO_QUERY_THROW);
927 0 : OUString aLast = xCell->getPropertyValue("CellName").get<OUString>();
928 :
929 0 : uno::Reference<text::XTextTableCursor> xCursor = xTable->createCursorByCellName(aFirst);
930 0 : xCursor->gotoCellByName(aLast, true);
931 0 : xCursor->mergeRange();
932 0 : }
933 : }
934 : }
935 :
936 : // OOXML table style may container paragraph properties, apply these now.
937 0 : for (int i = 0; i < aTableInfo.aTableProperties.getLength(); ++i)
938 : {
939 0 : if (aTableInfo.aTableProperties[i].Name == "ParaBottomMargin")
940 : {
941 0 : uno::Reference<table::XCellRange> xCellRange(xTable, uno::UNO_QUERY);
942 0 : uno::Any aBottomMargin = aTableInfo.aTableProperties[i].Value;
943 0 : sal_Int32 nRows = aCellProperties.getLength();
944 0 : for (sal_Int32 nRow = 0; nRow < nRows; ++nRow)
945 : {
946 0 : const uno::Sequence< beans::PropertyValues > aCurrentRow = aCellProperties[nRow];
947 0 : sal_Int32 nCells = aCurrentRow.getLength();
948 0 : for (sal_Int32 nCell = 0; nCell < nCells; ++nCell)
949 0 : lcl_ApplyCellParaProps(xCellRange->getCellByPosition(nCell, nRow), aBottomMargin);
950 0 : }
951 0 : break;
952 : }
953 : }
954 : }
955 : }
956 0 : catch ( const lang::IllegalArgumentException &e )
957 : {
958 : SAL_INFO("writerfilter.dmapper",
959 : "Conversion to table error: " << e.Message);
960 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
961 : dmapper_logger->chars(std::string("failed to import table!"));
962 : #endif
963 : }
964 0 : catch ( const uno::Exception &e )
965 : {
966 : SAL_INFO("writerfilter.dmapper",
967 : "Exception during table creation: " << e.Message);
968 : }
969 :
970 : // If we have a table with a start and an end position, we should make it a floating one.
971 0 : if (xTable.is() && xStart.is() && xEnd.is())
972 : {
973 0 : uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY);
974 0 : sal_Bool bIsRelative = sal_False;
975 0 : xTableProperties->getPropertyValue("IsWidthRelative") >>= bIsRelative;
976 0 : if (!bIsRelative)
977 : {
978 0 : aFrameProperties.realloc(aFrameProperties.getLength() + 1);
979 0 : aFrameProperties[aFrameProperties.getLength() - 1].Name = "Width";
980 0 : aFrameProperties[aFrameProperties.getLength() - 1].Value = xTableProperties->getPropertyValue("Width");
981 : }
982 : else
983 : {
984 0 : aFrameProperties.realloc(aFrameProperties.getLength() + 1);
985 0 : aFrameProperties[aFrameProperties.getLength() - 1].Name = "FrameWidthPercent";
986 0 : aFrameProperties[aFrameProperties.getLength() - 1].Value = xTableProperties->getPropertyValue("RelativeWidth");
987 :
988 : // Applying the relative width to the frame, needs to have the table width to be 100% of the frame width
989 0 : xTableProperties->setPropertyValue("RelativeWidth", uno::makeAny(sal_Int16(100)));
990 : }
991 :
992 : // A non-zero left margin would move the table out of the frame, move the frame itself instead.
993 0 : xTableProperties->setPropertyValue("LeftMargin", uno::makeAny(sal_Int32(0)));
994 :
995 : // In case the document ends with a table, we're called after
996 : // SectionPropertyMap::CloseSectionGroup(), so we'll have no idea
997 : // about the text area width, nor can fix this by delaying the text
998 : // frame conversion: just do it here.
999 : // Also, when the anchor is within a table, then do it here as well,
1000 : // as xStart/xEnd would not point to the start/end at conversion
1001 : // time anyway.
1002 0 : sal_Int32 nTableWidth = 0;
1003 0 : m_aTableProperties->getValue(TablePropertyMap::TABLE_WIDTH, nTableWidth);
1004 0 : if (m_rDMapper_Impl.GetSectionContext() && nestedTableLevel <= 1)
1005 0 : m_rDMapper_Impl.m_aPendingFloatingTables.push_back(FloatingTableInfo(xStart, xEnd, aFrameProperties, nTableWidth));
1006 : else
1007 0 : m_xText->convertToTextFrame(xStart, xEnd, aFrameProperties);
1008 0 : }
1009 : }
1010 :
1011 0 : m_aTableProperties.reset();
1012 0 : m_aCellProperties.clear();
1013 0 : m_aRowProperties.clear();
1014 :
1015 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
1016 : dmapper_logger->endElement();
1017 : dmapper_logger->endElement();
1018 : #endif
1019 0 : }
1020 :
1021 0 : void DomainMapperTableHandler::startRow(unsigned int nCells,
1022 : TablePropertyMapPtr pProps)
1023 : {
1024 0 : m_aRowProperties.push_back( pProps );
1025 0 : m_aCellProperties.push_back( PropertyMapVector1() );
1026 :
1027 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
1028 : dmapper_logger->startElement("table.row");
1029 : dmapper_logger->attribute("cells", nCells);
1030 : if (pProps != NULL)
1031 : pProps->dumpXml(dmapper_logger);
1032 : #endif
1033 :
1034 0 : m_pRowSeq = RowSequencePointer_t(new RowSequence_t(nCells));
1035 0 : m_nCellIndex = 0;
1036 0 : }
1037 :
1038 0 : void DomainMapperTableHandler::endRow()
1039 : {
1040 0 : (*m_pTableSeq)[m_nRowIndex] = *m_pRowSeq;
1041 0 : ++m_nRowIndex;
1042 0 : m_nCellIndex = 0;
1043 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
1044 : dmapper_logger->endElement();
1045 : #endif
1046 0 : }
1047 :
1048 0 : void DomainMapperTableHandler::startCell(const Handle_t & start,
1049 : TablePropertyMapPtr pProps )
1050 : {
1051 0 : sal_uInt32 nRow = m_aRowProperties.size();
1052 0 : if ( pProps.get( ) )
1053 0 : m_aCellProperties[nRow - 1].push_back( pProps );
1054 : else
1055 : {
1056 : // Adding an empty cell properties map to be able to get
1057 : // the table defaults properties
1058 0 : TablePropertyMapPtr pEmptyProps( new TablePropertyMap( ) );
1059 0 : m_aCellProperties[nRow - 1].push_back( pEmptyProps );
1060 : }
1061 :
1062 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
1063 : dmapper_logger->startElement("table.cell");
1064 : dmapper_logger->startElement("table.cell.start");
1065 : dmapper_logger->chars(toString(start));
1066 : dmapper_logger->endElement();
1067 : lcl_printProperties( pProps );
1068 : #endif
1069 :
1070 : //add a new 'row' of properties
1071 0 : m_pCellSeq = CellSequencePointer_t(new CellSequence_t(2));
1072 0 : if (!start.get())
1073 0 : return;
1074 0 : (*m_pCellSeq)[0] = start->getStart();
1075 : }
1076 :
1077 0 : void DomainMapperTableHandler::endCell(const Handle_t & end)
1078 : {
1079 : #ifdef DEBUG_DMAPPER_TABLE_HANDLER
1080 : dmapper_logger->startElement("table.cell.end");
1081 : dmapper_logger->chars(toString(end));
1082 : dmapper_logger->endElement();
1083 : dmapper_logger->endElement();
1084 : #endif
1085 :
1086 0 : if (!end.get())
1087 0 : return;
1088 0 : (*m_pCellSeq)[1] = end->getEnd();
1089 0 : (*m_pRowSeq)[m_nCellIndex] = *m_pCellSeq;
1090 0 : ++m_nCellIndex;
1091 : }
1092 :
1093 : }}
1094 :
1095 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|