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/tableproperties.hxx"
21 #include "drawingml/table/tablestylelist.hxx"
22 #include "oox/drawingml/drawingmltypes.hxx"
23 #include <com/sun/star/table/XTable.hpp>
24 #include <com/sun/star/container/XNameContainer.hpp>
25 #include <com/sun/star/beans/XMultiPropertySet.hpp>
26 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 #include <com/sun/star/table/XMergeableCellRange.hpp>
28 #include <com/sun/star/table/BorderLine2.hpp>
29 #include <rtl/instance.hxx>
30 #include "oox/core/xmlfilterbase.hxx"
31 #include "oox/helper/propertyset.hxx"
32 #include <oox/token/tokens.hxx>
34 using namespace ::oox::core
;
35 using namespace ::com::sun::star
;
36 using namespace ::com::sun::star::uno
;
37 using namespace ::com::sun::star::beans
;
38 using namespace ::com::sun::star::table
;
40 namespace oox
{ namespace drawingml
{ namespace table
{
42 TableProperties::TableProperties()
51 TableProperties::~TableProperties()
55 void CreateTableRows( const uno::Reference
< XTableRows
>& xTableRows
, const std::vector
< TableRow
>& rvTableRows
)
57 if ( rvTableRows
.size() > 1 )
58 xTableRows
->insertByIndex( 0, rvTableRows
.size() - 1 );
59 std::vector
< TableRow
>::const_iterator
aTableRowIter( rvTableRows
.begin() );
60 uno::Reference
< container::XIndexAccess
> xIndexAccess( xTableRows
, UNO_QUERY_THROW
);
61 for ( sal_Int32 n
= 0; n
< xIndexAccess
->getCount(); n
++ )
63 Reference
< XPropertySet
> xPropSet( xIndexAccess
->getByIndex( n
), UNO_QUERY_THROW
);
64 xPropSet
->setPropertyValue( "Height", Any( static_cast< sal_Int32
>( aTableRowIter
->getHeight() / 360 ) ) );
69 void CreateTableColumns( const Reference
< XTableColumns
>& xTableColumns
, const std::vector
< sal_Int32
>& rvTableGrid
)
71 if ( rvTableGrid
.size() > 1 )
72 xTableColumns
->insertByIndex( 0, rvTableGrid
.size() - 1 );
73 std::vector
< sal_Int32
>::const_iterator
aTableGridIter( rvTableGrid
.begin() );
74 uno::Reference
< container::XIndexAccess
> xIndexAccess( xTableColumns
, UNO_QUERY_THROW
);
75 for ( sal_Int32 n
= 0; n
< xIndexAccess
->getCount(); n
++ )
77 Reference
< XPropertySet
> xPropSet( xIndexAccess
->getByIndex( n
), UNO_QUERY_THROW
);
78 xPropSet
->setPropertyValue( "Width", Any( static_cast< sal_Int32
>( *aTableGridIter
++ / 360 ) ) );
82 void MergeCells( const uno::Reference
< XTable
>& xTable
, sal_Int32 nCol
, sal_Int32 nRow
, sal_Int32 nColSpan
, sal_Int32 nRowSpan
)
86 Reference
< XMergeableCellRange
> xRange( xTable
->createCursorByRange( xTable
->getCellRangeByPosition( nCol
, nRow
,nCol
+ nColSpan
- 1, nRow
+ nRowSpan
- 1 ) ), UNO_QUERY_THROW
);
87 if( xRange
->isMergeable() )
97 struct theDefaultTableStyle
: public ::rtl::Static
< TableStyle
, theDefaultTableStyle
> {};
100 //for pptx just has table style id
101 static void SetTableStyleProperties(TableStyle
* &pTableStyle
, sal_Int32 tblFillClr
, sal_Int32 tblTextClr
, sal_Int32 lineBdrClr
)
103 //whole table fill style and color
104 oox::drawingml::FillPropertiesPtr
pWholeTabFillProperties( new oox::drawingml::FillProperties
);
105 pWholeTabFillProperties
->moFillType
.set(XML_solidFill
);
106 pWholeTabFillProperties
->maFillColor
.setSchemeClr(tblFillClr
);
107 pWholeTabFillProperties
->maFillColor
.addTransformation(XML_tint
,20000);
108 pTableStyle
->getWholeTbl().getFillProperties() = pWholeTabFillProperties
;
109 //whole table text color
110 ::oox::drawingml::Color tableTextColor
;
111 tableTextColor
.setSchemeClr(tblTextClr
);
112 pTableStyle
->getWholeTbl().getTextColor() = tableTextColor
;
113 //whole table line border
114 oox::drawingml::LinePropertiesPtr
pLeftBorder( new oox::drawingml::LineProperties
);
115 pLeftBorder
->moLineWidth
= 12700;
116 pLeftBorder
->moPresetDash
= XML_sng
;
117 pLeftBorder
->maLineFill
.moFillType
.set(XML_solidFill
);
118 pLeftBorder
->maLineFill
.maFillColor
.setSchemeClr(lineBdrClr
);
119 pTableStyle
->getWholeTbl().getLineBorders().insert(std::pair
<sal_Int32
, ::oox::drawingml::LinePropertiesPtr
>(XML_left
,pLeftBorder
));
120 pTableStyle
->getWholeTbl().getLineBorders().insert(std::pair
<sal_Int32
, ::oox::drawingml::LinePropertiesPtr
>(XML_right
,pLeftBorder
));
121 pTableStyle
->getWholeTbl().getLineBorders().insert(std::pair
<sal_Int32
, ::oox::drawingml::LinePropertiesPtr
>(XML_top
,pLeftBorder
));
122 pTableStyle
->getWholeTbl().getLineBorders().insert(std::pair
<sal_Int32
, ::oox::drawingml::LinePropertiesPtr
>(XML_bottom
,pLeftBorder
));
123 pTableStyle
->getWholeTbl().getLineBorders().insert(std::pair
<sal_Int32
, ::oox::drawingml::LinePropertiesPtr
>(XML_insideH
,pLeftBorder
));
124 pTableStyle
->getWholeTbl().getLineBorders().insert(std::pair
<sal_Int32
, ::oox::drawingml::LinePropertiesPtr
>(XML_insideV
,pLeftBorder
));
127 oox::drawingml::FillPropertiesPtr
pBand1HFillProperties( new oox::drawingml::FillProperties
);
128 pBand1HFillProperties
->moFillType
.set(XML_solidFill
);
129 pBand1HFillProperties
->maFillColor
.setSchemeClr(tblFillClr
);
130 pBand1HFillProperties
->maFillColor
.addTransformation(XML_tint
,40000);
131 pTableStyle
->getBand1H().getFillProperties() = pBand1HFillProperties
;
134 pTableStyle
->getBand1V().getFillProperties() = pBand1HFillProperties
;
136 //tet bold for 1st row/last row/column
137 ::boost::optional
< sal_Bool
> textBoldStyle(true);
138 pTableStyle
->getFirstRow().getTextBoldStyle() = textBoldStyle
;
139 pTableStyle
->getLastRow().getTextBoldStyle() = textBoldStyle
;
140 pTableStyle
->getFirstCol().getTextBoldStyle() = textBoldStyle
;
141 pTableStyle
->getLastCol().getTextBoldStyle() = textBoldStyle
;
144 TableStyle
* CreateTableStyle(const OUString
& styleId
)
146 TableStyle
* pTableStyle
= nullptr;
147 if(styleId
== "{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}") { //Medium Style 2 Accent 1
148 pTableStyle
= new TableStyle();
150 //fill color and type
151 oox::drawingml::FillPropertiesPtr
pFstRowFillProperties( new oox::drawingml::FillProperties
);
152 pFstRowFillProperties
->moFillType
.set(XML_solidFill
);
153 pFstRowFillProperties
->maFillColor
.setSchemeClr(XML_accent1
);
154 pTableStyle
->getFirstRow().getFillProperties() = pFstRowFillProperties
;
156 ::oox::drawingml::Color fstRowTextColor
;
157 fstRowTextColor
.setSchemeClr(XML_lt1
);
158 pTableStyle
->getFirstRow().getTextColor() = fstRowTextColor
;
160 oox::drawingml::LinePropertiesPtr
pFstBottomBorder( new oox::drawingml::LineProperties
);
161 pFstBottomBorder
->moLineWidth
= 38100;
162 pFstBottomBorder
->moPresetDash
= XML_sng
;
163 pFstBottomBorder
->maLineFill
.moFillType
.set(XML_solidFill
);
164 pFstBottomBorder
->maLineFill
.maFillColor
.setSchemeClr(XML_lt1
);
165 pTableStyle
->getFirstRow().getLineBorders().insert(std::pair
<sal_Int32
, ::oox::drawingml::LinePropertiesPtr
>(XML_bottom
,pFstBottomBorder
));
168 pTableStyle
->getLastRow().getFillProperties() = pFstRowFillProperties
;
169 pTableStyle
->getLastRow().getTextColor() = fstRowTextColor
;
170 pTableStyle
->getLastRow().getLineBorders().insert(std::pair
<sal_Int32
, ::oox::drawingml::LinePropertiesPtr
>(XML_top
,pFstBottomBorder
));
173 pTableStyle
->getFirstRow().getFillProperties() = pFstRowFillProperties
;
174 pTableStyle
->getFirstRow().getTextColor() = fstRowTextColor
;
177 pTableStyle
->getLastCol().getFillProperties() = pFstRowFillProperties
;
178 pTableStyle
->getLastCol().getTextColor() = fstRowTextColor
;
180 SetTableStyleProperties(pTableStyle
, XML_accent1
, XML_dk1
, XML_lt1
);
182 else if (styleId
== "{21E4AEA4-8DFA-4A89-87EB-49C32662AFE0}") //Medium Style 2 Accent 2
184 pTableStyle
= new TableStyle();
185 oox::drawingml::FillPropertiesPtr
pFstRowFillProperties( new oox::drawingml::FillProperties
);
186 pFstRowFillProperties
->moFillType
.set(XML_solidFill
);
187 pFstRowFillProperties
->maFillColor
.setSchemeClr(XML_accent2
);
188 pTableStyle
->getFirstRow().getFillProperties() = pFstRowFillProperties
;
190 ::oox::drawingml::Color fstRowTextColor
;
191 fstRowTextColor
.setSchemeClr(XML_lt1
);
192 pTableStyle
->getFirstRow().getTextColor() = fstRowTextColor
;
194 oox::drawingml::LinePropertiesPtr
pFstBottomBorder( new oox::drawingml::LineProperties
);
195 pFstBottomBorder
->moLineWidth
= 38100;
196 pFstBottomBorder
->moPresetDash
= XML_sng
;
197 pFstBottomBorder
->maLineFill
.moFillType
.set(XML_solidFill
);
198 pFstBottomBorder
->maLineFill
.maFillColor
.setSchemeClr(XML_lt1
);
199 pTableStyle
->getFirstRow().getLineBorders().insert(std::pair
<sal_Int32
, ::oox::drawingml::LinePropertiesPtr
>(XML_bottom
,pFstBottomBorder
));
201 pTableStyle
->getLastRow().getFillProperties() = pFstRowFillProperties
;
202 pTableStyle
->getLastRow().getTextColor() = fstRowTextColor
;
203 pTableStyle
->getLastRow().getLineBorders().insert(std::pair
<sal_Int32
, ::oox::drawingml::LinePropertiesPtr
>(XML_top
,pFstBottomBorder
));
205 pTableStyle
->getFirstCol().getFillProperties() = pFstRowFillProperties
;
206 pTableStyle
->getFirstCol().getTextColor() = fstRowTextColor
;
208 pTableStyle
->getLastCol().getFillProperties() = pFstRowFillProperties
;
209 pTableStyle
->getLastCol().getTextColor() = fstRowTextColor
;
211 SetTableStyleProperties(pTableStyle
, XML_accent2
, XML_dk1
, XML_lt1
);
213 else if (styleId
== "{C4B1156A-380E-4F78-BDF5-A606A8083BF9}") //Medium Style 4 Accent 4
215 pTableStyle
= new TableStyle();
216 SetTableStyleProperties(pTableStyle
, XML_accent4
, XML_dk1
, XML_accent4
);
222 const TableStyle
& TableProperties::getUsedTableStyle( const ::oox::core::XmlFilterBase
& rFilterBase
, TableStyle
*& rTableStyleToDelete
)
224 ::oox::core::XmlFilterBase
& rBase( const_cast< ::oox::core::XmlFilterBase
& >( rFilterBase
) );
226 TableStyle
* pTableStyle
= nullptr;
228 pTableStyle
= &*mpTableStyle
;
229 else if ( !getStyleId().isEmpty() && rBase
.getTableStyles() )
231 const std::vector
< TableStyle
>& rTableStyles( rBase
.getTableStyles()->getTableStyles() );
232 const OUString
aStyleId( getStyleId() );
234 std::vector
< TableStyle
>::const_iterator
aIter( rTableStyles
.begin() );
235 while( aIter
!= rTableStyles
.end() )
237 if ( const_cast< TableStyle
& >( *aIter
).getStyleId() == aStyleId
)
239 pTableStyle
= &const_cast< TableStyle
& >( *aIter
);
240 break; // we get the correct style
244 //if the pptx just has table style id, but no table style content, we will create the table style ourselves
247 rTableStyleToDelete
= CreateTableStyle(aStyleId
);
248 pTableStyle
= rTableStyleToDelete
;
253 return theDefaultTableStyle::get();
258 void TableProperties::pushToPropSet( const ::oox::core::XmlFilterBase
& rFilterBase
,
259 const Reference
< XPropertySet
>& xPropSet
, const TextListStylePtr
& pMasterTextListStyle
)
261 uno::Reference
< XColumnRowRange
> xColumnRowRange(
262 xPropSet
->getPropertyValue("Model"), uno::UNO_QUERY_THROW
);
264 CreateTableColumns( xColumnRowRange
->getColumns(), mvTableGrid
);
265 CreateTableRows( xColumnRowRange
->getRows(), mvTableRows
);
267 TableStyle
* pTableStyleToDelete
= nullptr;
268 const TableStyle
& rTableStyle( getUsedTableStyle( rFilterBase
, pTableStyleToDelete
) );
270 const std::vector
< TableRow
>::const_iterator
aTableRowEnd( mvTableRows
.end() );
271 for (std::vector
< TableRow
>::iterator
aTableRowIter( mvTableRows
.begin() );
272 aTableRowIter
!= aTableRowEnd
; ++aTableRowIter
, ++nRow
)
274 sal_Int32 nColumn
= 0;
275 const std::vector
< TableCell
>::const_iterator
aTableCellEnd( aTableRowIter
->getTableCells().end() );
276 for (std::vector
< TableCell
>::iterator
aTableCellIter( aTableRowIter
->getTableCells().begin() );
277 aTableCellIter
!= aTableCellEnd
; ++aTableCellIter
, ++nColumn
)
279 TableCell
& rTableCell( *aTableCellIter
);
280 if ( !rTableCell
.getvMerge() && !rTableCell
.gethMerge() )
282 uno::Reference
< XTable
> xTable( xColumnRowRange
, uno::UNO_QUERY_THROW
);
283 if ( ( rTableCell
.getRowSpan() > 1 ) || ( rTableCell
.getGridSpan() > 1 ) )
284 MergeCells( xTable
, nColumn
, nRow
, rTableCell
.getGridSpan(), rTableCell
.getRowSpan() );
286 Reference
< XCellRange
> xCellRange( xTable
, UNO_QUERY_THROW
);
287 rTableCell
.pushToXCell( rFilterBase
, pMasterTextListStyle
, xCellRange
->getCellByPosition( nColumn
, nRow
), *this, rTableStyle
,
288 nColumn
, aTableRowIter
->getTableCells().size()-1, nRow
, mvTableRows
.size()-1 );
293 delete pTableStyleToDelete
;
298 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */