LibreOffice Module reportdesign (master) 1
xmlTable.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19#include "xmlTable.hxx"
20#include "xmlfilter.hxx"
21#include <o3tl/safeint.hxx>
22#include <utility>
23#include <xmloff/xmltoken.hxx>
25#include <xmloff/xmlstyle.hxx>
26#include <xmloff/prstylei.hxx>
27#include <xmloff/xmluconv.hxx>
29#include <RptDef.hxx>
30#include "xmlHelper.hxx"
31#include "xmlEnums.hxx"
32#include "xmlColumn.hxx"
33#include <com/sun/star/report/ForceNewPage.hpp>
34#include "xmlCondPrtExpr.hxx"
35#include <strings.hxx>
36#include <com/sun/star/report/XShape.hpp>
37#include <com/sun/star/report/XFixedLine.hpp>
38#include <osl/diagnose.h>
40
41#include <numeric>
42
43#define MIN_WIDTH 80
44#define MIN_HEIGHT 20
45
46namespace rptxml
47{
48 using namespace ::xmloff;
49 using namespace ::com::sun::star;
50 using ::com::sun::star::uno::Reference;
51 using namespace ::com::sun::star::xml::sax;
52
53 static sal_Int16 lcl_getForceNewPageOption(std::string_view _sValue)
54 {
55 sal_Int16 nRet = report::ForceNewPage::NONE;
57 (void)SvXMLUnitConverter::convertEnum( nRet,_sValue,aXML_EnumMap );
58 return nRet;
59 }
60
61OXMLTable::OXMLTable( ORptFilter& rImport
62 ,const Reference< XFastAttributeList > & _xAttrList
63 ,uno::Reference< report::XSection > _xSection
64 )
65:SvXMLImportContext( rImport )
66,m_xSection(std::move(_xSection))
67,m_nColSpan(1)
68,m_nRowSpan(0)
69,m_nRowIndex(0)
70,m_nColumnIndex(0)
71{
72
73 if (!m_xSection.is())
74 return;
75 try
76 {
77 for (auto &aIter : sax_fastparser::castToFastAttributeList( _xAttrList ))
78 {
79 switch( aIter.getToken() )
80 {
81 case XML_ELEMENT(REPORT, XML_VISIBLE):
82 m_xSection->setVisible(IsXMLToken(aIter, XML_TRUE));
83 break;
84 case XML_ELEMENT(REPORT, XML_FORCE_NEW_PAGE):
85 m_xSection->setForceNewPage(lcl_getForceNewPageOption(aIter.toView()));
86 break;
87 case XML_ELEMENT(REPORT, XML_FORCE_NEW_COLUMN):
88 m_xSection->setNewRowOrCol(lcl_getForceNewPageOption(aIter.toView()));
89 break;
90 case XML_ELEMENT(REPORT, XML_KEEP_TOGETHER):
91 m_xSection->setKeepTogether(IsXMLToken(aIter, XML_TRUE));
92 break;
93 case XML_ELEMENT(TABLE, XML_NAME):
94 m_xSection->setName(aIter.toString());
95 break;
96 case XML_ELEMENT(TABLE, XML_STYLE_NAME):
97 m_sStyleName = aIter.toString();
98 break;
99 default:
100 XMLOFF_WARN_UNKNOWN("reportdesign", aIter);
101 break;
102 }
103 }
104 }
105 catch(Exception&)
106 {
107 TOOLS_WARN_EXCEPTION( "reportdesign", "Exception caught while filling the section props");
108 }
109}
110
111OXMLTable::~OXMLTable()
112{
113}
114
115css::uno::Reference< css::xml::sax::XFastContextHandler > OXMLTable::createFastChildContext(
116 sal_Int32 nElement,
117 const Reference< XFastAttributeList > & xAttrList )
118{
119 css::uno::Reference< css::xml::sax::XFastContextHandler > xContext;
120 ORptFilter& rImport = GetOwnImport();
121
122 switch( nElement )
123 {
124 case XML_ELEMENT(TABLE, XML_TABLE_COLUMNS):
126 xContext = new OXMLRowColumn( rImport,xAttrList ,this);
127 break;
128 case XML_ELEMENT(TABLE, XML_TABLE_ROW):
129 incrementRowIndex();
130 rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP );
131 xContext = new OXMLRowColumn( rImport,xAttrList,this);
132 break;
133 case XML_ELEMENT(TABLE, XML_TABLE_COLUMN):
134 rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP );
135 xContext = new OXMLRowColumn( rImport,xAttrList,this);
136 break;
137 case XML_ELEMENT(REPORT, XML_CONDITIONAL_PRINT_EXPRESSION):
138 xContext = new OXMLCondPrtExpr( rImport,xAttrList,m_xSection);
139 break;
140 default:
141 break;
142 }
143
144 return xContext;
145}
146
147ORptFilter& OXMLTable::GetOwnImport()
148{
149 return static_cast<ORptFilter&>(GetImport());
150}
151
152void OXMLTable::endFastElement(sal_Int32 )
153{
154 try
155 {
156 if ( m_xSection.is() )
157 {
158 if ( !m_sStyleName.isEmpty() )
159 {
160 const SvXMLStylesContext* pAutoStyles = GetImport().GetAutoStyles();
161 if ( pAutoStyles )
162 {
163 XMLPropStyleContext* pAutoStyle = const_cast<XMLPropStyleContext*>(dynamic_cast< const XMLPropStyleContext *>(pAutoStyles->FindStyleChildContext(XmlStyleFamily::TABLE_TABLE,m_sStyleName)));
164 if ( pAutoStyle )
165 {
166 pAutoStyle->FillPropertySet(m_xSection);
167 }
168 }
169 }
170 // set height
171 sal_Int32 nHeight = std::accumulate(m_aHeight.begin(), m_aHeight.end(), sal_Int32(0),
172 [](const sal_Int32& rSum, const sal_Int32& rHeight) { return rSum + rHeight; });
173 m_xSection->setHeight( nHeight );
174 // set positions, widths, and heights
175 sal_Int32 nLeftMargin = rptui::getStyleProperty<sal_Int32>(m_xSection->getReportDefinition(),PROPERTY_LEFTMARGIN);
176 sal_Int32 nPosY = 0;
177 ::std::vector< ::std::vector<TCell> >::iterator aRowIter = m_aGrid.begin();
178 ::std::vector< ::std::vector<TCell> >::const_iterator aRowEnd = m_aGrid.end();
179 for (sal_Int32 i = 0; aRowIter != aRowEnd; ++aRowIter,++i)
180 {
181 sal_Int32 nPosX = nLeftMargin;
182 ::std::vector<TCell>::iterator aColIter = (*aRowIter).begin();
183 ::std::vector<TCell>::const_iterator aColEnd = (*aRowIter).end();
184 for (sal_Int32 j = 0; aColIter != aColEnd; ++aColIter,++j)
185 {
186 TCell& rCell = *aColIter;
187 for (const auto& rxElement : rCell.xElements)
188 {
189 uno::Reference<report::XShape> xShape(rxElement,uno::UNO_QUERY);
190 if ( xShape.is() )
191 {
192 xShape->setPositionX(xShape->getPositionX() + nLeftMargin);
193 }
194 else
195 {
196 sal_Int32 nWidth = rCell.nWidth;
197 sal_Int32 nColSpan = rCell.nColSpan;
198 if ( nColSpan > 1 )
199 {
200 ::std::vector<TCell>::const_iterator aWidthIter = aColIter + 1;
201 while ( nColSpan > 1 )
202 {
203 nWidth += (aWidthIter++)->nWidth;
204 --nColSpan;
205 }
206 }
207 nHeight = rCell.nHeight;
208 sal_Int32 nRowSpan = rCell.nRowSpan;
209 if ( nRowSpan > 1 )
210 {
211 ::std::vector< ::std::vector<TCell> >::const_iterator aHeightIter = aRowIter + 1;
212 while( nRowSpan > 1)
213 {
214 nHeight += (*aHeightIter)[j].nHeight;
215 ++aHeightIter;
216 --nRowSpan;
217 }
218 }
219 Reference<XFixedLine> xFixedLine(rxElement,uno::UNO_QUERY);
220 if ( xFixedLine.is() )
221 {
222 if ( xFixedLine->getOrientation() == 1 ) // vertical
223 {
224 OSL_ENSURE(o3tl::make_unsigned(j+1) < m_aWidth.size(),"Illegal pos of col iter. There should be an empty cell for the next line part.");
225 nWidth += m_aWidth[j+1];
226 if ( nWidth < MIN_WIDTH )
227 nWidth = MIN_WIDTH;
228 }
229 else if ( nHeight < MIN_HEIGHT )
230 nHeight = MIN_HEIGHT;
231 }
232 try
233 {
234 rxElement->setSize(awt::Size(nWidth,nHeight));
235 rxElement->setPosition(awt::Point(nPosX,nPosY));
236 rxElement->setAutoGrow(rCell.bAutoHeight);
237 }
238 catch(const beans::PropertyVetoException &)
239 {
240 OSL_FAIL("Could not set the correct position or size!");
241 }
242 }
243 }
244 nPosX += m_aWidth[j];
245 }
246 nPosY += m_aHeight[i];
247 }
248 }
249 }
250 catch(Exception&)
251 {
252 TOOLS_WARN_EXCEPTION( "reportdesign", "OXMLTable::EndElement");
253 }
254}
255
256void OXMLTable::addCell(const Reference<XReportComponent>& _xElement)
257{
258 uno::Reference<report::XShape> xShape(_xElement,uno::UNO_QUERY);
259 OSL_ENSURE(o3tl::make_unsigned(m_nRowIndex-1 ) < m_aGrid.size() && o3tl::make_unsigned( m_nColumnIndex-1 ) < m_aGrid[m_nRowIndex-1].size(),
260 "OXMLTable::addCell: Invalid column and row index");
261 if ( o3tl::make_unsigned(m_nRowIndex-1 ) < m_aGrid.size() && o3tl::make_unsigned( m_nColumnIndex-1 ) < m_aGrid[m_nRowIndex-1].size() )
262 {
263 TCell& rCell = m_aGrid[m_nRowIndex-1][m_nColumnIndex-1];
264 if ( _xElement.is() )
265 rCell.xElements.push_back( _xElement );
266 if ( !xShape.is() )
267 {
268 rCell.nWidth = m_aWidth[m_nColumnIndex-1];
269 rCell.nHeight = m_aHeight[m_nRowIndex-1];
270 rCell.bAutoHeight = m_aAutoHeight[m_nRowIndex-1];
271 rCell.nColSpan = m_nColSpan;
272 rCell.nRowSpan = m_nRowSpan;
273 }
274 }
275
276 if ( !xShape.is() )
277 m_nColSpan = m_nRowSpan = 1;
278}
279
280void OXMLTable::incrementRowIndex()
281{
282 ++m_nRowIndex;
283 m_nColumnIndex = 0;
284 m_aGrid.push_back(::std::vector<TCell>(m_aWidth.size()));
285}
286
287} // namespace rptxml
288
289
290/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const SvXMLStyleContext * FindStyleChildContext(XmlStyleFamily nFamily, const OUString &rName, bool bCreateIndex=false) const
css::uno::Reference< css::style::XAutoStyleFamily > GetAutoStyles(XmlStyleFamily nFamily) const
static bool convertEnum(EnumT &rEnum, std::u16string_view rValue, const SvXMLEnumMapEntry< EnumT > *pMap)
virtual void FillPropertySet(const css::uno::Reference< css::beans::XPropertySet > &rPropSet)
static const SvXMLEnumMapEntry< sal_Int16 > * GetForceNewPageOptions()
Definition: xmlHelper.cxx:197
OXMLTable(const OXMLTable &)=delete
#define TOOLS_WARN_EXCEPTION(area, stream)
tools::Long const nLeftMargin
@ Exception
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
static sal_Int16 lcl_getForceNewPageOption(std::string_view _sValue)
Definition: xmlTable.cxx:53
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
OUString toString(OptionInfo const *info)
XML_TRUE
XML_TABLE_ROWS
bool IsXMLToken(std::u16string_view rString, enum XMLTokenEnum eToken)
constexpr OUStringLiteral PROPERTY_LEFTMARGIN
Definition: strings.hxx:102
::std::vector< css::uno::Reference< css::report::XReportComponent > > xElements
Definition: xmlTable.hxx:39
#define PROGRESS_BAR_STEP
Definition: xmlEnums.hxx:22
#define MIN_HEIGHT
Definition: xmlTable.cxx:44
#define MIN_WIDTH
Definition: xmlTable.cxx:43
TABLE
#define XMLOFF_WARN_UNKNOWN(area, rIter)
#define XML_ELEMENT(prefix, name)