Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "BorderHandler.hxx"
21 : #include "CellColorHandler.hxx"
22 : #include "CellMarginHandler.hxx"
23 : #include "ConversionHelper.hxx"
24 : #include "MeasureHandler.hxx"
25 : #include "TrackChangesHandler.hxx"
26 : #include "TablePropertiesHandler.hxx"
27 : #include "TDefTableHandler.hxx"
28 : #include "DomainMapperTableManager.hxx"
29 :
30 : #include <ooxml/resourceids.hxx>
31 :
32 : #include <com/sun/star/text/SizeType.hpp>
33 : #include <com/sun/star/text/VertOrientation.hpp>
34 : #include <oox/token/tokens.hxx>
35 : #include <DomainMapper.hxx>
36 :
37 : using namespace com::sun::star;
38 : using namespace oox;
39 :
40 : namespace writerfilter {
41 : namespace dmapper {
42 :
43 53802 : TablePropertiesHandler::TablePropertiesHandler() :
44 : m_pCurrentInteropGrabBag(nullptr),
45 53802 : m_pTableManager( nullptr )
46 : {
47 53802 : }
48 :
49 :
50 161406 : TablePropertiesHandler::~TablePropertiesHandler( )
51 : {
52 : // Do not delete the table manager... this will be done somewhere else
53 53802 : m_pTableManager = nullptr;
54 107604 : }
55 :
56 493033 : bool TablePropertiesHandler::sprm(Sprm & rSprm)
57 : {
58 : #ifdef DEBUG_WRITERFILTER
59 : TagLogger::getInstance().startElement("TablePropertiesHandler.sprm");
60 : TagLogger::getInstance().attribute("sprm", rSprm.toString());
61 : #endif
62 :
63 493033 : bool bRet = true;
64 493033 : sal_uInt32 nSprmId = rSprm.getId();
65 493033 : Value::Pointer_t pValue = rSprm.getValue();
66 493033 : sal_Int32 nIntValue = ((pValue.get() != nullptr) ? pValue->getInt() : 0);
67 493033 : switch( nSprmId )
68 : {
69 : case NS_ooxml::LN_CT_TrPrBase_jc:
70 : case NS_ooxml::LN_CT_TblPrBase_jc:
71 : {
72 1499 : sal_Int16 nOrient = ConversionHelper::convertTableJustification( nIntValue );
73 1499 : TablePropertyMapPtr pTableMap( new TablePropertyMap );
74 1499 : pTableMap->setValue( TablePropertyMap::HORI_ORIENT, nOrient );
75 1499 : insertTableProps( pTableMap );
76 : }
77 1499 : break;
78 : case NS_ooxml::LN_CT_TrPrBase_trHeight:
79 : {
80 : //contains unit and value
81 1407 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
82 1407 : if( pProperties.get())
83 : { //contains attributes x2902 (LN_unit) and x17e2 (LN_trleft)
84 1407 : MeasureHandlerPtr pMeasureHandler( new MeasureHandler );
85 1407 : pProperties->resolve(*pMeasureHandler);
86 2814 : TablePropertyMapPtr pPropMap( new TablePropertyMap );
87 :
88 1407 : DomainMapperTableManager* pManager = dynamic_cast<DomainMapperTableManager*>(m_pTableManager);
89 : // In case any of the cells has the btLr cell direction, then an explicit minimal size will just hide the whole row, don't do that.
90 1407 : const int MINLAY = 23; // sw/inc/swtypes.hxx, minimal possible size of frames.
91 1407 : if (!pManager || !pManager->HasBtlrCell() || pMeasureHandler->getMeasureValue() > ConversionHelper::convertTwipToMM100(MINLAY))
92 : {
93 : // In case a cell already wanted fixed size, we should not overwrite it here.
94 1405 : if (!pManager || !pManager->IsRowSizeTypeInserted())
95 1400 : pPropMap->Insert( PROP_SIZE_TYPE, uno::makeAny( pMeasureHandler->GetRowHeightSizeType() ), false);
96 : else
97 5 : pPropMap->Insert( PROP_SIZE_TYPE, uno::makeAny(text::SizeType::FIX), false);
98 :
99 1405 : pPropMap->Insert( PROP_HEIGHT, uno::makeAny(pMeasureHandler->getMeasureValue() ));
100 : }
101 2814 : insertRowProps(pPropMap);
102 1407 : }
103 : }
104 1407 : break;
105 : case NS_ooxml::LN_CT_TrPr_ins:
106 : case NS_ooxml::LN_CT_TrPr_del:
107 : {
108 28 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
109 28 : if( pProperties.get())
110 : {
111 28 : sal_Int32 nToken = sal_Int32();
112 28 : switch( nSprmId )
113 : {
114 : case NS_ooxml::LN_CT_TrPr_ins:
115 3 : nToken = XML_tableRowInsert;
116 3 : break;
117 : case NS_ooxml::LN_CT_TrPr_del:
118 25 : nToken = XML_tableRowDelete;
119 25 : break;
120 : };
121 28 : TrackChangesHandlerPtr pTrackChangesHandler( new TrackChangesHandler( nToken ) );
122 28 : pProperties->resolve(*pTrackChangesHandler);
123 56 : TablePropertyMapPtr pPropMap( new TablePropertyMap );
124 :
125 : // Add the 'track changes' properties to the 'table row' via UNO.
126 : // This way - in the SW core - when it receives this - it will create a new 'Table Redline' object for that row
127 56 : uno::Sequence<beans::PropertyValue> aTableRedlineProperties = pTrackChangesHandler->getRedlineProperties();
128 28 : pPropMap->Insert( PROP_TABLE_REDLINE_PARAMS , uno::makeAny( aTableRedlineProperties ));
129 56 : insertRowProps(pPropMap);
130 28 : }
131 : }
132 28 : break;
133 : case NS_ooxml::LN_CT_TcPrBase_cellIns:
134 : case NS_ooxml::LN_CT_TcPrBase_cellDel:
135 : {
136 6 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
137 6 : if( pProperties.get())
138 : {
139 : sal_Int32 nToken;
140 6 : switch( nSprmId )
141 : {
142 : case NS_ooxml::LN_CT_TcPrBase_cellIns:
143 3 : nToken = XML_tableCellInsert;
144 3 : break;
145 : case NS_ooxml::LN_CT_TcPrBase_cellDel:
146 3 : nToken = XML_tableCellDelete;
147 3 : break;
148 : default:
149 0 : throw lang::IllegalArgumentException("illegal redline token type", nullptr, 0);
150 : break;
151 : };
152 6 : TrackChangesHandlerPtr pTrackChangesHandler( new TrackChangesHandler( nToken ) );
153 6 : pProperties->resolve(*pTrackChangesHandler);
154 12 : TablePropertyMapPtr pPropMap( new TablePropertyMap );
155 :
156 : // Add the 'track changes' properties to the 'table row' via UNO.
157 : // This way - in the SW core - when it receives this - it will create a new 'Table Redline' object for that row
158 12 : uno::Sequence<beans::PropertyValue> aTableRedlineProperties = pTrackChangesHandler->getRedlineProperties();
159 6 : pPropMap->Insert( PROP_TABLE_REDLINE_PARAMS , uno::makeAny( aTableRedlineProperties ));
160 12 : cellProps(pPropMap);
161 6 : }
162 : }
163 6 : break;
164 : case NS_ooxml::LN_CT_TrPrBase_cantSplit:
165 : {
166 : //row can't break across pages if nIntValue == 1
167 158 : TablePropertyMapPtr pPropMap( new TablePropertyMap );
168 158 : pPropMap->Insert( PROP_IS_SPLIT_ALLOWED, uno::makeAny( nIntValue != 1 ) );
169 158 : insertRowProps(pPropMap);
170 : }
171 158 : break;
172 : case NS_ooxml::LN_CT_TcPrBase_vAlign:
173 : {
174 1780 : sal_Int16 nVertOrient = text::VertOrientation::NONE;
175 1780 : switch( nIntValue )
176 : {
177 1149 : case NS_ooxml::LN_Value_ST_VerticalJc_center: nVertOrient = text::VertOrientation::CENTER; break;
178 383 : case NS_ooxml::LN_Value_ST_VerticalJc_bottom: nVertOrient = text::VertOrientation::BOTTOM; break;
179 : default:;
180 : };
181 1780 : TablePropertyMapPtr pCellPropMap( new TablePropertyMap() );
182 1780 : pCellPropMap->Insert( PROP_VERT_ORIENT, uno::makeAny( nVertOrient ) );
183 : //todo: in ooxml import the value of m_ncell is wrong
184 1780 : cellProps( pCellPropMap );
185 1780 : if (m_pCurrentInteropGrabBag)
186 : {
187 53 : OUString aVertOrient;
188 53 : switch( nIntValue )
189 : {
190 20 : case NS_ooxml::LN_Value_ST_VerticalJc_top: aVertOrient = "top"; break;
191 30 : case NS_ooxml::LN_Value_ST_VerticalJc_center: aVertOrient = "center"; break;
192 0 : case NS_ooxml::LN_Value_ST_VerticalJc_both: aVertOrient = "both"; break;
193 3 : case NS_ooxml::LN_Value_ST_VerticalJc_bottom: aVertOrient = "bottom"; break;
194 : };
195 53 : if (!aVertOrient.isEmpty())
196 : {
197 53 : beans::PropertyValue aValue;
198 53 : aValue.Name = "vAlign";
199 53 : aValue.Value = uno::makeAny(aVertOrient);
200 53 : m_pCurrentInteropGrabBag->push_back(aValue);
201 53 : }
202 1780 : }
203 : }
204 1780 : break;
205 : case NS_ooxml::LN_CT_TblPrBase_tblBorders: //table borders, might be defined in table style
206 : {
207 2222 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
208 2222 : if( pProperties.get())
209 : {
210 2222 : BorderHandlerPtr pBorderHandler(new BorderHandler(true));
211 2222 : if (m_pCurrentInteropGrabBag)
212 978 : pBorderHandler->enableInteropGrabBag("tblBorders");
213 2222 : pProperties->resolve(*pBorderHandler);
214 2222 : if (m_pCurrentInteropGrabBag)
215 978 : m_pCurrentInteropGrabBag->push_back(pBorderHandler->getInteropGrabBag());
216 4444 : TablePropertyMapPtr pTablePropMap( new TablePropertyMap );
217 2222 : pTablePropMap->InsertProps(pBorderHandler->getProperties());
218 :
219 : #ifdef DEBUG_WRITERFILTER
220 : pTablePropMap->dumpXml();
221 : #endif
222 4444 : insertTableProps( pTablePropMap );
223 2222 : }
224 : }
225 2222 : break;
226 : case NS_ooxml::LN_CT_TblPrBase_tblLayout:
227 : {
228 198 : DomainMapperTableManager* pManager = dynamic_cast<DomainMapperTableManager*>(m_pTableManager);
229 198 : if (pManager)
230 198 : pManager->SetLayoutType(static_cast<sal_uInt32>(nIntValue));
231 : }
232 198 : break;
233 : case NS_ooxml::LN_CT_TcPrBase_tcBorders ://cell borders
234 : //contains CT_TcBorders_left, right, top, bottom
235 : {
236 6462 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
237 6462 : if( pProperties.get())
238 : {
239 : //in OOXML there's one set of borders at each cell (if there is any)
240 6462 : TDefTableHandlerPtr pTDefTableHandler( new TDefTableHandler());
241 6462 : if (m_pCurrentInteropGrabBag)
242 2167 : pTDefTableHandler->enableInteropGrabBag("tcBorders");
243 6462 : pProperties->resolve( *pTDefTableHandler );
244 6462 : if (m_pCurrentInteropGrabBag)
245 2167 : m_pCurrentInteropGrabBag->push_back(pTDefTableHandler->getInteropGrabBag());
246 12924 : TablePropertyMapPtr pCellPropMap( new TablePropertyMap );
247 6462 : pTDefTableHandler->fillCellProperties( 0, pCellPropMap );
248 12924 : cellProps( pCellPropMap );
249 6462 : }
250 : }
251 6462 : break;
252 : case NS_ooxml::LN_CT_TcPrBase_tcMar:
253 :
254 : {
255 1703 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
256 1703 : if (pProperties.get())
257 : {
258 1703 : CellMarginHandlerPtr pCellMarginHandler(new CellMarginHandler);
259 1703 : if (m_pCurrentInteropGrabBag)
260 56 : pCellMarginHandler->enableInteropGrabBag("tcMar");
261 1703 : pProperties->resolve(*pCellMarginHandler);
262 1703 : if (m_pCurrentInteropGrabBag)
263 56 : m_pCurrentInteropGrabBag->push_back(pCellMarginHandler->getInteropGrabBag());
264 3406 : TablePropertyMapPtr pCellProperties(new TablePropertyMap);
265 1703 : if (pCellMarginHandler->m_bTopMarginValid)
266 177 : pCellProperties->Insert(PROP_TOP_BORDER_DISTANCE, uno::makeAny(pCellMarginHandler->m_nTopMargin));
267 1703 : if (pCellMarginHandler->m_bLeftMarginValid)
268 447 : pCellProperties->Insert(PROP_LEFT_BORDER_DISTANCE, uno::makeAny(pCellMarginHandler->m_nLeftMargin));
269 1703 : if (pCellMarginHandler->m_bBottomMarginValid)
270 177 : pCellProperties->Insert(PROP_BOTTOM_BORDER_DISTANCE, uno::makeAny(pCellMarginHandler->m_nBottomMargin));
271 1703 : if (pCellMarginHandler->m_bRightMarginValid)
272 137 : pCellProperties->Insert(PROP_RIGHT_BORDER_DISTANCE, uno::makeAny(pCellMarginHandler->m_nRightMargin));
273 3406 : cellProps(pCellProperties);
274 1703 : }
275 : }
276 1703 : break;
277 : case NS_ooxml::LN_CT_TblPrBase_shd:
278 : {
279 96 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
280 96 : if( pProperties.get())
281 : {
282 96 : CellColorHandlerPtr pCellColorHandler( new CellColorHandler);
283 96 : pProperties->resolve( *pCellColorHandler );
284 192 : TablePropertyMapPtr pTablePropMap( new TablePropertyMap );
285 192 : insertTableProps( pCellColorHandler->getProperties() );
286 96 : }
287 : }
288 96 : break;
289 : case NS_ooxml::LN_CT_TcPrBase_shd:
290 : {
291 : // each color sprm contains as much colors as cells are in a row
292 : //LN_CT_TcPrBase_shd: cell shading contains: LN_CT_Shd_val, LN_CT_Shd_fill, LN_CT_Shd_color
293 4885 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
294 4885 : if( pProperties.get())
295 : {
296 4885 : CellColorHandlerPtr pCellColorHandler( new CellColorHandler );
297 4885 : pCellColorHandler->enableInteropGrabBag("shd"); //enable to store shd unsupported props in grab bag
298 4885 : pProperties->resolve( *pCellColorHandler );
299 9770 : TablePropertyMapPtr pPropertyMap = pCellColorHandler->getProperties();
300 9770 : beans::PropertyValue aGrabBag = pCellColorHandler->getInteropGrabBag();
301 4885 : if (m_pCurrentInteropGrabBag)
302 1217 : m_pCurrentInteropGrabBag->push_back(aGrabBag);
303 4885 : pPropertyMap->Insert( PROP_CELL_INTEROP_GRAB_BAG, aGrabBag.Value );
304 9770 : cellProps( pPropertyMap );
305 4885 : }
306 : }
307 4885 : break;
308 : //OOXML table properties
309 : case NS_ooxml::LN_CT_TblPrBase_tblCellMar: //cell margins
310 : {
311 : //contains LN_CT_TblCellMar_top, LN_CT_TblCellMar_left, LN_CT_TblCellMar_bottom, LN_CT_TblCellMar_right
312 : // LN_CT_TblCellMar_start, LN_CT_TblCellMar_end
313 3780 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
314 3780 : if( pProperties.get())
315 : {
316 3780 : CellMarginHandlerPtr pCellMarginHandler( new CellMarginHandler );
317 3780 : if (m_pCurrentInteropGrabBag)
318 2492 : pCellMarginHandler->enableInteropGrabBag("tblCellMar");
319 3780 : pProperties->resolve( *pCellMarginHandler );
320 3780 : if (m_pCurrentInteropGrabBag)
321 2492 : m_pCurrentInteropGrabBag->push_back(pCellMarginHandler->getInteropGrabBag());
322 7560 : TablePropertyMapPtr pMarginProps( new TablePropertyMap );
323 3780 : if( pCellMarginHandler->m_bTopMarginValid )
324 3404 : pMarginProps->setValue( TablePropertyMap::CELL_MAR_TOP, pCellMarginHandler->m_nTopMargin );
325 3780 : if( pCellMarginHandler->m_bBottomMarginValid )
326 3404 : pMarginProps->setValue( TablePropertyMap::CELL_MAR_BOTTOM, pCellMarginHandler->m_nBottomMargin );
327 3780 : if( pCellMarginHandler->m_bLeftMarginValid )
328 3778 : pMarginProps->setValue( TablePropertyMap::CELL_MAR_LEFT, pCellMarginHandler->m_nLeftMargin );
329 3780 : if( pCellMarginHandler->m_bRightMarginValid )
330 3707 : pMarginProps->setValue( TablePropertyMap::CELL_MAR_RIGHT, pCellMarginHandler->m_nRightMargin );
331 7560 : insertTableProps(pMarginProps);
332 3780 : }
333 : }
334 3780 : break;
335 : case NS_ooxml::LN_CT_TblPrBase_tblInd:
336 : {
337 3681 : writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
338 3681 : if (pProperties.get())
339 : {
340 3681 : MeasureHandlerPtr pHandler(new MeasureHandler);
341 3681 : if (m_pCurrentInteropGrabBag)
342 2494 : pHandler->enableInteropGrabBag("tblInd");
343 3681 : pProperties->resolve( *pHandler );
344 3681 : if (m_pCurrentInteropGrabBag)
345 2494 : m_pCurrentInteropGrabBag->push_back(pHandler->getInteropGrabBag());
346 7362 : TablePropertyMapPtr pTblIndMap(new TablePropertyMap);
347 3681 : sal_uInt32 nTblInd = pHandler->getMeasureValue();
348 3681 : pTblIndMap->setValue( TablePropertyMap::LEFT_MARGIN, nTblInd);
349 7362 : insertTableProps(pTblIndMap);
350 3681 : }
351 : }
352 3681 : break;
353 : case NS_ooxml::LN_CT_TcPrBase_hideMark:
354 1642 : if (nIntValue)
355 : {
356 1642 : TablePropertyMapPtr pPropMap(new TablePropertyMap());
357 1642 : pPropMap->Insert(PROP_CELL_HIDE_MARK, uno::makeAny(nIntValue));
358 1642 : cellProps(pPropMap);
359 : }
360 1642 : break;
361 : default:
362 : // Not handled here, give the next handler a chance.
363 463486 : bRet = false;
364 : // However, these logically belong here, so save the value if necessary.
365 463486 : switch (nSprmId)
366 : {
367 : case NS_ooxml::LN_CT_TblPrBase_tblStyleRowBandSize:
368 : case NS_ooxml::LN_CT_TblPrBase_tblStyleColBandSize:
369 670 : if (m_pCurrentInteropGrabBag)
370 : {
371 332 : beans::PropertyValue aValue;
372 332 : aValue.Name = (nSprmId == NS_ooxml::LN_CT_TblPrBase_tblStyleRowBandSize ? OUString("tblStyleRowBandSize") : OUString("tblStyleColBandSize"));
373 332 : aValue.Value = uno::makeAny(nIntValue);
374 332 : m_pCurrentInteropGrabBag->push_back(aValue);
375 : }
376 670 : break;
377 : }
378 463486 : break;
379 : }
380 :
381 : #ifdef DEBUG_WRITERFILTER
382 : TagLogger::getInstance().endElement();
383 : #endif
384 :
385 493033 : return bRet;
386 : }
387 :
388 14359 : void TablePropertiesHandler::SetInteropGrabBag(std::vector<beans::PropertyValue>& rValue)
389 : {
390 14359 : m_pCurrentInteropGrabBag = &rValue;
391 14359 : }
392 : }}
393 :
394 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|