1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "oox/drawingml/table/tableproperties.hxx"
29 #include "oox/drawingml/drawingmltypes.hxx"
30 #include <com/sun/star/table/XTable.hpp>
31 #include <com/sun/star/container/XNameContainer.hpp>
32 #include <com/sun/star/beans/XMultiPropertySet.hpp>
33 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34 #include <com/sun/star/table/XMergeableCellRange.hpp>
35 #include <com/sun/star/table/BorderLine.hpp>
36 #include "oox/core/xmlfilterbase.hxx"
37 #include "oox/helper/propertyset.hxx"
38 
39 using rtl::OUString;
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 namespace ::com::sun::star::table;
45 
46 
47 namespace oox { namespace drawingml { namespace table {
48 
49 TableProperties::TableProperties()
50 : mbRtl( sal_False )
51 , mbFirstRow( sal_False )
52 , mbFirstCol( sal_False )
53 , mbLastRow( sal_False )
54 , mbLastCol( sal_False )
55 , mbBandRow( sal_False )
56 , mbBandCol( sal_False )
57 {
58 }
59 TableProperties::~TableProperties()
60 {
61 }
62 
63 void TableProperties::apply( const TablePropertiesPtr& /* rSourceTableProperties */ )
64 {
65 }
66 
67 void CreateTableRows( uno::Reference< XTableRows > xTableRows, const std::vector< TableRow >& rvTableRows )
68 {
69 	if ( rvTableRows.size() > 1 )
70 		xTableRows->insertByIndex( 0, rvTableRows.size() - 1 );
71 	std::vector< TableRow >::const_iterator aTableRowIter( rvTableRows.begin() );
72 	uno::Reference< container::XIndexAccess > xIndexAccess( xTableRows, UNO_QUERY_THROW );
73 	for ( sal_Int32 n = 0; n < xIndexAccess->getCount(); n++ )
74 	{
75 		static const rtl::OUString	sHeight( RTL_CONSTASCII_USTRINGPARAM ( "Height" ) );
76 		Reference< XPropertySet > xPropSet( xIndexAccess->getByIndex( n ), UNO_QUERY_THROW );
77 		xPropSet->setPropertyValue( sHeight, Any( static_cast< sal_Int32 >( aTableRowIter->getHeight() / 360 ) ) );
78 		aTableRowIter++;
79 	}
80 }
81 
82 void CreateTableColumns( Reference< XTableColumns > xTableColumns, const std::vector< sal_Int32 >& rvTableGrid )
83 {
84 	if ( rvTableGrid.size() > 1 )
85 		xTableColumns->insertByIndex( 0, rvTableGrid.size() - 1 );
86 	std::vector< sal_Int32 >::const_iterator aTableGridIter( rvTableGrid.begin() );
87 	uno::Reference< container::XIndexAccess > xIndexAccess( xTableColumns, UNO_QUERY_THROW );
88 	for ( sal_Int32 n = 0; n < xIndexAccess->getCount(); n++ )
89 	{
90 		static const rtl::OUString	sWidth( RTL_CONSTASCII_USTRINGPARAM ( "Width" ) );
91 		Reference< XPropertySet > xPropSet( xIndexAccess->getByIndex( n ), UNO_QUERY_THROW );
92 		xPropSet->setPropertyValue( sWidth, Any( static_cast< sal_Int32 >( *aTableGridIter++ / 360 ) ) );
93 	}
94 }
95 
96 void MergeCells( const uno::Reference< XTable >& xTable, sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nColSpan, sal_Int32 nRowSpan )
97 {
98    if( xTable.is() ) try
99    {
100        Reference< XMergeableCellRange > xRange( xTable->createCursorByRange( xTable->getCellRangeByPosition( nCol, nRow,nCol + nColSpan - 1, nRow + nRowSpan - 1 ) ), UNO_QUERY_THROW );
101        if( xRange->isMergeable() )
102                xRange->merge();
103    }
104    catch( Exception& )
105    {
106    }
107 }
108 
109 static TableStyle* pDefaultTableStyle = new TableStyle();
110 
111 const TableStyle& TableProperties::getUsedTableStyle( const ::oox::core::XmlFilterBase& rFilterBase )
112 {
113 	::oox::core::XmlFilterBase& rBase( const_cast< ::oox::core::XmlFilterBase& >( rFilterBase ) );
114 
115 	TableStyle* pTableStyle = NULL;
116 	if ( mpTableStyle )
117 		pTableStyle = &*mpTableStyle;
118 	else if ( rBase.getTableStyles() )
119 	{
120 		const std::vector< TableStyle >& rTableStyles( rBase.getTableStyles()->getTableStyles() );
121 		const rtl::OUString aStyleId( getStyleId().getLength() ? getStyleId() : rBase.getTableStyles()->getDefaultStyleId() );
122 		std::vector< TableStyle >::const_iterator aIter( rTableStyles.begin() );
123 		while( aIter != rTableStyles.end() )
124 		{
125 			if ( const_cast< TableStyle& >( *aIter ).getStyleId() == aStyleId )
126 			{
127 				pTableStyle = &const_cast< TableStyle& >( *aIter );
128 				break;	// we get the correct style
129 			}
130 			aIter++;
131 		}
132 	}
133 	if ( !pTableStyle )
134 		pTableStyle = pDefaultTableStyle;
135 
136 	return *pTableStyle;
137 }
138 
139 void TableProperties::pushToPropSet( const ::oox::core::XmlFilterBase& rFilterBase,
140 	const Reference < XPropertySet >& xPropSet, TextListStylePtr pMasterTextListStyle )
141 {
142 	TableStyleListPtr( const_cast< ::oox::core::XmlFilterBase& >( rFilterBase ).getTableStyles() );
143 
144 	uno::Reference< XColumnRowRange > xColumnRowRange(
145  		xPropSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("Model") ) ), uno::UNO_QUERY_THROW );
146 
147 	CreateTableColumns( xColumnRowRange->getColumns(), mvTableGrid );
148 	CreateTableRows( xColumnRowRange->getRows(), mvTableRows );
149 
150 	const TableStyle& rTableStyle( getUsedTableStyle( rFilterBase ) );
151 	sal_Int32 nRow = 0;
152 	std::vector< TableRow >::iterator aTableRowIter( mvTableRows.begin() );
153 	while( aTableRowIter != mvTableRows.end() )
154 	{
155 		sal_Int32 nColumn = 0;
156 		std::vector< TableCell >::iterator aTableCellIter( aTableRowIter->getTableCells().begin() );
157 		while( aTableCellIter != aTableRowIter->getTableCells().end() )
158 		{
159 			TableCell& rTableCell( *aTableCellIter );
160 			if ( !rTableCell.getvMerge() && !rTableCell.gethMerge() )
161 			{
162 				uno::Reference< XTable > xTable( xColumnRowRange, uno::UNO_QUERY_THROW );
163 				if ( ( rTableCell.getRowSpan() > 1 ) || ( rTableCell.getGridSpan() > 1 ) )
164 					MergeCells( xTable, nColumn, nRow, rTableCell.getGridSpan(), rTableCell.getRowSpan() );
165 
166 				Reference< XCellRange > xCellRange( xTable, UNO_QUERY_THROW );
167 				rTableCell.pushToXCell( rFilterBase, pMasterTextListStyle, xCellRange->getCellByPosition( nColumn, nRow ), *this, rTableStyle,
168 					nColumn, aTableRowIter->getTableCells().size(), nRow, mvTableRows.size() );
169 			}
170 			nColumn++;
171 			aTableCellIter++;
172 		}
173 		nRow++;
174 		aTableRowIter++;
175 	}
176 }
177 
178 } } }
179