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 "drawingml/table/tablecell.hxx"
21 : #include "drawingml/table/tableproperties.hxx"
22 : #include <basegfx/color/bcolor.hxx>
23 : #include "oox/drawingml/shapepropertymap.hxx"
24 : #include "drawingml/textbody.hxx"
25 : #include "oox/drawingml/theme.hxx"
26 : #include "oox/core/xmlfilterbase.hxx"
27 : #include "oox/helper/propertyset.hxx"
28 : #include <tools/color.hxx>
29 : #include <com/sun/star/container/XNameContainer.hpp>
30 : #include <com/sun/star/beans/XMultiPropertySet.hpp>
31 : #include <com/sun/star/table/XTable.hpp>
32 : #include <com/sun/star/table/XMergeableCellRange.hpp>
33 : #include <com/sun/star/table/BorderLine2.hpp>
34 : #include <com/sun/star/drawing/LineStyle.hpp>
35 : #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
36 : #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
37 : #include <com/sun/star/text/XText.hpp>
38 : #include <com/sun/star/text/WritingMode.hpp>
39 :
40 : using namespace ::oox::core;
41 : using namespace ::com::sun::star;
42 : using namespace ::com::sun::star::uno;
43 : using namespace ::com::sun::star::beans;
44 : using ::com::sun::star::table::BorderLine2;
45 :
46 : namespace oox { namespace drawingml { namespace table {
47 :
48 88 : TableCell::TableCell()
49 0 : : mpTextBody( new TextBody() )
50 : , mnRowSpan ( 1 )
51 : , mnGridSpan( 1 )
52 : , mbhMerge( false )
53 : , mbvMerge( false )
54 : , mnMarL( 91440 )
55 : , mnMarR( 91440 )
56 : , mnMarT( 45720 )
57 : , mnMarB( 45720 )
58 : , mnVertToken( XML_horz )
59 : , mnAnchorToken( XML_t )
60 : , mbAnchorCtr( false )
61 88 : , mnHorzOverflowToken( XML_clip )
62 : {
63 88 : }
64 254 : TableCell::~TableCell()
65 : {
66 254 : }
67 :
68 528 : void applyLineAttributes( const ::oox::core::XmlFilterBase& rFilterBase,
69 : Reference< XPropertySet >& rxPropSet, oox::drawingml::LineProperties& rLineProperties,
70 : sal_Int32 nPropId )
71 : {
72 528 : BorderLine2 aBorderLine;
73 528 : if( rLineProperties.maLineFill.moFillType.differsFrom( XML_noFill ) )
74 : {
75 342 : Color aColor = rLineProperties.maLineFill.getBestSolidColor();
76 342 : aBorderLine.Color = aColor.getColor( rFilterBase.getGraphicHelper() );
77 342 : aBorderLine.OuterLineWidth = static_cast< sal_Int16 >( GetCoordinate( rLineProperties.moLineWidth.get( 0 ) ) / 4 );
78 342 : aBorderLine.InnerLineWidth = static_cast< sal_Int16 >( GetCoordinate( rLineProperties.moLineWidth.get( 0 ) ) / 4 );
79 342 : aBorderLine.LineWidth = static_cast< sal_Int16 >( GetCoordinate( rLineProperties.moLineWidth.get( 0 ) ) / 2 );
80 342 : aBorderLine.LineDistance = 0;
81 : }
82 :
83 528 : PropertySet aPropSet( rxPropSet );
84 528 : aPropSet.setProperty( nPropId, aBorderLine );
85 528 : }
86 :
87 1248 : void applyBorder( const ::oox::core::XmlFilterBase& rFilterBase, TableStylePart& rTableStylePart, sal_Int32 nLineType, oox::drawingml::LineProperties& rLineProperties )
88 : {
89 1248 : std::map < sal_Int32, ::oox::drawingml::LinePropertiesPtr >& rPartLineBorders( rTableStylePart.getLineBorders() );
90 1248 : ::oox::drawingml::ShapeStyleRef& rLineStyleRef = rTableStylePart.getStyleRefs()[ nLineType ];
91 1248 : std::map < sal_Int32, ::oox::drawingml::LinePropertiesPtr >::const_iterator aIter( rPartLineBorders.find( nLineType ) );
92 1248 : if ( ( aIter != rPartLineBorders.end() ) && aIter->second.get() )
93 186 : rLineProperties.assignUsed( *aIter->second );
94 1062 : else if (rLineStyleRef.mnThemedIdx != 0)
95 : {
96 192 : if (const Theme* pTheme = rFilterBase.getCurrentTheme())
97 : {
98 192 : rLineProperties.assignUsed( *pTheme->getLineStyle(rLineStyleRef.mnThemedIdx) );
99 192 : sal_Int32 nPhClr = rLineStyleRef.maPhClr.getColor( rFilterBase.getGraphicHelper() );
100 192 : rLineProperties.maLineFill.maFillColor.setSrgbClr( nPhClr );
101 : }
102 : }
103 1248 : }
104 :
105 208 : void applyTableStylePart( const ::oox::core::XmlFilterBase& rFilterBase,
106 : oox::drawingml::FillProperties& rFillProperties,
107 : TextCharacterProperties& aTextCharProps,
108 : oox::drawingml::LineProperties& rLeftBorder,
109 : oox::drawingml::LineProperties& rRightBorder,
110 : oox::drawingml::LineProperties& rTopBorder,
111 : oox::drawingml::LineProperties& rBottomBorder,
112 : oox::drawingml::LineProperties& rTopLeftToBottomRightBorder,
113 : oox::drawingml::LineProperties& rBottomLeftToTopRightBorder,
114 : TableStylePart& rTableStylePart )
115 : {
116 208 : ::oox::drawingml::FillPropertiesPtr& rPartFillPropertiesPtr( rTableStylePart.getFillProperties() );
117 208 : if ( rPartFillPropertiesPtr.get() )
118 156 : rFillProperties.assignUsed( *rPartFillPropertiesPtr );
119 :
120 208 : applyBorder( rFilterBase, rTableStylePart, XML_left, rLeftBorder );
121 208 : applyBorder( rFilterBase, rTableStylePart, XML_right, rRightBorder );
122 208 : applyBorder( rFilterBase, rTableStylePart, XML_top, rTopBorder );
123 208 : applyBorder( rFilterBase, rTableStylePart, XML_bottom, rBottomBorder );
124 208 : applyBorder( rFilterBase, rTableStylePart, XML_tl2br, rTopLeftToBottomRightBorder );
125 208 : applyBorder( rFilterBase, rTableStylePart, XML_tr2bl, rBottomLeftToTopRightBorder );
126 :
127 208 : aTextCharProps.maLatinFont = rTableStylePart.getLatinFont();
128 208 : aTextCharProps.maAsianFont = rTableStylePart.getAsianFont();
129 208 : aTextCharProps.maComplexFont = rTableStylePart.getComplexFont();
130 208 : aTextCharProps.maSymbolFont = rTableStylePart.getSymbolFont();
131 208 : if (rTableStylePart.getTextColor().isUsed())
132 124 : aTextCharProps.maCharColor = rTableStylePart.getTextColor();
133 208 : if( rTableStylePart.getTextBoldStyle().is_initialized() )
134 36 : aTextCharProps.moBold = *rTableStylePart.getTextBoldStyle();
135 208 : if( rTableStylePart.getTextItalicStyle().is_initialized() )
136 0 : aTextCharProps.moItalic = *rTableStylePart.getTextItalicStyle();
137 208 : }
138 :
139 88 : void applyTableCellProperties( const Reference < ::com::sun::star::table::XCell >& rxCell, const TableCell& rTableCell )
140 : {
141 88 : Reference< XPropertySet > xPropSet( rxCell, UNO_QUERY_THROW );
142 88 : xPropSet->setPropertyValue( "TextUpperDistance", Any( static_cast< sal_Int32 >( rTableCell.getTopMargin() / 360 ) ) );
143 88 : xPropSet->setPropertyValue( "TextRightDistance", Any( static_cast< sal_Int32 >( rTableCell.getRightMargin() / 360 ) ) );
144 88 : xPropSet->setPropertyValue( "TextLeftDistance", Any( static_cast< sal_Int32 >( rTableCell.getLeftMargin() / 360 ) ) );
145 88 : xPropSet->setPropertyValue( "TextLowerDistance", Any( static_cast< sal_Int32 >( rTableCell.getBottomMargin() / 360 ) ) );
146 :
147 : drawing::TextVerticalAdjust eVA;
148 88 : switch( rTableCell.getAnchorToken() )
149 : {
150 0 : case XML_ctr: eVA = drawing::TextVerticalAdjust_CENTER; break;
151 0 : case XML_b: eVA = drawing::TextVerticalAdjust_BOTTOM; break;
152 : case XML_just:
153 : case XML_dist:
154 : default:
155 88 : case XML_t: eVA = drawing::TextVerticalAdjust_TOP; break;
156 : }
157 88 : xPropSet->setPropertyValue( "TextVerticalAdjust", Any( eVA ) );
158 88 : }
159 :
160 88 : void TableCell::pushToXCell( const ::oox::core::XmlFilterBase& rFilterBase, ::oox::drawingml::TextListStylePtr pMasterTextListStyle,
161 : const ::com::sun::star::uno::Reference < ::com::sun::star::table::XCell >& rxCell, const TableProperties& rTableProperties,
162 : const TableStyle& rTableStyle, sal_Int32 nColumn, sal_Int32 nMaxColumn, sal_Int32 nRow, sal_Int32 nMaxRow )
163 : {
164 88 : TableStyle& rTable( const_cast< TableStyle& >( rTableStyle ) );
165 88 : TableProperties& rProperties( const_cast< TableProperties& >( rTableProperties ) );
166 :
167 88 : Reference< text::XText > xText( rxCell, UNO_QUERY_THROW );
168 176 : Reference< text::XTextCursor > xAt = xText->createTextCursor();
169 :
170 88 : applyTableCellProperties( rxCell, *this );
171 176 : TextCharacterProperties aTextStyleProps;
172 88 : xAt->gotoStart( sal_True );
173 176 : Reference< text::XTextRange > xStart( xAt, UNO_QUERY );
174 88 : xAt->gotoEnd( sal_True );
175 :
176 176 : Reference< XPropertySet > xPropSet( rxCell, UNO_QUERY_THROW );
177 176 : oox::drawingml::FillProperties aFillProperties;
178 176 : oox::drawingml::LineProperties aLinePropertiesLeft;
179 176 : oox::drawingml::LineProperties aLinePropertiesRight;
180 176 : oox::drawingml::LineProperties aLinePropertiesTop;
181 176 : oox::drawingml::LineProperties aLinePropertiesBottom;
182 176 : oox::drawingml::LineProperties aLinePropertiesTopLeftToBottomRight;
183 176 : oox::drawingml::LineProperties aLinePropertiesBottomLeftToTopRight;
184 :
185 : applyTableStylePart( rFilterBase, aFillProperties, aTextStyleProps,
186 : aLinePropertiesLeft,
187 : aLinePropertiesRight,
188 : aLinePropertiesTop,
189 : aLinePropertiesBottom,
190 : aLinePropertiesTopLeftToBottomRight,
191 : aLinePropertiesBottomLeftToTopRight,
192 88 : rTable.getWholeTbl() );
193 :
194 88 : if ( rProperties.isFirstRow() && ( nRow == 0 ) )
195 : {
196 : applyTableStylePart( rFilterBase, aFillProperties, aTextStyleProps,
197 : aLinePropertiesLeft,
198 : aLinePropertiesRight,
199 : aLinePropertiesTop,
200 : aLinePropertiesBottom,
201 : aLinePropertiesTopLeftToBottomRight,
202 : aLinePropertiesBottomLeftToTopRight,
203 8 : rTable.getFirstRow() );
204 : }
205 88 : if ( rProperties.isLastRow() && ( nRow == nMaxRow ) )
206 : {
207 : applyTableStylePart( rFilterBase, aFillProperties, aTextStyleProps,
208 : aLinePropertiesLeft,
209 : aLinePropertiesRight,
210 : aLinePropertiesTop,
211 : aLinePropertiesBottom,
212 : aLinePropertiesTopLeftToBottomRight,
213 : aLinePropertiesBottomLeftToTopRight,
214 8 : rTable.getLastRow() );
215 : }
216 88 : if ( rProperties.isFirstCol() && ( nColumn == 0 ) )
217 : {
218 : applyTableStylePart( rFilterBase, aFillProperties, aTextStyleProps,
219 : aLinePropertiesLeft,
220 : aLinePropertiesRight,
221 : aLinePropertiesTop,
222 : aLinePropertiesBottom,
223 : aLinePropertiesTopLeftToBottomRight,
224 : aLinePropertiesBottomLeftToTopRight,
225 10 : rTable.getFirstCol() );
226 : }
227 88 : if ( rProperties.isLastCol() && ( nColumn == nMaxColumn ) )
228 : {
229 : applyTableStylePart( rFilterBase, aFillProperties, aTextStyleProps,
230 : aLinePropertiesLeft,
231 : aLinePropertiesRight,
232 : aLinePropertiesTop,
233 : aLinePropertiesBottom,
234 : aLinePropertiesTopLeftToBottomRight,
235 : aLinePropertiesBottomLeftToTopRight,
236 10 : rTable.getLastCol() );
237 : }
238 88 : if ( rProperties.isBandRow() )
239 : {
240 296 : if ( ( !rProperties.isFirstRow() || ( nRow != 0 ) ) &&
241 184 : ( !rProperties.isLastRow() || ( nRow != nMaxRow ) ) &&
242 310 : ( !rProperties.isFirstCol() || ( nColumn != 0 ) ) &&
243 84 : ( !rProperties.isLastCol() || ( nColumn != nMaxColumn ) ) )
244 : {
245 60 : sal_Int32 nBand = nRow;
246 60 : if ( rProperties.isFirstRow() )
247 12 : nBand++;
248 60 : if ( nBand & 1 )
249 : {
250 : applyTableStylePart( rFilterBase, aFillProperties, aTextStyleProps,
251 : aLinePropertiesLeft,
252 : aLinePropertiesRight,
253 : aLinePropertiesTop,
254 : aLinePropertiesBottom,
255 : aLinePropertiesTopLeftToBottomRight,
256 : aLinePropertiesBottomLeftToTopRight,
257 28 : rTable.getBand2H() );
258 : }
259 : else
260 : {
261 : applyTableStylePart( rFilterBase, aFillProperties, aTextStyleProps,
262 : aLinePropertiesLeft,
263 : aLinePropertiesRight,
264 : aLinePropertiesTop,
265 : aLinePropertiesBottom,
266 : aLinePropertiesTopLeftToBottomRight,
267 : aLinePropertiesBottomLeftToTopRight,
268 32 : rTable.getBand1H() );
269 : }
270 : }
271 : }
272 88 : if ( ( nRow == 0 ) && ( nColumn == 0 ) )
273 : {
274 : applyTableStylePart( rFilterBase, aFillProperties, aTextStyleProps,
275 : aLinePropertiesLeft,
276 : aLinePropertiesRight,
277 : aLinePropertiesTop,
278 : aLinePropertiesBottom,
279 : aLinePropertiesTopLeftToBottomRight,
280 : aLinePropertiesBottomLeftToTopRight,
281 6 : rTable.getNwCell() );
282 : }
283 88 : if ( ( nRow == nMaxRow ) && ( nColumn == 0 ) )
284 : {
285 : applyTableStylePart( rFilterBase, aFillProperties, aTextStyleProps,
286 : aLinePropertiesLeft,
287 : aLinePropertiesRight,
288 : aLinePropertiesTop,
289 : aLinePropertiesBottom,
290 : aLinePropertiesTopLeftToBottomRight,
291 : aLinePropertiesBottomLeftToTopRight,
292 6 : rTable.getSwCell() );
293 : }
294 88 : if ( ( nRow == 0 ) && ( nColumn == nMaxColumn ) )
295 : {
296 : applyTableStylePart( rFilterBase, aFillProperties, aTextStyleProps,
297 : aLinePropertiesLeft,
298 : aLinePropertiesRight,
299 : aLinePropertiesTop,
300 : aLinePropertiesBottom,
301 : aLinePropertiesTopLeftToBottomRight,
302 : aLinePropertiesBottomLeftToTopRight,
303 6 : rTable.getNeCell() );
304 : }
305 88 : if ( ( nRow == nMaxRow ) && ( nColumn == nMaxColumn ) )
306 : {
307 : applyTableStylePart( rFilterBase, aFillProperties, aTextStyleProps,
308 : aLinePropertiesLeft,
309 : aLinePropertiesRight,
310 : aLinePropertiesTop,
311 : aLinePropertiesBottom,
312 : aLinePropertiesTopLeftToBottomRight,
313 : aLinePropertiesBottomLeftToTopRight,
314 6 : rTable.getSeCell() );
315 : }
316 88 : if ( rProperties.isBandCol() )
317 : {
318 0 : if ( ( !rProperties.isFirstRow() || ( nRow != 0 ) ) &&
319 0 : ( !rProperties.isLastRow() || ( nRow != nMaxRow ) ) &&
320 0 : ( !rProperties.isFirstCol() || ( nColumn != 0 ) ) &&
321 0 : ( !rProperties.isLastCol() || ( nColumn != nMaxColumn ) ) )
322 : {
323 0 : sal_Int32 nBand = nColumn;
324 0 : if ( rProperties.isFirstCol() )
325 0 : nBand++;
326 0 : if ( nBand & 1 )
327 : {
328 : applyTableStylePart( rFilterBase, aFillProperties, aTextStyleProps,
329 : aLinePropertiesLeft,
330 : aLinePropertiesRight,
331 : aLinePropertiesTop,
332 : aLinePropertiesBottom,
333 : aLinePropertiesTopLeftToBottomRight,
334 : aLinePropertiesBottomLeftToTopRight,
335 0 : rTable.getBand2V() );
336 : }
337 : else
338 : {
339 : applyTableStylePart( rFilterBase, aFillProperties, aTextStyleProps,
340 : aLinePropertiesLeft,
341 : aLinePropertiesRight,
342 : aLinePropertiesTop,
343 : aLinePropertiesBottom,
344 : aLinePropertiesTopLeftToBottomRight,
345 : aLinePropertiesBottomLeftToTopRight,
346 0 : rTable.getBand1V() );
347 : }
348 : }
349 : }
350 88 : aLinePropertiesLeft.assignUsed( maLinePropertiesLeft );
351 88 : aLinePropertiesRight.assignUsed( maLinePropertiesRight );
352 88 : aLinePropertiesTop.assignUsed( maLinePropertiesTop );
353 88 : aLinePropertiesBottom.assignUsed( maLinePropertiesBottom );
354 88 : aLinePropertiesTopLeftToBottomRight.assignUsed( maLinePropertiesTopLeftToBottomRight );
355 88 : aLinePropertiesBottomLeftToTopRight.assignUsed( maLinePropertiesBottomLeftToTopRight );
356 88 : applyLineAttributes( rFilterBase, xPropSet, aLinePropertiesLeft, PROP_LeftBorder );
357 88 : applyLineAttributes( rFilterBase, xPropSet, aLinePropertiesRight, PROP_RightBorder );
358 88 : applyLineAttributes( rFilterBase, xPropSet, aLinePropertiesTop, PROP_TopBorder );
359 88 : applyLineAttributes( rFilterBase, xPropSet, aLinePropertiesBottom, PROP_BottomBorder );
360 88 : applyLineAttributes( rFilterBase, xPropSet, aLinePropertiesTopLeftToBottomRight, PROP_DiagonalTLBR );
361 88 : applyLineAttributes( rFilterBase, xPropSet, aLinePropertiesBottomLeftToTopRight, PROP_DiagonalBLTR );
362 :
363 88 : aFillProperties.assignUsed( maFillProperties );
364 176 : ShapePropertyMap aPropMap( rFilterBase.getModelObjectHelper() );
365 :
366 176 : Color aBgColor;
367 88 : sal_Int32 nPhClr = API_RGB_TRANSPARENT;
368 88 : boost::shared_ptr< ::oox::drawingml::FillProperties >& rBackgroundFillPropertiesPtr( rTable.getBackgroundFillProperties() );
369 88 : ::oox::drawingml::ShapeStyleRef& rBackgroundFillStyle( rTable.getBackgroundFillStyleRef() );
370 88 : if (rBackgroundFillPropertiesPtr.get())
371 0 : aBgColor = rBackgroundFillPropertiesPtr->getBestSolidColor();
372 88 : else if (rBackgroundFillStyle.mnThemedIdx != 0)
373 : {
374 48 : if (const Theme* pTheme = rFilterBase.getCurrentTheme())
375 : {
376 48 : aBgColor = pTheme->getFillStyle(rBackgroundFillStyle.mnThemedIdx)->getBestSolidColor();
377 48 : nPhClr = rBackgroundFillStyle.maPhClr.getColor(rFilterBase.getGraphicHelper());
378 : }
379 : }
380 88 : if (aBgColor.isUsed())
381 : {
382 48 : const Color& rCellColor = aFillProperties.getBestSolidColor();
383 48 : const double fTransparency = rCellColor.isUsed() ? 0.01 * rCellColor.getTransparency() : 1.0;
384 48 : ::Color nBgColor( aBgColor.getColor(rFilterBase.getGraphicHelper(), nPhClr) );
385 48 : ::Color nCellColor( rCellColor.getColor(rFilterBase.getGraphicHelper()) );
386 48 : ::Color aResult( basegfx::interpolate(nBgColor.getBColor(), nCellColor.getBColor(), 1.0 - fTransparency) );
387 48 : aFillProperties.maFillColor.clearTransformations();
388 48 : aFillProperties.maFillColor.setSrgbClr(aResult.GetRGBColor());
389 48 : aFillProperties.moFillType.set(XML_solidFill);
390 : }
391 :
392 : // TODO: phClr?
393 88 : aFillProperties.pushToPropMap( aPropMap, rFilterBase.getGraphicHelper() );
394 88 : PropertySet( xPropSet ).setProperties( aPropMap );
395 :
396 88 : if ( getVertToken() == XML_eaVert )
397 : {
398 0 : xPropSet->setPropertyValue("TextWritingMode", Any(com::sun::star::text::WritingMode_TB_RL));
399 : }
400 :
401 176 : getTextBody()->insertAt( rFilterBase, xText, xAt, aTextStyleProps, pMasterTextListStyle );
402 88 : }
403 :
404 408 : } } }
405 :
406 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|