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 #include "precompiled_rptxml.hxx"
24 #include "xmlTable.hxx"
25 #include "xmlfilter.hxx"
26 #include <xmloff/xmltoken.hxx>
27 #include <xmloff/xmlnmspe.hxx>
28 #include <xmloff/nmspmap.hxx>
29 #include <xmloff/xmluconv.hxx>
30 #include "RptDef.hxx"
31 #include "xmlHelper.hxx"
32 #include "xmlEnums.hxx"
33 #ifndef RPT_XMLCOLUMN_HXX
34 #include "xmlColumn.hxx"
35 #endif
36 #include <com/sun/star/report/ForceNewPage.hpp>
37 #include "xmlCondPrtExpr.hxx"
38 #include "xmlStyleImport.hxx"
39 #include "xmlstrings.hrc"
40 #include <connectivity/dbtools.hxx>
41 #include <tools/debug.hxx>
42 #ifndef REPORTDESIGN_SHARED_XMLSTRINGS_HRC
43 #include "xmlstrings.hrc"
44 #endif
45 #include <com/sun/star/report/XShape.hpp>
46 #include <com/sun/star/report/XFixedLine.hpp>
47
48 #define MIN_WIDTH 80
49 #define MIN_HEIGHT 20
50
51 namespace rptxml
52 {
53 using namespace ::xmloff;
54 using namespace ::com::sun::star;
55 using ::com::sun::star::uno::Reference;
56 using namespace ::com::sun::star::xml::sax;
57 using ::com::sun::star::xml::sax::XAttributeList;
58
lcl_getForceNewPageOption(const::rtl::OUString & _sValue)59 sal_uInt16 lcl_getForceNewPageOption(const ::rtl::OUString& _sValue)
60 {
61 sal_uInt16 nRet = report::ForceNewPage::NONE;
62 const SvXMLEnumMapEntry* aXML_EnumMap = OXMLHelper::GetForceNewPageOptions();
63 SvXMLUnitConverter::convertEnum( nRet,_sValue,aXML_EnumMap );
64 return nRet;
65 }
DBG_NAME(rpt_OXMLTable)66 DBG_NAME( rpt_OXMLTable )
67
68 OXMLTable::OXMLTable( ORptFilter& rImport
69 ,sal_uInt16 nPrfx
70 ,const ::rtl::OUString& _sLocalName
71 ,const Reference< XAttributeList > & _xAttrList
72 ,const uno::Reference< report::XSection >& _xSection
73 )
74 :SvXMLImportContext( rImport, nPrfx, _sLocalName )
75 ,m_xSection(_xSection)
76 ,m_nColSpan(1)
77 ,m_nRowSpan(0)
78 ,m_nRowIndex(0)
79 ,m_nColumnIndex(0)
80 {
81 DBG_CTOR( rpt_OXMLTable,NULL);
82 OSL_ENSURE(_xAttrList.is(),"Attribute list is NULL!");
83 const SvXMLNamespaceMap& rMap = rImport.GetNamespaceMap();
84 const SvXMLTokenMap& rTokenMap = rImport.GetSectionElemTokenMap();
85
86 const sal_Int16 nLength = (m_xSection.is() && _xAttrList.is()) ? _xAttrList->getLength() : 0;
87 static const ::rtl::OUString s_sTRUE = ::xmloff::token::GetXMLToken(XML_TRUE);
88 try
89 {
90 for(sal_Int16 i = 0; i < nLength; ++i)
91 {
92 rtl::OUString sLocalName;
93 const rtl::OUString sAttrName = _xAttrList->getNameByIndex( i );
94 const sal_uInt16 nPrefix = rMap.GetKeyByAttrName( sAttrName,&sLocalName );
95 const rtl::OUString sValue = _xAttrList->getValueByIndex( i );
96
97 switch( rTokenMap.Get( nPrefix, sLocalName ) )
98 {
99 case XML_TOK_VISIBLE:
100 m_xSection->setVisible(sValue == s_sTRUE);
101 break;
102 case XML_TOK_FORCE_NEW_PAGE:
103 m_xSection->setForceNewPage(lcl_getForceNewPageOption(sValue));
104 break;
105 case XML_TOK_FORCE_NEW_COLUMN:
106 m_xSection->setNewRowOrCol(lcl_getForceNewPageOption(sValue));
107 break;
108 case XML_TOK_KEEP_TOGETHER:
109 m_xSection->setKeepTogether(sValue == s_sTRUE);
110 break;
111 case XML_TOK_SECTION_NAME:
112 m_xSection->setName(sValue);
113 break;
114 case XML_TOK_SECT_STYLE_NAME:
115 m_sStyleName = sValue;
116 break;
117 default:
118 break;
119 }
120 }
121 }
122 catch(Exception&)
123 {
124 OSL_ENSURE(0,"Exception catched while filling the section props");
125 }
126 }
127 // -----------------------------------------------------------------------------
~OXMLTable()128 OXMLTable::~OXMLTable()
129 {
130 DBG_DTOR( rpt_OXMLTable,NULL);
131 }
132 // -----------------------------------------------------------------------------
133
CreateChildContext(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName,const Reference<XAttributeList> & xAttrList)134 SvXMLImportContext* OXMLTable::CreateChildContext(
135 sal_uInt16 _nPrefix,
136 const ::rtl::OUString& _rLocalName,
137 const Reference< XAttributeList > & xAttrList )
138 {
139 SvXMLImportContext *pContext = 0;
140 ORptFilter& rImport = GetOwnImport();
141 const SvXMLTokenMap& rTokenMap = rImport.GetColumnTokenMap();
142 Reference<XMultiServiceFactory> xFactor = rImport.getServiceFactory();
143
144 switch( rTokenMap.Get( _nPrefix, _rLocalName ) )
145 {
146 case XML_TOK_TABLE_COLUMNS:
147 case XML_TOK_TABLE_ROWS:
148 pContext = new OXMLRowColumn( rImport, _nPrefix, _rLocalName,xAttrList ,this);
149 break;
150 case XML_TOK_ROW:
151 incrementRowIndex();
152 rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP );
153 pContext = new OXMLRowColumn( rImport, _nPrefix, _rLocalName,xAttrList,this);
154 break;
155 case XML_TOK_COLUMN:
156 rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP );
157 pContext = new OXMLRowColumn( rImport, _nPrefix, _rLocalName,xAttrList,this);
158 break;
159 case XML_TOK_CONDITIONAL_PRINT_EXPRESSION:
160 pContext = new OXMLCondPrtExpr( rImport, _nPrefix, _rLocalName,xAttrList,m_xSection.get());
161 break;
162 default:
163 break;
164 }
165
166 if( !pContext )
167 pContext = new SvXMLImportContext( rImport, _nPrefix, _rLocalName );
168
169 return pContext;
170 }
171 // -----------------------------------------------------------------------------
GetOwnImport()172 ORptFilter& OXMLTable::GetOwnImport()
173 {
174 return static_cast<ORptFilter&>(GetImport());
175 }
176 // -----------------------------------------------------------------------------
EndElement()177 void OXMLTable::EndElement()
178 {
179 try
180 {
181 if ( m_xSection.is() )
182 {
183 if ( m_sStyleName.getLength() )
184 {
185 const SvXMLStylesContext* pAutoStyles = GetImport().GetAutoStyles();
186 if ( pAutoStyles )
187 {
188 XMLPropStyleContext* pAutoStyle = PTR_CAST(XMLPropStyleContext,pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_TABLE_TABLE,m_sStyleName));
189 if ( pAutoStyle )
190 {
191 pAutoStyle->FillPropertySet(m_xSection.get());
192 }
193 }
194 } // if ( m_sStyleName.getLength() )
195 // set height
196 ::std::vector<sal_Int32>::iterator aIter = m_aHeight.begin();
197 ::std::vector<sal_Int32>::iterator aEnd = m_aHeight.end();
198 sal_Int32 nHeight = 0;
199 for (; aIter != aEnd; ++aIter)
200 nHeight += *aIter;
201 m_xSection->setHeight( nHeight );
202 // set positions, widths, and heights
203 sal_Int32 nLeftMargin = rptui::getStyleProperty<sal_Int32>(m_xSection->getReportDefinition(),PROPERTY_LEFTMARGIN);
204 sal_Int32 nPosY = 0;
205 ::std::vector< ::std::vector<TCell> >::iterator aRowIter = m_aGrid.begin();
206 ::std::vector< ::std::vector<TCell> >::iterator aRowEnd = m_aGrid.end();
207 for (sal_Int32 i = 0; aRowIter != aRowEnd; ++aRowIter,++i)
208 {
209 sal_Int32 nPosX = nLeftMargin;
210 ::std::vector<TCell>::iterator aColIter = (*aRowIter).begin();
211 ::std::vector<TCell>::iterator aColEnd = (*aRowIter).end();
212 for (sal_Int32 j = 0; aColIter != aColEnd; ++aColIter,++j)
213 {
214 TCell& rCell = *aColIter;
215 if ( !rCell.xElements.empty())
216 {
217 ::std::vector< uno::Reference< report::XReportComponent> >::iterator aCellIter = rCell.xElements.begin();
218 const ::std::vector< uno::Reference< report::XReportComponent> >::iterator aCellEnd = rCell.xElements.end();
219 for (;aCellIter != aCellEnd ; ++aCellIter)
220 {
221 uno::Reference<report::XShape> xShape(*aCellIter,uno::UNO_QUERY);
222 if ( xShape.is() )
223 {
224 xShape->setPositionX(xShape->getPositionX() + nLeftMargin);
225 }
226 else
227 {
228 sal_Int32 nWidth = rCell.nWidth;
229 sal_Int32 nColSpan = rCell.nColSpan;
230 if ( nColSpan > 1 )
231 {
232 ::std::vector<TCell>::iterator aWidthIter = aColIter + 1;
233 while ( nColSpan > 1 )
234 {
235 nWidth += (aWidthIter++)->nWidth;
236 --nColSpan;
237 }
238 }
239 nHeight = rCell.nHeight;
240 sal_Int32 nRowSpan = rCell.nRowSpan;
241 if ( nRowSpan > 1 )
242 {
243 ::std::vector< ::std::vector<TCell> >::iterator aHeightIter = aRowIter + 1;
244 while( nRowSpan > 1)
245 {
246 nHeight += (*aHeightIter)[j].nHeight;
247 ++aHeightIter;
248 --nRowSpan;
249 }
250 }
251 Reference<XFixedLine> xFixedLine(*aCellIter,uno::UNO_QUERY);
252 if ( xFixedLine.is() )
253 {
254 if ( xFixedLine->getOrientation() == 1 ) // vertical
255 {
256 OSL_ENSURE(static_cast<sal_uInt32>(j+1) < m_aWidth.size(),"Illegal pos of col iter. There should be an empty cell for the next line part.");
257 nWidth += m_aWidth[j+1];
258 if ( nWidth < MIN_WIDTH )
259 nWidth = MIN_WIDTH;
260 }
261 else if ( nHeight < MIN_HEIGHT )
262 nHeight = MIN_HEIGHT;
263 }
264 try
265 {
266 (*aCellIter)->setSize(awt::Size(nWidth,nHeight));
267 (*aCellIter)->setPosition(awt::Point(nPosX,nPosY));
268 }
269 catch(beans::PropertyVetoException)
270 {
271 OSL_ENSURE(0,"Could not set the correct position or size!");
272 }
273 }
274 }
275 }
276 nPosX += m_aWidth[j];
277 }
278 nPosY += m_aHeight[i];
279 }
280 } // if ( m_xComponent.is() )
281 }
282 catch(Exception&)
283 {
284 OSL_ENSURE(0,"OXMLTable::EndElement -> exception catched");
285 }
286 }
287 // -----------------------------------------------------------------------------
addCell(const Reference<XReportComponent> & _xElement)288 void OXMLTable::addCell(const Reference<XReportComponent>& _xElement)
289 {
290 uno::Reference<report::XShape> xShape(_xElement,uno::UNO_QUERY);
291 OSL_ENSURE(static_cast<sal_uInt32>(m_nRowIndex-1 ) < m_aGrid.size() && static_cast<sal_uInt32>( m_nColumnIndex-1 ) < m_aGrid[m_nRowIndex-1].size(),
292 "OXMLTable::addCell: Invalid column and row index");
293 if ( static_cast<sal_uInt32>(m_nRowIndex-1 ) < m_aGrid.size() && static_cast<sal_uInt32>( m_nColumnIndex-1 ) < m_aGrid[m_nRowIndex-1].size() )
294 {
295 TCell& rCell = m_aGrid[m_nRowIndex-1][m_nColumnIndex-1];
296 if ( _xElement.is() )
297 rCell.xElements.push_back( _xElement );
298 if ( !xShape.is() )
299 {
300 rCell.nWidth = m_aWidth[m_nColumnIndex-1];
301 rCell.nHeight = m_aHeight[m_nRowIndex-1];
302 rCell.nColSpan = m_nColSpan;
303 rCell.nRowSpan = m_nRowSpan;
304 }
305 }
306
307 if ( !xShape.is() )
308 m_nColSpan = m_nRowSpan = 1;
309 }
310 // -----------------------------------------------------------------------------
incrementRowIndex()311 void OXMLTable::incrementRowIndex()
312 {
313 ++m_nRowIndex;
314 m_nColumnIndex = 0;
315 m_aGrid.push_back(::std::vector<TCell>(m_aWidth.size()));
316 }
317 //----------------------------------------------------------------------------
318 } // namespace rptxml
319 // -----------------------------------------------------------------------------
320