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/table/XMergeableCellRange.hpp>
25 #include <oox/core/xmlfilterbase.hxx>
26 #include "predefined-table-styles.cxx"
28 using namespace ::oox::core
;
29 using namespace ::com::sun::star
;
30 using namespace ::com::sun::star::uno
;
31 using namespace ::com::sun::star::beans
;
32 using namespace ::com::sun::star::table
;
34 namespace oox::drawingml::table
{
36 TableProperties::TableProperties()
44 maBgColor
.setUnused();
47 static void CreateTableRows( const uno::Reference
< XTableRows
>& xTableRows
, const std::vector
< TableRow
>& rvTableRows
)
49 if ( rvTableRows
.size() > 1 )
50 xTableRows
->insertByIndex( 0, rvTableRows
.size() - 1 );
51 std::vector
< TableRow
>::const_iterator
aTableRowIter( rvTableRows
.begin() );
52 uno::Reference
< container::XIndexAccess
> xIndexAccess( xTableRows
, UNO_QUERY_THROW
);
53 sal_Int32 nCols
= std::min
<sal_Int32
>(xIndexAccess
->getCount(), rvTableRows
.size());
54 for (sal_Int32 n
= 0; n
< nCols
; ++n
)
56 Reference
< XPropertySet
> xPropSet( xIndexAccess
->getByIndex( n
), UNO_QUERY_THROW
);
57 xPropSet
->setPropertyValue( u
"Height"_ustr
, Any( static_cast< sal_Int32
>( aTableRowIter
->getHeight() / 360 ) ) );
62 static void CreateTableColumns( const Reference
< XTableColumns
>& xTableColumns
, const std::vector
< sal_Int32
>& rvTableGrid
)
64 if ( rvTableGrid
.size() > 1 )
65 xTableColumns
->insertByIndex( 0, rvTableGrid
.size() - 1 );
66 std::vector
< sal_Int32
>::const_iterator
aTableGridIter( rvTableGrid
.begin() );
67 uno::Reference
< container::XIndexAccess
> xIndexAccess( xTableColumns
, UNO_QUERY_THROW
);
68 sal_Int32 nCols
= std::min
<sal_Int32
>(xIndexAccess
->getCount(), rvTableGrid
.size());
69 for (sal_Int32 n
= 0; n
< nCols
; ++n
)
71 Reference
< XPropertySet
> xPropSet( xIndexAccess
->getByIndex( n
), UNO_QUERY_THROW
);
72 xPropSet
->setPropertyValue( u
"Width"_ustr
, Any( static_cast< sal_Int32
>( *aTableGridIter
++ / 360 ) ) );
76 static void MergeCells( const uno::Reference
< XTable
>& xTable
, sal_Int32 nCol
, sal_Int32 nRow
, sal_Int32 nColSpan
, sal_Int32 nRowSpan
)
80 Reference
< XMergeableCellRange
> xRange( xTable
->createCursorByRange( xTable
->getCellRangeByPosition( nCol
, nRow
,nCol
+ nColSpan
- 1, nRow
+ nRowSpan
- 1 ) ), UNO_QUERY_THROW
);
81 if( xRange
->isMergeable() )
89 const TableStyle
& TableProperties::getUsedTableStyle( const ::oox::core::XmlFilterBase
& rFilterBase
, std::unique_ptr
<TableStyle
>& rTableStyleToDelete
)
91 ::oox::core::XmlFilterBase
& rBase( const_cast< ::oox::core::XmlFilterBase
& >( rFilterBase
) );
93 TableStyle
* pTableStyle
= nullptr;
95 pTableStyle
= &*mpTableStyle
;
96 else if ( !getStyleId().isEmpty() && rBase
.getTableStyles() )
98 const std::vector
< TableStyle
>& rTableStyles( rBase
.getTableStyles()->getTableStyles() );
99 const OUString
aStyleId( getStyleId() );
101 for (auto const& tableStyle
: rTableStyles
)
103 if ( const_cast< TableStyle
& >(tableStyle
).getStyleId() == aStyleId
)
105 pTableStyle
= &const_cast< TableStyle
& >(tableStyle
);
106 break; // we get the correct style
109 //if the pptx just has table style id, but no table style content, we will create the table style ourselves
112 rTableStyleToDelete
= CreateTableStyle(aStyleId
);
113 pTableStyle
= rTableStyleToDelete
.get();
119 static TableStyle theDefaultTableStyle
;
120 return theDefaultTableStyle
;
126 void TableProperties::pushToPropSet(const ::oox::core::XmlFilterBase
& rFilterBase
,
127 const Reference
<XPropertySet
>& xPropSet
,
128 const TextListStylePtr
& pMasterTextListStyle
)
130 uno::Reference
<XColumnRowRange
> xColumnRowRange(xPropSet
->getPropertyValue(u
"Model"_ustr
),
131 uno::UNO_QUERY_THROW
);
133 CreateTableColumns(xColumnRowRange
->getColumns(), mvTableGrid
);
134 CreateTableRows(xColumnRowRange
->getRows(), mvTableRows
);
136 std::unique_ptr
<TableStyle
> xTableStyleToDelete
;
137 const TableStyle
& rTableStyle(getUsedTableStyle(rFilterBase
, xTableStyleToDelete
));
140 for (auto& tableRow
: mvTableRows
)
142 sal_Int32 nColumn
= 0;
143 sal_Int32 nColumnSize
= tableRow
.getTableCells().size();
144 sal_Int32 nRemovedColumn
= 0;
145 sal_Int32 nRemovedRow
= 0;
147 for (sal_Int32 nColIndex
= 0; nColIndex
< nColumnSize
; nColIndex
++)
149 TableCell
& rTableCell(tableRow
.getTableCells().at(nColIndex
));
151 if (!rTableCell
.getvMerge() && !rTableCell
.gethMerge())
153 uno::Reference
<XTable
> xTable(xColumnRowRange
, uno::UNO_QUERY_THROW
);
154 bool bMerged
= false;
156 if ((rTableCell
.getRowSpan() > 1) || (rTableCell
.getGridSpan() > 1))
158 MergeCells(xTable
, nColumn
, nRow
, rTableCell
.getGridSpan(),
159 rTableCell
.getRowSpan());
161 if (rTableCell
.getGridSpan() > 1)
163 nRemovedColumn
= (rTableCell
.getGridSpan() - 1);
164 // MergeCells removes columns. Our loop does not know about those
165 // removed columns and we skip handling those removed columns.
166 nColIndex
+= nRemovedColumn
;
167 // It will adjust new column number after push current column's
168 // props with pushToXCell.
172 if (rTableCell
.getRowSpan() > 1)
173 nRemovedRow
= (rTableCell
.getRowSpan() - 1);
176 Reference
<XCellRange
> xCellRange(xTable
, UNO_QUERY_THROW
);
177 Reference
<XCell
> xCell
;
183 xCell
= xCellRange
->getCellByPosition(nColumn
, nRow
);
185 // Exception can come from TableModel::getCellByPosition when a column
186 // is removed while merging columns. So adjust again here.
189 xCell
= xCellRange
->getCellByPosition(nColumn
- nRemovedColumn
, nRow
);
193 xCell
= xCellRange
->getCellByPosition(nColumn
, nRow
);
196 sal_Int32 nMaxCol
= tableRow
.getTableCells().size() - nRemovedColumn
- 1;
197 sal_Int32 nMaxRow
= mvTableRows
.size() - nRemovedRow
- 1;
199 rTableCell
.pushToXCell(rFilterBase
, pMasterTextListStyle
, xCell
, *this, rTableStyle
,
200 nColumn
, nMaxCol
, nRow
, nMaxRow
);
203 nColumn
+= nRemovedColumn
;
212 xTableStyleToDelete
.reset();
216 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */