1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "oox/drawingml/table/tableproperties.hxx"
25 #include "oox/drawingml/drawingmltypes.hxx"
26 #include <com/sun/star/table/XTable.hpp>
27 #include <com/sun/star/container/XNameContainer.hpp>
28 #include <com/sun/star/beans/XMultiPropertySet.hpp>
29 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
30 #include <com/sun/star/table/XMergeableCellRange.hpp>
31 #include <com/sun/star/table/BorderLine.hpp>
32 #include "oox/core/xmlfilterbase.hxx"
33 #include "oox/helper/propertyset.hxx"
34 
35 
36 using rtl::OUString;
37 using namespace ::oox::core;
38 using namespace ::com::sun::star;
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::beans;
41 using namespace ::com::sun::star::table;
42 
43 
44 namespace oox { namespace drawingml { namespace table {
45 
TableProperties()46 TableProperties::TableProperties()
47 : mbRtl( sal_False )
48 , mbFirstRow( sal_False )
49 , mbFirstCol( sal_False )
50 , mbLastRow( sal_False )
51 , mbLastCol( sal_False )
52 , mbBandRow( sal_False )
53 , mbBandCol( sal_False )
54 {
55 }
~TableProperties()56 TableProperties::~TableProperties()
57 {
58 }
59 
apply(const TablePropertiesPtr &)60 void TableProperties::apply( const TablePropertiesPtr& /* rSourceTableProperties */ )
61 {
62 }
63 
CreateTableRows(uno::Reference<XTableRows> xTableRows,const std::vector<TableRow> & rvTableRows)64 void CreateTableRows( uno::Reference< XTableRows > xTableRows, const std::vector< TableRow >& rvTableRows )
65 {
66 	if ( rvTableRows.size() > 1 )
67 		xTableRows->insertByIndex( 0, rvTableRows.size() - 1 );
68 	std::vector< TableRow >::const_iterator aTableRowIter( rvTableRows.begin() );
69 	uno::Reference< container::XIndexAccess > xIndexAccess( xTableRows, UNO_QUERY_THROW );
70 	for ( sal_Int32 n = 0; n < xIndexAccess->getCount(); n++ )
71 	{
72 		static const rtl::OUString	sHeight( RTL_CONSTASCII_USTRINGPARAM ( "Height" ) );
73 		Reference< XPropertySet > xPropSet( xIndexAccess->getByIndex( n ), UNO_QUERY_THROW );
74 		xPropSet->setPropertyValue( sHeight, Any( static_cast< sal_Int32 >( aTableRowIter->getHeight() / 360 ) ) );
75 		aTableRowIter++;
76 	}
77 }
78 
CreateTableColumns(Reference<XTableColumns> xTableColumns,const std::vector<sal_Int32> & rvTableGrid)79 void CreateTableColumns( Reference< XTableColumns > xTableColumns, const std::vector< sal_Int32 >& rvTableGrid )
80 {
81 	if ( rvTableGrid.size() > 1 )
82 		xTableColumns->insertByIndex( 0, rvTableGrid.size() - 1 );
83 	std::vector< sal_Int32 >::const_iterator aTableGridIter( rvTableGrid.begin() );
84 	uno::Reference< container::XIndexAccess > xIndexAccess( xTableColumns, UNO_QUERY_THROW );
85 	for ( sal_Int32 n = 0; n < xIndexAccess->getCount(); n++ )
86 	{
87 		static const rtl::OUString	sWidth( RTL_CONSTASCII_USTRINGPARAM ( "Width" ) );
88 		Reference< XPropertySet > xPropSet( xIndexAccess->getByIndex( n ), UNO_QUERY_THROW );
89 		xPropSet->setPropertyValue( sWidth, Any( static_cast< sal_Int32 >( *aTableGridIter++ / 360 ) ) );
90 	}
91 }
92 
MergeCells(const uno::Reference<XTable> & xTable,sal_Int32 nCol,sal_Int32 nRow,sal_Int32 nColSpan,sal_Int32 nRowSpan)93 void MergeCells( const uno::Reference< XTable >& xTable, sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nColSpan, sal_Int32 nRowSpan )
94 {
95    if( xTable.is() ) try
96    {
97        Reference< XMergeableCellRange > xRange( xTable->createCursorByRange( xTable->getCellRangeByPosition( nCol, nRow,nCol + nColSpan - 1, nRow + nRowSpan - 1 ) ), UNO_QUERY_THROW );
98        if( xRange->isMergeable() )
99                xRange->merge();
100    }
101    catch( Exception& )
102    {
103    }
104 }
105 
106 static TableStyle* pDefaultTableStyle = new TableStyle();
107 
108 //for pptx just has table style id
SetTableStyleProperties(TableStyle * & pTableStyle,const sal_Int32 & tblFillClr,const sal_Int32 & tblTextClr,const sal_Int32 & lineBdrClr)109 static void SetTableStyleProperties(TableStyle* &pTableStyle , const sal_Int32& tblFillClr,const sal_Int32& tblTextClr, const sal_Int32& lineBdrClr)
110 {
111 	//whole table fill style and color
112 	oox::drawingml::FillPropertiesPtr pWholeTabFillProperties( new oox::drawingml::FillProperties );
113 	pWholeTabFillProperties->moFillType.set(XML_solidFill);
114 	pWholeTabFillProperties->maFillColor.setSchemeClr(tblFillClr);
115 	pWholeTabFillProperties->maFillColor.addTransformation(XML_tint,20000);
116 	pTableStyle->getWholeTbl().getFillProperties() = pWholeTabFillProperties;
117 	//whole table text color
118 	::oox::drawingml::Color tableTextColor;
119 	tableTextColor.setSchemeClr(tblTextClr);
120 	pTableStyle->getWholeTbl().getTextColor() = tableTextColor;
121 	//whole table line border
122 	oox::drawingml::LinePropertiesPtr pLeftBorder( new oox::drawingml::LineProperties);
123 	pLeftBorder->moLineWidth = 12700;
124 	pLeftBorder->moPresetDash = XML_sng;
125 	pLeftBorder->maLineFill.moFillType.set(XML_solidFill);
126 	pLeftBorder->maLineFill.maFillColor.setSchemeClr(lineBdrClr);
127 	pTableStyle->getWholeTbl().getLineBorders().insert(std::pair<sal_Int32, ::oox::drawingml::LinePropertiesPtr>(XML_left,pLeftBorder));
128 	pTableStyle->getWholeTbl().getLineBorders().insert(std::pair<sal_Int32, ::oox::drawingml::LinePropertiesPtr>(XML_right,pLeftBorder));
129 	pTableStyle->getWholeTbl().getLineBorders().insert(std::pair<sal_Int32, ::oox::drawingml::LinePropertiesPtr>(XML_top,pLeftBorder));
130 	pTableStyle->getWholeTbl().getLineBorders().insert(std::pair<sal_Int32, ::oox::drawingml::LinePropertiesPtr>(XML_bottom,pLeftBorder));
131 	pTableStyle->getWholeTbl().getLineBorders().insert(std::pair<sal_Int32, ::oox::drawingml::LinePropertiesPtr>(XML_insideH,pLeftBorder));
132 	pTableStyle->getWholeTbl().getLineBorders().insert(std::pair<sal_Int32, ::oox::drawingml::LinePropertiesPtr>(XML_insideV,pLeftBorder));
133 
134 	//Band1H style
135 	oox::drawingml::FillPropertiesPtr pBand1HFillProperties( new oox::drawingml::FillProperties );
136 	pBand1HFillProperties->moFillType.set(XML_solidFill);
137 	pBand1HFillProperties->maFillColor.setSchemeClr(tblFillClr);
138 	pBand1HFillProperties->maFillColor.addTransformation(XML_tint,40000);
139 	pTableStyle->getBand1H().getFillProperties() = pBand1HFillProperties;
140 
141 	//Band1V style
142 	pTableStyle->getBand1V().getFillProperties() = pBand1HFillProperties;
143 
144     //tet bold for 1st row/last row/column
145 	::boost::optional< sal_Bool > textBoldStyle(sal_True);
146 	pTableStyle->getFirstRow().getTextBoldStyle() = textBoldStyle;
147 	pTableStyle->getLastRow().getTextBoldStyle() = textBoldStyle;
148 	pTableStyle->getFirstCol().getTextBoldStyle() = textBoldStyle;
149 	pTableStyle->getLastCol().getTextBoldStyle() = textBoldStyle;
150 }
151 
CreateTableStyle(TableStyle * & pTableStyle,const OUString & styleId)152  sal_Bool CreateTableStyle(TableStyle* &pTableStyle , const OUString& styleId)
153 {
154 	sal_Bool createdTblStyle = sal_False;
155 	if(!styleId.compareToAscii("{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}")){           //Medium Style 2 Accenat 1
156 		pTableStyle = new TableStyle();
157 		createdTblStyle = sal_True;
158         //first row style
159         //fill color and type
160 		oox::drawingml::FillPropertiesPtr pFstRowFillProperties( new oox::drawingml::FillProperties );
161 		pFstRowFillProperties->moFillType.set(XML_solidFill);
162 		pFstRowFillProperties->maFillColor.setSchemeClr(XML_accent1);
163 		pTableStyle->getFirstRow().getFillProperties() = pFstRowFillProperties;
164 		//text color
165 		::oox::drawingml::Color fstRowTextColor;
166 		fstRowTextColor.setSchemeClr(XML_lt1);
167 		pTableStyle->getFirstRow().getTextColor() = fstRowTextColor;
168 		//bottom line border
169 		oox::drawingml::LinePropertiesPtr pFstBottomBorder( new oox::drawingml::LineProperties);
170 		pFstBottomBorder->moLineWidth = 38100;
171 		pFstBottomBorder->moPresetDash = XML_sng;
172 		pFstBottomBorder->maLineFill.moFillType.set(XML_solidFill);
173 		pFstBottomBorder->maLineFill.maFillColor.setSchemeClr(XML_lt1);
174 		pTableStyle->getFirstRow().getLineBorders().insert(std::pair<sal_Int32, ::oox::drawingml::LinePropertiesPtr>(XML_bottom,pFstBottomBorder));
175 
176         //last row style
177 		pTableStyle->getLastRow().getFillProperties() = pFstRowFillProperties;
178 		pTableStyle->getLastRow().getTextColor() = fstRowTextColor;
179 		pTableStyle->getLastRow().getLineBorders().insert(std::pair<sal_Int32, ::oox::drawingml::LinePropertiesPtr>(XML_top,pFstBottomBorder));
180 
181 		//first column style
182 		pTableStyle->getFirstRow().getFillProperties() = pFstRowFillProperties;
183 		pTableStyle->getFirstRow().getTextColor() = fstRowTextColor;
184 
185 		//last column style
186 		pTableStyle->getLastCol().getFillProperties() = pFstRowFillProperties;
187 		pTableStyle->getLastCol().getTextColor() = fstRowTextColor;
188 
189 		SetTableStyleProperties(pTableStyle, XML_accent1, XML_dk1, XML_lt1);
190 	}
191 	else if (!styleId.compareToAscii("{21E4AEA4-8DFA-4A89-87EB-49C32662AFE0}"))         //Medium Style 2 Accent 2
192 	{
193 		pTableStyle = new TableStyle();
194 		createdTblStyle = sal_True;
195 		oox::drawingml::FillPropertiesPtr pFstRowFillProperties( new oox::drawingml::FillProperties );
196 		pFstRowFillProperties->moFillType.set(XML_solidFill);
197 		pFstRowFillProperties->maFillColor.setSchemeClr(XML_accent2);
198 		pTableStyle->getFirstRow().getFillProperties() = pFstRowFillProperties;
199 
200 		::oox::drawingml::Color fstRowTextColor;
201 		fstRowTextColor.setSchemeClr(XML_lt1);
202 		pTableStyle->getFirstRow().getTextColor() = fstRowTextColor;
203 
204 		oox::drawingml::LinePropertiesPtr pFstBottomBorder( new oox::drawingml::LineProperties);
205 		pFstBottomBorder->moLineWidth = 38100;
206 		pFstBottomBorder->moPresetDash = XML_sng;
207 		pFstBottomBorder->maLineFill.moFillType.set(XML_solidFill);
208 		pFstBottomBorder->maLineFill.maFillColor.setSchemeClr(XML_lt1);
209 		pTableStyle->getFirstRow().getLineBorders().insert(std::pair<sal_Int32, ::oox::drawingml::LinePropertiesPtr>(XML_bottom,pFstBottomBorder));
210 
211 		pTableStyle->getLastRow().getFillProperties() = pFstRowFillProperties;
212 		pTableStyle->getLastRow().getTextColor() = fstRowTextColor;
213 		pTableStyle->getLastRow().getLineBorders().insert(std::pair<sal_Int32, ::oox::drawingml::LinePropertiesPtr>(XML_top,pFstBottomBorder));
214 
215 		pTableStyle->getFirstCol().getFillProperties() = pFstRowFillProperties;
216 		pTableStyle->getFirstCol().getTextColor() = fstRowTextColor;
217 
218 		pTableStyle->getLastCol().getFillProperties() = pFstRowFillProperties;
219 		pTableStyle->getLastCol().getTextColor() = fstRowTextColor;
220 
221 		SetTableStyleProperties(pTableStyle, XML_accent2, XML_dk1, XML_lt1);
222 	}
223 	else if (!styleId.compareToAscii("{C4B1156A-380E-4F78-BDF5-A606A8083BF9}"))         //Medium Style 4 Accent 4
224 	{
225 		pTableStyle = new TableStyle();
226 		createdTblStyle = sal_True;
227 		SetTableStyleProperties(pTableStyle, XML_accent4, XML_dk1, XML_accent4);
228 	}
229 
230 	return createdTblStyle;
231 }
232 //end
233 
getUsedTableStyle(const::oox::core::XmlFilterBase & rFilterBase,sal_Bool & isCreateTabStyle)234 const TableStyle& TableProperties::getUsedTableStyle( const ::oox::core::XmlFilterBase& rFilterBase, sal_Bool &isCreateTabStyle )
235 {
236 	::oox::core::XmlFilterBase& rBase( const_cast< ::oox::core::XmlFilterBase& >( rFilterBase ) );
237 
238 	TableStyle* pTableStyle = NULL;
239 	if ( mpTableStyle )
240 		pTableStyle = &*mpTableStyle;
241 	else if ( rBase.getTableStyles() )
242 	{
243 		const std::vector< TableStyle >& rTableStyles( rBase.getTableStyles()->getTableStyles() );
244 		const rtl::OUString aStyleId( getStyleId().getLength() ? getStyleId() : rBase.getTableStyles()->getDefaultStyleId() );
245 		std::vector< TableStyle >::const_iterator aIter( rTableStyles.begin() );
246 		while( aIter != rTableStyles.end() )
247 		{
248 			if ( const_cast< TableStyle& >( *aIter ).getStyleId() == aStyleId )
249 			{
250 				pTableStyle = &const_cast< TableStyle& >( *aIter );
251 				break;	// we get the correct style
252 			}
253 			aIter++;
254 		}
255 		//if the pptx just has table style id, but no table style content, we will create the table style ourselves
256 		if ( !pTableStyle )
257 		{
258 			isCreateTabStyle = CreateTableStyle(pTableStyle , aStyleId);
259 		}
260 	}
261 	if ( !pTableStyle )
262 		pTableStyle = pDefaultTableStyle;
263 
264 	return *pTableStyle;
265 }
266 
pushToPropSet(const::oox::core::XmlFilterBase & rFilterBase,const Reference<XPropertySet> & xPropSet,TextListStylePtr pMasterTextListStyle)267 void TableProperties::pushToPropSet( const ::oox::core::XmlFilterBase& rFilterBase,
268 	const Reference < XPropertySet >& xPropSet, TextListStylePtr pMasterTextListStyle )
269 {
270 	TableStyleListPtr( const_cast< ::oox::core::XmlFilterBase& >( rFilterBase ).getTableStyles() );
271 
272 	uno::Reference< XColumnRowRange > xColumnRowRange(
273  		xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("Model") ) ), uno::UNO_QUERY_THROW );
274 
275 	CreateTableColumns( xColumnRowRange->getColumns(), mvTableGrid );
276 	CreateTableRows( xColumnRowRange->getRows(), mvTableRows );
277 
278 	sal_Bool mbOwnTblStyle = sal_False;
279 	const TableStyle& rTableStyle( getUsedTableStyle( rFilterBase, mbOwnTblStyle ) );
280 	sal_Int32 nRow = 0;
281 	std::vector< TableRow >::iterator aTableRowIter( mvTableRows.begin() );
282 	while( aTableRowIter != mvTableRows.end() )
283 	{
284 		sal_Int32 nColumn = 0;
285 		std::vector< TableCell >::iterator aTableCellIter( aTableRowIter->getTableCells().begin() );
286 		while( aTableCellIter != aTableRowIter->getTableCells().end() )
287 		{
288 			TableCell& rTableCell( *aTableCellIter );
289 			if ( !rTableCell.getvMerge() && !rTableCell.gethMerge() )
290 			{
291 				uno::Reference< XTable > xTable( xColumnRowRange, uno::UNO_QUERY_THROW );
292 				if ( ( rTableCell.getRowSpan() > 1 ) || ( rTableCell.getGridSpan() > 1 ) )
293 					MergeCells( xTable, nColumn, nRow, rTableCell.getGridSpan(), rTableCell.getRowSpan() );
294 
295 				Reference< XCellRange > xCellRange( xTable, UNO_QUERY_THROW );
296 				rTableCell.pushToXCell( rFilterBase, pMasterTextListStyle, xCellRange->getCellByPosition( nColumn, nRow ), *this, rTableStyle,
297 					nColumn, aTableRowIter->getTableCells().size(), nRow, mvTableRows.size() );
298 			}
299 			nColumn++;
300 			aTableCellIter++;
301 		}
302 		nRow++;
303 		aTableRowIter++;
304 	}
305 
306 	if(mbOwnTblStyle == sal_True)
307 	{
308 		TableStyle* pTableStyle = (TableStyle*)&rTableStyle;
309 		if(pTableStyle != NULL)
310 		{
311 			delete pTableStyle;
312 			pTableStyle = NULL;
313 		}
314 		mbOwnTblStyle = sal_False;
315 	}
316 }
317 
318 } } }
319