1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
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
;
46 namespace oox
{ namespace drawingml
{ namespace table
{
48 TableCell::TableCell()
49 : mpTextBody( new TextBody() )
58 , mnVertToken( XML_horz
)
59 , mnAnchorToken( XML_t
)
60 , mbAnchorCtr( false )
61 , mnHorzOverflowToken( XML_clip
)
64 TableCell::~TableCell()
68 void applyLineAttributes( const ::oox::core::XmlFilterBase
& rFilterBase
,
69 Reference
< XPropertySet
>& rxPropSet
, oox::drawingml::LineProperties
& rLineProperties
,
72 BorderLine2 aBorderLine
;
73 if( rLineProperties
.maLineFill
.moFillType
.differsFrom( XML_noFill
))
75 Color aColor
= rLineProperties
.maLineFill
.getBestSolidColor();
76 aBorderLine
.Color
= aColor
.getColor( rFilterBase
.getGraphicHelper() );
77 aBorderLine
.OuterLineWidth
= static_cast< sal_Int16
>( GetCoordinate( rLineProperties
.moLineWidth
.get( 0 ) ) / 4 );
78 aBorderLine
.InnerLineWidth
= static_cast< sal_Int16
>( GetCoordinate( rLineProperties
.moLineWidth
.get( 0 ) ) / 4 );
79 aBorderLine
.LineWidth
= static_cast< sal_Int16
>( GetCoordinate( rLineProperties
.moLineWidth
.get( 0 ) ) / 2 );
80 aBorderLine
.LineDistance
= 0;
82 else if ( rLineProperties
.moLineWidth
.get(0)!=0 )
84 // Default color of Line is black.
85 rLineProperties
.maLineFill
.maFillColor
.setSrgbClr( 0 );
86 aBorderLine
.OuterLineWidth
= static_cast< sal_Int16
>( GetCoordinate( rLineProperties
.moLineWidth
.get( 0 ) ) / 4 );
87 aBorderLine
.InnerLineWidth
= static_cast< sal_Int16
>( GetCoordinate( rLineProperties
.moLineWidth
.get( 0 ) ) / 4 );
88 aBorderLine
.LineWidth
= static_cast< sal_Int16
>( GetCoordinate( rLineProperties
.moLineWidth
.get( 0 ) ) / 2 );
89 aBorderLine
.LineDistance
= 0;
92 PropertySet
aPropSet( rxPropSet
);
93 aPropSet
.setProperty( nPropId
, aBorderLine
);
96 void applyBorder( const ::oox::core::XmlFilterBase
& rFilterBase
, TableStylePart
& rTableStylePart
, sal_Int32 nLineType
, oox::drawingml::LineProperties
& rLineProperties
)
98 std::map
< sal_Int32
, ::oox::drawingml::LinePropertiesPtr
>& rPartLineBorders( rTableStylePart
.getLineBorders() );
99 ::oox::drawingml::ShapeStyleRef
& rLineStyleRef
= rTableStylePart
.getStyleRefs()[ nLineType
];
100 std::map
< sal_Int32
, ::oox::drawingml::LinePropertiesPtr
>::const_iterator
aIter( rPartLineBorders
.find( nLineType
) );
101 if ( ( aIter
!= rPartLineBorders
.end() ) && aIter
->second
.get() )
102 rLineProperties
.assignUsed( *aIter
->second
);
103 else if (rLineStyleRef
.mnThemedIdx
!= 0)
105 if (const Theme
* pTheme
= rFilterBase
.getCurrentTheme())
107 rLineProperties
.assignUsed( *pTheme
->getLineStyle(rLineStyleRef
.mnThemedIdx
) );
108 sal_Int32 nPhClr
= rLineStyleRef
.maPhClr
.getColor( rFilterBase
.getGraphicHelper() );
109 rLineProperties
.maLineFill
.maFillColor
.setSrgbClr( nPhClr
);
114 void applyTableStylePart( const ::oox::core::XmlFilterBase
& rFilterBase
,
115 oox::drawingml::FillProperties
& rFillProperties
,
116 TextCharacterProperties
& aTextCharProps
,
117 oox::drawingml::LineProperties
& rLeftBorder
,
118 oox::drawingml::LineProperties
& rRightBorder
,
119 oox::drawingml::LineProperties
& rTopBorder
,
120 oox::drawingml::LineProperties
& rBottomBorder
,
121 oox::drawingml::LineProperties
& rTopLeftToBottomRightBorder
,
122 oox::drawingml::LineProperties
& rBottomLeftToTopRightBorder
,
123 TableStylePart
& rTableStylePart
)
125 ::oox::drawingml::FillPropertiesPtr
& rPartFillPropertiesPtr( rTableStylePart
.getFillProperties() );
126 if ( rPartFillPropertiesPtr
.get() )
127 rFillProperties
.assignUsed( *rPartFillPropertiesPtr
);
130 ::oox::drawingml::ShapeStyleRef
& rFillStyleRef
= rTableStylePart
.getStyleRefs()[ XML_fillRef
];
131 const Theme
* pTheme
= rFilterBase
.getCurrentTheme();
132 if (pTheme
&& rFillStyleRef
.mnThemedIdx
!= 0 )
134 rFillProperties
.assignUsed( *pTheme
->getFillStyle( rFillStyleRef
.mnThemedIdx
) );
135 sal_Int32 nPhClr
= rFillStyleRef
.maPhClr
.getColor( rFilterBase
.getGraphicHelper() );
136 rFillProperties
.maFillColor
.setSrgbClr( nPhClr
);
140 applyBorder( rFilterBase
, rTableStylePart
, XML_left
, rLeftBorder
);
141 applyBorder( rFilterBase
, rTableStylePart
, XML_right
, rRightBorder
);
142 applyBorder( rFilterBase
, rTableStylePart
, XML_top
, rTopBorder
);
143 applyBorder( rFilterBase
, rTableStylePart
, XML_bottom
, rBottomBorder
);
144 applyBorder( rFilterBase
, rTableStylePart
, XML_tl2br
, rTopLeftToBottomRightBorder
);
145 applyBorder( rFilterBase
, rTableStylePart
, XML_tr2bl
, rBottomLeftToTopRightBorder
);
147 aTextCharProps
.maLatinFont
= rTableStylePart
.getLatinFont();
148 aTextCharProps
.maAsianFont
= rTableStylePart
.getAsianFont();
149 aTextCharProps
.maComplexFont
= rTableStylePart
.getComplexFont();
150 aTextCharProps
.maSymbolFont
= rTableStylePart
.getSymbolFont();
151 if (rTableStylePart
.getTextColor().isUsed())
152 aTextCharProps
.maCharColor
= rTableStylePart
.getTextColor();
153 if( rTableStylePart
.getTextBoldStyle().is_initialized() )
154 aTextCharProps
.moBold
= *rTableStylePart
.getTextBoldStyle();
155 if( rTableStylePart
.getTextItalicStyle().is_initialized() )
156 aTextCharProps
.moItalic
= *rTableStylePart
.getTextItalicStyle();
159 void applyTableCellProperties( const Reference
< ::com::sun::star::table::XCell
>& rxCell
, const TableCell
& rTableCell
)
161 Reference
< XPropertySet
> xPropSet( rxCell
, UNO_QUERY_THROW
);
162 xPropSet
->setPropertyValue( "TextUpperDistance", Any( static_cast< sal_Int32
>( rTableCell
.getTopMargin() / 360 ) ) );
163 xPropSet
->setPropertyValue( "TextRightDistance", Any( static_cast< sal_Int32
>( rTableCell
.getRightMargin() / 360 ) ) );
164 xPropSet
->setPropertyValue( "TextLeftDistance", Any( static_cast< sal_Int32
>( rTableCell
.getLeftMargin() / 360 ) ) );
165 xPropSet
->setPropertyValue( "TextLowerDistance", Any( static_cast< sal_Int32
>( rTableCell
.getBottomMargin() / 360 ) ) );
167 drawing::TextVerticalAdjust eVA
;
168 switch( rTableCell
.getAnchorToken() )
170 case XML_ctr
: eVA
= drawing::TextVerticalAdjust_CENTER
; break;
171 case XML_b
: eVA
= drawing::TextVerticalAdjust_BOTTOM
; break;
175 case XML_t
: eVA
= drawing::TextVerticalAdjust_TOP
; break;
177 xPropSet
->setPropertyValue( "TextVerticalAdjust", Any( eVA
) );
180 void TableCell::pushToXCell( const ::oox::core::XmlFilterBase
& rFilterBase
, ::oox::drawingml::TextListStylePtr pMasterTextListStyle
,
181 const ::com::sun::star::uno::Reference
< ::com::sun::star::table::XCell
>& rxCell
, const TableProperties
& rTableProperties
,
182 const TableStyle
& rTableStyle
, sal_Int32 nColumn
, sal_Int32 nMaxColumn
, sal_Int32 nRow
, sal_Int32 nMaxRow
)
184 TableStyle
& rTable( const_cast< TableStyle
& >( rTableStyle
) );
185 TableProperties
& rProperties( const_cast< TableProperties
& >( rTableProperties
) );
187 Reference
< text::XText
> xText( rxCell
, UNO_QUERY_THROW
);
188 Reference
< text::XTextCursor
> xAt
= xText
->createTextCursor();
190 applyTableCellProperties( rxCell
, *this );
191 TextCharacterProperties aTextStyleProps
;
192 xAt
->gotoStart( sal_True
);
193 Reference
< text::XTextRange
> xStart( xAt
, UNO_QUERY
);
194 xAt
->gotoEnd( sal_True
);
196 Reference
< XPropertySet
> xPropSet( rxCell
, UNO_QUERY_THROW
);
197 oox::drawingml::FillProperties aFillProperties
;
198 oox::drawingml::LineProperties aLinePropertiesLeft
;
199 oox::drawingml::LineProperties aLinePropertiesRight
;
200 oox::drawingml::LineProperties aLinePropertiesTop
;
201 oox::drawingml::LineProperties aLinePropertiesBottom
;
202 oox::drawingml::LineProperties aLinePropertiesTopLeftToBottomRight
;
203 oox::drawingml::LineProperties aLinePropertiesBottomLeftToTopRight
;
205 applyTableStylePart( rFilterBase
, aFillProperties
, aTextStyleProps
,
207 aLinePropertiesRight
,
209 aLinePropertiesBottom
,
210 aLinePropertiesTopLeftToBottomRight
,
211 aLinePropertiesBottomLeftToTopRight
,
212 rTable
.getWholeTbl() );
214 if ( rProperties
.isFirstRow() && ( nRow
== 0 ) )
216 applyTableStylePart( rFilterBase
, aFillProperties
, aTextStyleProps
,
218 aLinePropertiesRight
,
220 aLinePropertiesBottom
,
221 aLinePropertiesTopLeftToBottomRight
,
222 aLinePropertiesBottomLeftToTopRight
,
223 rTable
.getFirstRow() );
225 if ( rProperties
.isLastRow() && ( nRow
== nMaxRow
) )
227 applyTableStylePart( rFilterBase
, aFillProperties
, aTextStyleProps
,
229 aLinePropertiesRight
,
231 aLinePropertiesBottom
,
232 aLinePropertiesTopLeftToBottomRight
,
233 aLinePropertiesBottomLeftToTopRight
,
234 rTable
.getLastRow() );
236 if ( rProperties
.isFirstCol() && ( nColumn
== 0 ) )
238 applyTableStylePart( rFilterBase
, aFillProperties
, aTextStyleProps
,
240 aLinePropertiesRight
,
242 aLinePropertiesBottom
,
243 aLinePropertiesTopLeftToBottomRight
,
244 aLinePropertiesBottomLeftToTopRight
,
245 rTable
.getFirstCol() );
247 if ( rProperties
.isLastCol() && ( nColumn
== nMaxColumn
) )
249 applyTableStylePart( rFilterBase
, aFillProperties
, aTextStyleProps
,
251 aLinePropertiesRight
,
253 aLinePropertiesBottom
,
254 aLinePropertiesTopLeftToBottomRight
,
255 aLinePropertiesBottomLeftToTopRight
,
256 rTable
.getLastCol() );
258 if ( rProperties
.isBandRow() )
260 if ( ( !rProperties
.isFirstRow() || ( nRow
!= 0 ) ) &&
261 ( !rProperties
.isLastRow() || ( nRow
!= nMaxRow
) ) &&
262 ( !rProperties
.isFirstCol() || ( nColumn
!= 0 ) ) &&
263 ( !rProperties
.isLastCol() || ( nColumn
!= nMaxColumn
) ) )
265 sal_Int32 nBand
= nRow
;
266 if ( rProperties
.isFirstRow() )
270 applyTableStylePart( rFilterBase
, aFillProperties
, aTextStyleProps
,
272 aLinePropertiesRight
,
274 aLinePropertiesBottom
,
275 aLinePropertiesTopLeftToBottomRight
,
276 aLinePropertiesBottomLeftToTopRight
,
277 rTable
.getBand2H() );
281 applyTableStylePart( rFilterBase
, aFillProperties
, aTextStyleProps
,
283 aLinePropertiesRight
,
285 aLinePropertiesBottom
,
286 aLinePropertiesTopLeftToBottomRight
,
287 aLinePropertiesBottomLeftToTopRight
,
288 rTable
.getBand1H() );
292 if ( ( nRow
== 0 ) && ( nColumn
== 0 ) )
294 applyTableStylePart( rFilterBase
, aFillProperties
, aTextStyleProps
,
296 aLinePropertiesRight
,
298 aLinePropertiesBottom
,
299 aLinePropertiesTopLeftToBottomRight
,
300 aLinePropertiesBottomLeftToTopRight
,
301 rTable
.getNwCell() );
303 if ( ( nRow
== nMaxRow
) && ( nColumn
== 0 ) )
305 applyTableStylePart( rFilterBase
, aFillProperties
, aTextStyleProps
,
307 aLinePropertiesRight
,
309 aLinePropertiesBottom
,
310 aLinePropertiesTopLeftToBottomRight
,
311 aLinePropertiesBottomLeftToTopRight
,
312 rTable
.getSwCell() );
314 if ( ( nRow
== 0 ) && ( nColumn
== nMaxColumn
) )
316 applyTableStylePart( rFilterBase
, aFillProperties
, aTextStyleProps
,
318 aLinePropertiesRight
,
320 aLinePropertiesBottom
,
321 aLinePropertiesTopLeftToBottomRight
,
322 aLinePropertiesBottomLeftToTopRight
,
323 rTable
.getNeCell() );
325 if ( ( nRow
== nMaxRow
) && ( nColumn
== nMaxColumn
) )
327 applyTableStylePart( rFilterBase
, aFillProperties
, aTextStyleProps
,
329 aLinePropertiesRight
,
331 aLinePropertiesBottom
,
332 aLinePropertiesTopLeftToBottomRight
,
333 aLinePropertiesBottomLeftToTopRight
,
334 rTable
.getSeCell() );
336 if ( rProperties
.isBandCol() )
338 if ( ( !rProperties
.isFirstRow() || ( nRow
!= 0 ) ) &&
339 ( !rProperties
.isLastRow() || ( nRow
!= nMaxRow
) ) &&
340 ( !rProperties
.isFirstCol() || ( nColumn
!= 0 ) ) &&
341 ( !rProperties
.isLastCol() || ( nColumn
!= nMaxColumn
) ) )
343 sal_Int32 nBand
= nColumn
;
344 if ( rProperties
.isFirstCol() )
348 applyTableStylePart( rFilterBase
, aFillProperties
, aTextStyleProps
,
350 aLinePropertiesRight
,
352 aLinePropertiesBottom
,
353 aLinePropertiesTopLeftToBottomRight
,
354 aLinePropertiesBottomLeftToTopRight
,
355 rTable
.getBand2V() );
359 applyTableStylePart( rFilterBase
, aFillProperties
, aTextStyleProps
,
361 aLinePropertiesRight
,
363 aLinePropertiesBottom
,
364 aLinePropertiesTopLeftToBottomRight
,
365 aLinePropertiesBottomLeftToTopRight
,
366 rTable
.getBand1V() );
370 aLinePropertiesLeft
.assignUsed( maLinePropertiesLeft
);
371 aLinePropertiesRight
.assignUsed( maLinePropertiesRight
);
372 aLinePropertiesTop
.assignUsed( maLinePropertiesTop
);
373 aLinePropertiesBottom
.assignUsed( maLinePropertiesBottom
);
374 aLinePropertiesTopLeftToBottomRight
.assignUsed( maLinePropertiesTopLeftToBottomRight
);
375 aLinePropertiesBottomLeftToTopRight
.assignUsed( maLinePropertiesBottomLeftToTopRight
);
376 applyLineAttributes( rFilterBase
, xPropSet
, aLinePropertiesLeft
, PROP_LeftBorder
);
377 applyLineAttributes( rFilterBase
, xPropSet
, aLinePropertiesRight
, PROP_RightBorder
);
378 applyLineAttributes( rFilterBase
, xPropSet
, aLinePropertiesTop
, PROP_TopBorder
);
379 applyLineAttributes( rFilterBase
, xPropSet
, aLinePropertiesBottom
, PROP_BottomBorder
);
380 applyLineAttributes( rFilterBase
, xPropSet
, aLinePropertiesTopLeftToBottomRight
, PROP_DiagonalTLBR
);
381 applyLineAttributes( rFilterBase
, xPropSet
, aLinePropertiesBottomLeftToTopRight
, PROP_DiagonalBLTR
);
383 aFillProperties
.assignUsed( maFillProperties
);
384 ShapePropertyMap
aPropMap( rFilterBase
.getModelObjectHelper() );
387 sal_Int32 nPhClr
= API_RGB_TRANSPARENT
;
388 std::shared_ptr
< ::oox::drawingml::FillProperties
>& rBackgroundFillPropertiesPtr( rTable
.getBackgroundFillProperties() );
389 ::oox::drawingml::ShapeStyleRef
& rBackgroundFillStyle( rTable
.getBackgroundFillStyleRef() );
390 if (rBackgroundFillPropertiesPtr
.get())
391 aBgColor
= rBackgroundFillPropertiesPtr
->getBestSolidColor();
392 else if (rBackgroundFillStyle
.mnThemedIdx
!= 0)
394 if (const Theme
* pTheme
= rFilterBase
.getCurrentTheme())
396 aBgColor
= pTheme
->getFillStyle(rBackgroundFillStyle
.mnThemedIdx
)->getBestSolidColor();
397 nPhClr
= rBackgroundFillStyle
.maPhClr
.getColor(rFilterBase
.getGraphicHelper());
400 if (aBgColor
.isUsed())
402 const Color
& rCellColor
= aFillProperties
.getBestSolidColor();
403 const double fTransparency
= rCellColor
.isUsed() ? 0.01 * rCellColor
.getTransparency() : 1.0;
404 ::Color
nBgColor( aBgColor
.getColor(rFilterBase
.getGraphicHelper(), nPhClr
) );
405 ::Color
nCellColor( rCellColor
.getColor(rFilterBase
.getGraphicHelper()) );
406 ::Color
aResult( basegfx::interpolate(nBgColor
.getBColor(), nCellColor
.getBColor(), 1.0 - fTransparency
) );
407 aFillProperties
.maFillColor
.clearTransformations();
408 aFillProperties
.maFillColor
.setSrgbClr(aResult
.GetRGBColor());
409 aFillProperties
.moFillType
.set(XML_solidFill
);
413 aFillProperties
.pushToPropMap( aPropMap
, rFilterBase
.getGraphicHelper() );
414 PropertySet( xPropSet
).setProperties( aPropMap
);
416 if ( getVertToken() == XML_eaVert
)
418 xPropSet
->setPropertyValue("TextWritingMode", Any(com::sun::star::text::WritingMode_TB_RL
));
421 getTextBody()->insertAt( rFilterBase
, xText
, xAt
, aTextStyleProps
, pMasterTextListStyle
);
426 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */