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 <boost/optional.hpp>
20 : #include <DomainMapperTableManager.hxx>
21 : #include <resourcemodel/WW8ResourceModel.hxx>
22 : #include <BorderHandler.hxx>
23 : #include <CellColorHandler.hxx>
24 : #include <CellMarginHandler.hxx>
25 : #include <ConversionHelper.hxx>
26 : #include <MeasureHandler.hxx>
27 : #include <TablePositionHandler.hxx>
28 : #include <TDefTableHandler.hxx>
29 : #include <com/sun/star/text/HoriOrientation.hpp>
30 : #include <com/sun/star/text/SizeType.hpp>
31 : #include <com/sun/star/text/TableColumnSeparator.hpp>
32 : #include <com/sun/star/text/VertOrientation.hpp>
33 : #include <ooxml/resourceids.hxx>
34 : #include <doctok/sprmids.hxx>
35 : #include <dmapperLoggers.hxx>
36 :
37 : namespace writerfilter {
38 : namespace dmapper {
39 :
40 : using namespace ::com::sun::star;
41 : using namespace ::std;
42 :
43 :
44 594 : DomainMapperTableManager::DomainMapperTableManager(bool bOOXML, bool bImplicitMerges) :
45 : m_nRow(0),
46 : m_nCell(),
47 : m_nGridSpan(1),
48 : m_nGridBefore(0),
49 : m_nGridAfter(0),
50 : m_nCellBorderIndex(0),
51 : m_nHeaderRepeat(0),
52 : m_nTableWidth(0),
53 : m_bOOXML( bOOXML ),
54 : m_bImplicitMerges(bImplicitMerges),
55 : m_bPushCurrentWidth(false),
56 594 : m_pTablePropsHandler( new TablePropertiesHandler( bOOXML ) )
57 : {
58 594 : m_pTablePropsHandler->SetTableManager( this );
59 :
60 : #ifdef DEBUG_DOMAINMAPPER
61 : #ifdef DEBUG_TABLE
62 : setTagLogger(dmapper_logger);
63 : #endif
64 : #endif
65 594 : }
66 :
67 :
68 1782 : DomainMapperTableManager::~DomainMapperTableManager()
69 : {
70 594 : if ( m_pTablePropsHandler )
71 594 : delete m_pTablePropsHandler, m_pTablePropsHandler = NULL;
72 1188 : }
73 :
74 :
75 45428 : bool DomainMapperTableManager::sprm(Sprm & rSprm)
76 : {
77 : #ifdef DEBUG_DOMAINMAPPER
78 : dmapper_logger->startElement("tablemanager.sprm");
79 : string sSprm = rSprm.toString();
80 : dmapper_logger->chars(sSprm);
81 : dmapper_logger->endElement();
82 : #endif
83 45428 : bool bRet = DomainMapperTableManager_Base_t::sprm(rSprm);
84 45428 : if( !bRet )
85 : {
86 42632 : bRet = m_pTablePropsHandler->sprm( rSprm );
87 : }
88 :
89 45428 : if ( !bRet )
90 : {
91 41776 : bRet = true;
92 41776 : sal_uInt32 nSprmId = rSprm.getId();
93 41776 : Value::Pointer_t pValue = rSprm.getValue();
94 41776 : sal_Int32 nIntValue = ((pValue.get() != NULL) ? pValue->getInt() : 0);
95 41776 : switch ( nSprmId )
96 : {
97 : case 0xf661: //sprmTTRLeft left table indent
98 : case 0xf614: // sprmTTPreferredWidth - preferred table width
99 : case NS_ooxml::LN_CT_TblPrBase_tblW: //90722;
100 : case NS_ooxml::LN_CT_TblPrBase_tblInd: //90725
101 : {
102 : //contains unit and value
103 100 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
104 100 : if( pProperties.get())
105 : { //contains attributes x2902 (LN_unit) and x17e2 (LN_trleft)
106 100 : MeasureHandlerPtr pMeasureHandler( new MeasureHandler );
107 100 : pProperties->resolve(*pMeasureHandler);
108 100 : TablePropertyMapPtr pPropMap( new TablePropertyMap );
109 100 : if( nSprmId == 0xf661 || nSprmId == sal_uInt32(NS_ooxml::LN_CT_TblPrBase_tblInd ))
110 : {
111 0 : pPropMap->setValue( TablePropertyMap::LEFT_MARGIN, pMeasureHandler->getMeasureValue() );
112 : }
113 : else
114 : {
115 100 : m_nTableWidth = pMeasureHandler->getMeasureValue();
116 100 : if( m_nTableWidth )
117 52 : pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nTableWidth );
118 : }
119 : #ifdef DEBUG_DOMAINMAPPER
120 : pPropMap->dumpXml( dmapper_logger );
121 : #endif
122 100 : insertTableProps(pPropMap);
123 100 : }
124 : }
125 100 : break;
126 : case 0x3404:// sprmTTableHeader
127 : case NS_ooxml::LN_CT_TrPrBase_tblHeader: //90704
128 : // if nIntValue == 1 then the row is a repeated header line
129 : // to prevent later rows from increasing the repeating m_nHeaderRepeat is set to NULL when repeating stops
130 0 : if( nIntValue > 0 && m_nHeaderRepeat >= 0 )
131 : {
132 0 : ++m_nHeaderRepeat;
133 0 : TablePropertyMapPtr pPropMap( new TablePropertyMap );
134 0 : pPropMap->Insert( PROP_HEADER_ROW_COUNT, false, uno::makeAny( m_nHeaderRepeat ));
135 0 : insertTableProps(pPropMap);
136 : }
137 : else
138 0 : m_nHeaderRepeat = -1;
139 0 : break;
140 : case 0xd608: // TDefTable
141 : {
142 0 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
143 0 : if( pProperties.get())
144 : {
145 0 : TDefTableHandlerPtr pTDefTableHandler( new TDefTableHandler(m_bOOXML) );
146 0 : pProperties->resolve( *pTDefTableHandler );
147 :
148 0 : TablePropertyMapPtr pRowPropMap( new TablePropertyMap );
149 0 : pRowPropMap->InsertProps(pTDefTableHandler->getRowProperties());
150 0 : insertRowProps( pRowPropMap );
151 0 : if( !m_nTableWidth )
152 : {
153 0 : m_nTableWidth= pTDefTableHandler->getTableWidth();
154 0 : if( m_nTableWidth )
155 : {
156 0 : TablePropertyMapPtr pPropMap( new TablePropertyMap );
157 0 : pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nTableWidth );
158 0 : insertTableProps(pPropMap);
159 : }
160 : }
161 0 : for( size_t nCell = 0; nCell < pTDefTableHandler->getCellCount(); ++nCell )
162 : {
163 0 : TablePropertyMapPtr pCellPropMap( new TablePropertyMap );
164 0 : pTDefTableHandler->fillCellProperties( nCell, pCellPropMap );
165 0 : cellPropsByCell( nCell, pCellPropMap );
166 0 : }
167 0 : }
168 : }
169 0 : break;
170 : case 0xD605: // sprmTTableBorders
171 : {
172 0 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
173 0 : if( pProperties.get())
174 : {
175 0 : BorderHandlerPtr pBorderHandler( new BorderHandler(m_bOOXML) );
176 0 : pProperties->resolve(*pBorderHandler);
177 0 : TablePropertyMapPtr pCellPropMap( new TablePropertyMap() );
178 0 : pCellPropMap->InsertProps(pBorderHandler->getProperties());
179 0 : cellPropsByCell( m_nCellBorderIndex, pCellPropMap );
180 0 : ++m_nCellBorderIndex;
181 0 : }
182 : }
183 0 : break;
184 : case 0xd632 : //sprmTNewSpacing
185 : case 0xd634 : //sprmTNewSpacing
186 : //TODO: sprms contain default (TNew) and actual border spacing of cells - not resolvable yet
187 0 : break;
188 : case 0xd613: //sprmTGridLineProps
189 : // TODO: needs a handler
190 : /*contains:
191 : GridLineProps">
192 : rtf:LINEPROPSTOP
193 : rtf:LINEPROPSLEFT
194 : rtf:LINEPROPSBOTTOM
195 : rtf:LINEPROPSRIGHT
196 : rtf:LINEPROPSHORIZONTAL
197 : rtf:LINEPROPSVERTICAL
198 : rtf:LINECOLOR
199 : rtf:LINEWIDTH
200 : rtf:LINETYPE
201 :
202 : */
203 0 : break;
204 : case 0x740a : //sprmTTlp
205 : //TODO: Table look specifier
206 0 : break;
207 : case 0x6816 : //unknown
208 : case 0x3466 : //unknown
209 : case 0x3615 : //unknown
210 : case 0x646b : //unknown - expandable sprm - see ww8scan.cxx
211 : case 0x7479 : //unknown
212 : case 0xf617 : //unknown
213 : case 0xf618 : //unknown
214 0 : bRet = false;
215 0 : break;
216 : case NS_ooxml::LN_CT_TblPrBase_tblStyle: //table style name
217 : {
218 50 : m_sTableStyleName = pValue->getString();
219 50 : TablePropertyMapPtr pPropMap( new TablePropertyMap );
220 50 : pPropMap->Insert( META_PROP_TABLE_STYLE_NAME, false, uno::makeAny( m_sTableStyleName ));
221 50 : insertTableProps(pPropMap);
222 : }
223 50 : break;
224 : case NS_ooxml::LN_CT_TblGridBase_gridCol:
225 : {
226 460 : getCurrentGrid()->push_back( ConversionHelper::convertTwipToMM100( nIntValue ) );
227 : }
228 460 : break;
229 : case NS_ooxml::LN_CT_TcPrBase_vMerge : //vertical merge
230 : {
231 : // values can be: LN_Value_ST_Merge_restart, LN_Value_ST_Merge_continue, in reality the second one is a 0
232 2 : TablePropertyMapPtr pMergeProps( new TablePropertyMap );
233 2 : pMergeProps->Insert( PROP_VERTICAL_MERGE, false, uno::makeAny( bool( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_ST_Merge_restart )) );
234 2 : cellProps( pMergeProps);
235 : }
236 2 : break;
237 : case NS_ooxml::LN_CT_TcPrBase_gridSpan: //number of grid positions spanned by this cell
238 : {
239 : #if DEBUG_DOMAINMAPPER
240 : dmapper_logger->startElement("tablemanager.GridSpan");
241 : dmapper_logger->attribute("gridSpan", nIntValue);
242 : dmapper_logger->endElement();
243 : #endif
244 8 : m_nGridSpan = nIntValue;
245 : }
246 8 : break;
247 : case NS_ooxml::LN_CT_TblPrBase_tblLook:
248 52 : break; //todo: table look specifier
249 : case NS_ooxml::LN_CT_TcPrBase_textDirection:
250 : {
251 118 : TablePropertyMapPtr pPropMap( new TablePropertyMap );
252 118 : const sal_Int16 HORI_LEFT_TOP = 0;
253 118 : const sal_Int16 VERT_TOP_RIGHT = 2;
254 118 : bool bInsertCellProps = true;
255 118 : switch ( nIntValue )
256 : {
257 : case 1: // tbRl
258 : // Binary filter takes BiDirection into account ( but I have no idea about that here )
259 : // or even what it is. But... here's where to handle it if it becomes an issue
260 0 : pPropMap->Insert( PROP_FRM_DIRECTION, false, uno::makeAny( VERT_TOP_RIGHT ));
261 : SAL_INFO( "writerfilter", "Have inserted textDirection " << nIntValue );
262 0 : break;
263 : case 3: // btLr
264 : // We have to fake this text direction
265 0 : pPropMap->Insert( PROP_FRM_DIRECTION, false, uno::makeAny( HORI_LEFT_TOP ));
266 0 : pPropMap->Insert( PROP_CHAR_ROTATION, false, uno::makeAny( sal_Int16( 900 ) ));
267 : SAL_INFO( "writerfilter", "Have inserted textDirection " << nIntValue );
268 0 : break;
269 : case 4: // lrTbV
270 0 : pPropMap->Insert( PROP_FRM_DIRECTION, false, uno::makeAny( HORI_LEFT_TOP ));
271 0 : break;
272 : case 5: // tbRlV
273 0 : pPropMap->Insert( PROP_FRM_DIRECTION, false, uno::makeAny( VERT_TOP_RIGHT ));
274 0 : break;
275 : case 0: // lrTb
276 : case NS_ooxml::LN_Value_ST_TextDirection_tbLrV:
277 : default:
278 : // Ignore - we can't handle these
279 118 : bInsertCellProps = false;
280 118 : break;
281 : }
282 118 : if ( bInsertCellProps )
283 0 : cellProps( pPropMap );
284 118 : break;
285 : }
286 : case NS_ooxml::LN_CT_TcPrBase_tcW:
287 : {
288 : // Contains unit and value, but unit is not interesting for
289 : // us, later we'll just distribute these values in a
290 : // 0..10000 scale.
291 358 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
292 358 : if( pProperties.get())
293 : {
294 358 : MeasureHandlerPtr pMeasureHandler(new MeasureHandler());
295 358 : pProperties->resolve(*pMeasureHandler);
296 358 : getCurrentCellWidths()->push_back(pMeasureHandler->getMeasureValue());
297 358 : if (getTableDepthDifference() > 0)
298 68 : m_bPushCurrentWidth = true;
299 358 : }
300 : }
301 358 : break;
302 : case NS_ooxml::LN_CT_TrPrBase_cnfStyle:
303 : {
304 0 : TablePropertyMapPtr pProps( new TablePropertyMap );
305 0 : pProps->Insert( PROP_CNF_STYLE, true, uno::makeAny( pValue->getString( ) ) );
306 0 : insertRowProps( pProps );
307 : }
308 0 : break;
309 : case NS_ooxml::LN_CT_PPrBase_cnfStyle:
310 : // TODO cnfStyle on a paragraph
311 0 : break;
312 : case NS_ooxml::LN_CT_TcPrBase_cnfStyle:
313 : {
314 0 : TablePropertyMapPtr pProps( new TablePropertyMap );
315 0 : pProps->Insert( PROP_CNF_STYLE, true, uno::makeAny( pValue->getString( ) ) );
316 0 : cellProps( pProps );
317 : }
318 0 : break;
319 : case NS_ooxml::LN_CT_TblPrBase_tblpPr:
320 : {
321 2 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
322 2 : if (pProperties.get())
323 : {
324 2 : TablePositionHandlerPtr pHandler( new TablePositionHandler );
325 2 : pProperties->resolve(*pHandler);
326 2 : m_sTableVertAnchor = pHandler->getVertAnchor();
327 2 : }
328 : }
329 2 : break;
330 : case NS_ooxml::LN_CT_TrPrBase_gridBefore:
331 2 : m_nGridBefore = nIntValue;
332 2 : break;
333 : case NS_ooxml::LN_CT_TrPrBase_gridAfter:
334 2 : m_nGridAfter = nIntValue;
335 2 : break;
336 : default:
337 40622 : bRet = false;
338 :
339 : #ifdef DEBUG_DOMAINMAPPER
340 : dmapper_logger->element("unhandled");
341 : #endif
342 41776 : }
343 : }
344 45428 : return bRet;
345 : }
346 :
347 628 : boost::shared_ptr< vector<sal_Int32> > DomainMapperTableManager::getCurrentGrid( )
348 : {
349 628 : return m_aTableGrid.back( );
350 : }
351 :
352 748 : boost::shared_ptr< vector< sal_Int32 > > DomainMapperTableManager::getCurrentSpans( )
353 : {
354 748 : return m_aGridSpans.back( );
355 : }
356 :
357 526 : boost::shared_ptr< vector< sal_Int32 > > DomainMapperTableManager::getCurrentCellWidths( )
358 : {
359 526 : return m_aCellWidths.back( );
360 : }
361 :
362 116 : const OUString& DomainMapperTableManager::getTableVertAnchor() const
363 : {
364 116 : return m_sTableVertAnchor;
365 : }
366 :
367 708 : void DomainMapperTableManager::startLevel( )
368 : {
369 708 : DomainMapperTableManager_Base_t::startLevel( );
370 :
371 : // If requested, pop the value that was pushed too early.
372 708 : boost::optional<sal_Int32> oCurrentWidth;
373 708 : if (m_bPushCurrentWidth && !m_aCellWidths.empty() && !m_aCellWidths.back()->empty())
374 : {
375 60 : oCurrentWidth.reset(m_aCellWidths.back()->back());
376 60 : m_aCellWidths.back()->pop_back();
377 : }
378 :
379 708 : IntVectorPtr pNewGrid( new vector<sal_Int32> );
380 708 : IntVectorPtr pNewSpans( new vector<sal_Int32> );
381 708 : IntVectorPtr pNewCellWidths( new vector<sal_Int32> );
382 708 : m_aTableGrid.push_back( pNewGrid );
383 708 : m_aGridSpans.push_back( pNewSpans );
384 708 : m_aCellWidths.push_back( pNewCellWidths );
385 708 : m_nCell.push_back( 0 );
386 708 : m_nTableWidth = 0;
387 :
388 : // And push it back to the right level.
389 708 : if (oCurrentWidth)
390 60 : m_aCellWidths.back()->push_back(*oCurrentWidth);
391 708 : }
392 :
393 708 : void DomainMapperTableManager::endLevel( )
394 : {
395 708 : m_aTableGrid.pop_back( );
396 708 : m_aGridSpans.pop_back( );
397 708 : m_aCellWidths.pop_back( );
398 708 : m_nCell.pop_back( );
399 708 : m_nTableWidth = 0;
400 :
401 708 : DomainMapperTableManager_Base_t::endLevel( );
402 : #ifdef DEBUG_DOMAINMAPPER
403 : dmapper_logger->startElement("dmappertablemanager.endLevel");
404 : PropertyMapPtr pProps = getTableProps();
405 : if (pProps.get() != NULL)
406 : getTableProps()->dumpXml( dmapper_logger );
407 :
408 : dmapper_logger->endElement();
409 : #endif
410 708 : }
411 :
412 :
413 :
414 580 : void DomainMapperTableManager::endOfCellAction()
415 : {
416 : #ifdef DEBUG_DOMAINMAPPER
417 : dmapper_logger->element("endOFCellAction");
418 : #endif
419 :
420 580 : getCurrentSpans()->push_back(m_nGridSpan);
421 580 : m_nGridSpan = 1;
422 580 : ++m_nCell.back( );
423 580 : }
424 :
425 :
426 168 : void DomainMapperTableManager::endOfRowAction()
427 : {
428 : #ifdef DEBUG_DOMAINMAPPER
429 : dmapper_logger->startElement("endOfRowAction");
430 : #endif
431 :
432 168 : IntVectorPtr pTableGrid = getCurrentGrid( );
433 168 : IntVectorPtr pCellWidths = getCurrentCellWidths( );
434 168 : if(!m_nTableWidth && pTableGrid->size())
435 : {
436 60 : ::std::vector<sal_Int32>::const_iterator aCellIter = pTableGrid->begin();
437 :
438 : #ifdef DEBUG_DOMAINMAPPER
439 : dmapper_logger->startElement("tableWidth");
440 : #endif
441 :
442 382 : while( aCellIter != pTableGrid->end() )
443 : {
444 : #ifdef DEBUG_DOMAINMAPPER
445 : dmapper_logger->startElement("col");
446 : dmapper_logger->attribute("width", *aCellIter);
447 : dmapper_logger->endElement();
448 : #endif
449 :
450 262 : m_nTableWidth += *aCellIter++;
451 : }
452 :
453 60 : if( m_nTableWidth > 0)
454 : {
455 60 : TablePropertyMapPtr pPropMap( new TablePropertyMap );
456 60 : pPropMap->setValue( TablePropertyMap::TABLE_WIDTH, m_nTableWidth );
457 60 : insertTableProps(pPropMap);
458 : }
459 :
460 : #ifdef DEBUG_DOMAINMAPPER
461 : dmapper_logger->endElement();
462 : #endif
463 : }
464 :
465 168 : IntVectorPtr pCurrentSpans = getCurrentSpans( );
466 168 : if( pCurrentSpans->size() < m_nCell.back( ) )
467 : {
468 : //fill missing elements with '1'
469 0 : pCurrentSpans->insert( pCurrentSpans->end( ), m_nCell.back( ) - pCurrentSpans->size(), 1 );
470 : }
471 :
472 : #ifdef DEBUG_DOMAINMAPPER
473 : dmapper_logger->startElement("gridSpans");
474 : {
475 : ::std::vector<sal_Int32>::const_iterator aGridSpanIter = pCurrentSpans->begin();
476 : ::std::vector<sal_Int32>::const_iterator aGridSpanIterEnd = pCurrentSpans->end();
477 :
478 : while (aGridSpanIter != aGridSpanIterEnd)
479 : {
480 : dmapper_logger->startElement("gridSpan");
481 : dmapper_logger->attribute("span", *aGridSpanIter);
482 : dmapper_logger->endElement();
483 :
484 : ++aGridSpanIter;
485 : }
486 : }
487 : dmapper_logger->endElement();
488 : #endif
489 :
490 : //calculate number of used grids - it has to match the size of m_aTableGrid
491 168 : size_t nGrids = 0;
492 168 : ::std::vector<sal_Int32>::const_iterator aGridSpanIter = pCurrentSpans->begin();
493 748 : for( ; aGridSpanIter != pCurrentSpans->end(); ++aGridSpanIter)
494 580 : nGrids += *aGridSpanIter;
495 :
496 : //determine table width
497 168 : double nFullWidth = m_nTableWidth;
498 : //the positions have to be distibuted in a range of 10000
499 168 : const double nFullWidthRelative = 10000.;
500 168 : if( pTableGrid->size() == ( m_nGridBefore + nGrids + m_nGridAfter ) && m_nCell.back( ) > 0 )
501 : {
502 134 : uno::Sequence< text::TableColumnSeparator > aSeparators( m_nCell.back( ) - 1 );
503 134 : text::TableColumnSeparator* pSeparators = aSeparators.getArray();
504 134 : sal_Int16 nLastRelPos = 0;
505 134 : sal_uInt32 nBorderGridIndex = m_nGridBefore;
506 :
507 134 : ::std::vector< sal_Int32 >::const_iterator aSpansIter = pCurrentSpans->begin( );
508 514 : for( sal_uInt32 nBorder = 0; nBorder < m_nCell.back( ) - 1; ++nBorder )
509 : {
510 380 : sal_Int32 nGridCount = *aSpansIter;
511 380 : double fGridWidth = 0.;
512 394 : do
513 : {
514 394 : fGridWidth += (*pTableGrid.get())[nBorderGridIndex++];
515 : }while( --nGridCount );
516 :
517 : sal_Int16 nRelPos =
518 380 : sal::static_int_cast< sal_Int16 >( floor( fGridWidth * nFullWidthRelative / nFullWidth + 0.5 ) );
519 :
520 380 : pSeparators[nBorder].Position = nRelPos + nLastRelPos;
521 380 : pSeparators[nBorder].IsVisible = sal_True;
522 380 : nLastRelPos = nLastRelPos + nRelPos;
523 380 : ++aSpansIter;
524 : }
525 134 : TablePropertyMapPtr pPropMap( new TablePropertyMap );
526 134 : pPropMap->Insert( PROP_TABLE_COLUMN_SEPARATORS, false, uno::makeAny( aSeparators ) );
527 :
528 : #ifdef DEBUG_DOMAINMAPPER
529 : dmapper_logger->startElement("rowProperties");
530 : pPropMap->dumpXml( dmapper_logger );
531 : dmapper_logger->endElement();
532 : #endif
533 134 : insertRowProps(pPropMap);
534 : }
535 34 : else if (m_bImplicitMerges && pTableGrid->size())
536 : {
537 : // More grid than cells definitions? Then take the last ones.
538 : // This feature is used by the RTF implicit horizontal cell merges.
539 16 : uno::Sequence< text::TableColumnSeparator > aSeparators(m_nCell.back( ) - 1);
540 16 : text::TableColumnSeparator* pSeparators = aSeparators.getArray();
541 :
542 16 : sal_Int16 nSum = 0;
543 16 : sal_uInt32 nPos = 0;
544 16 : sal_uInt32 nSizeTableGrid = pTableGrid->size();
545 : // Ignoring the i=0 case means we assume that the width of the last cell matches the table width
546 34 : for (sal_uInt32 i = m_nCell.back( ); i > 1 && nSizeTableGrid >= i; i--)
547 : {
548 18 : nSum += (*pTableGrid.get())[pTableGrid->size() - i]; // Size of the current cell
549 18 : pSeparators[nPos].Position = nSum * nFullWidthRelative / nFullWidth; // Relative position
550 18 : pSeparators[nPos].IsVisible = sal_True;
551 18 : nPos++;
552 : }
553 :
554 16 : TablePropertyMapPtr pPropMap( new TablePropertyMap );
555 16 : pPropMap->Insert( PROP_TABLE_COLUMN_SEPARATORS, false, uno::makeAny( aSeparators ) );
556 : #ifdef DEBUG_DOMAINMAPPER
557 : dmapper_logger->startElement("rowProperties");
558 : pPropMap->dumpXml( dmapper_logger );
559 : dmapper_logger->endElement();
560 : #endif
561 16 : insertRowProps(pPropMap);
562 : }
563 18 : else if (pCellWidths->size() > 0)
564 : {
565 : // If we're here, then the number of cells does not equal to the amount
566 : // defined by the grid, even after taking care of
567 : // gridSpan/gridBefore/gridAfter. Handle this by ignoring the grid and
568 : // providing the separators based on the provided cell widths.
569 4 : uno::Sequence< text::TableColumnSeparator > aSeparators(pCellWidths->size() - 1);
570 4 : text::TableColumnSeparator* pSeparators = aSeparators.getArray();
571 4 : sal_Int16 nSum = 0;
572 4 : sal_uInt32 nPos = 0;
573 :
574 14 : for (sal_uInt32 i = 0; i < pCellWidths->size() - 1; ++i)
575 : {
576 10 : nSum += (*pCellWidths.get())[i];
577 10 : pSeparators[nPos].Position = nSum * nFullWidthRelative / nFullWidth;
578 10 : pSeparators[nPos].IsVisible = sal_True;
579 10 : nPos++;
580 : }
581 :
582 4 : TablePropertyMapPtr pPropMap( new TablePropertyMap );
583 4 : pPropMap->Insert( PROP_TABLE_COLUMN_SEPARATORS, false, uno::makeAny( aSeparators ) );
584 : #ifdef DEBUG_DOMAINMAPPER
585 : dmapper_logger->startElement("rowProperties");
586 : pPropMap->dumpXml( dmapper_logger );
587 : dmapper_logger->endElement();
588 : #endif
589 4 : insertRowProps(pPropMap);
590 : }
591 :
592 168 : ++m_nRow;
593 168 : m_nCell.back( ) = 0;
594 168 : m_nCellBorderIndex = 0;
595 168 : pCurrentSpans->clear();
596 168 : pCellWidths->clear();
597 :
598 168 : m_nGridBefore = m_nGridAfter = 0;
599 :
600 : #ifdef DEBUG_DOMAINMAPPER
601 : dmapper_logger->endElement();
602 : #endif
603 168 : }
604 :
605 :
606 708 : void DomainMapperTableManager::clearData()
607 : {
608 708 : m_nRow = m_nCellBorderIndex = m_nHeaderRepeat = m_nTableWidth = 0;
609 708 : m_sTableStyleName = OUString();
610 708 : m_sTableVertAnchor = OUString();
611 708 : m_pTableStyleTextProperies.reset();
612 708 : }
613 :
614 :
615 50 : void lcl_CopyTextProperties(PropertyMapPtr pToFill,
616 : const StyleSheetEntry* pStyleSheetEntry, StyleSheetTablePtr pStyleSheetTable)
617 : {
618 50 : if( !pStyleSheetEntry )
619 50 : return;
620 : //fill base style properties first, recursively
621 0 : if( !pStyleSheetEntry->sBaseStyleIdentifier.isEmpty())
622 : {
623 : const StyleSheetEntryPtr pParentStyleSheet =
624 0 : pStyleSheetTable->FindStyleSheetByISTD(pStyleSheetEntry->sBaseStyleIdentifier);
625 : OSL_ENSURE( pParentStyleSheet, "table style not found" );
626 0 : lcl_CopyTextProperties( pToFill, pParentStyleSheet.get( ), pStyleSheetTable);
627 : }
628 :
629 0 : PropertyMap::const_iterator aPropIter = pStyleSheetEntry->pProperties->begin();
630 0 : while(aPropIter != pStyleSheetEntry->pProperties->end())
631 : {
632 : //copy all text properties form the table style to the current run attributes
633 0 : if( aPropIter->first.bIsTextProperty )
634 0 : pToFill->insert(*aPropIter);
635 0 : ++aPropIter;
636 : }
637 : }
638 194 : void DomainMapperTableManager::CopyTextProperties(PropertyMapPtr pContext, StyleSheetTablePtr pStyleSheetTable)
639 : {
640 194 : if( !m_pTableStyleTextProperies.get())
641 : {
642 50 : m_pTableStyleTextProperies.reset( new PropertyMap );
643 : const StyleSheetEntryPtr pStyleSheetEntry = pStyleSheetTable->FindStyleSheetByISTD(
644 50 : m_sTableStyleName);
645 : OSL_ENSURE( pStyleSheetEntry, "table style not found" );
646 50 : lcl_CopyTextProperties(m_pTableStyleTextProperies, pStyleSheetEntry.get( ), pStyleSheetTable);
647 : }
648 194 : pContext->InsertProps(m_pTableStyleTextProperies);
649 194 : }
650 :
651 :
652 30 : }}
653 :
654 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|