/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: xmlTable.cxx,v $ * $Revision: 1.6 $ * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #include "precompiled_reportdesign.hxx" #include "xmlTable.hxx" #include "xmlfilter.hxx" #include #include #include #include #include "RptDef.hxx" #include "xmlHelper.hxx" #include "xmlEnums.hxx" #ifndef RPT_XMLCOLUMN_HXX #include "xmlColumn.hxx" #endif #include #include "xmlCondPrtExpr.hxx" #include "xmlStyleImport.hxx" #include "xmlstrings.hrc" #include #include #ifndef REPORTDESIGN_SHARED_XMLSTRINGS_HRC #include "xmlstrings.hrc" #endif #include #include #define MIN_WIDTH 80 #define MIN_HEIGHT 20 namespace rptxml { using namespace ::xmloff; using namespace ::com::sun::star; using ::com::sun::star::uno::Reference; using namespace ::com::sun::star::xml::sax; using ::com::sun::star::xml::sax::XAttributeList; sal_uInt16 lcl_getForceNewPageOption(const ::rtl::OUString& _sValue) { sal_uInt16 nRet = report::ForceNewPage::NONE; const SvXMLEnumMapEntry* aXML_EnumMap = OXMLHelper::GetForceNewPageOptions(); SvXMLUnitConverter::convertEnum( nRet,_sValue,aXML_EnumMap ); return nRet; } DBG_NAME( rpt_OXMLTable ) OXMLTable::OXMLTable( ORptFilter& rImport ,sal_uInt16 nPrfx ,const ::rtl::OUString& _sLocalName ,const Reference< XAttributeList > & _xAttrList ,const uno::Reference< report::XSection >& _xSection ) :SvXMLImportContext( rImport, nPrfx, _sLocalName ) ,m_xSection(_xSection) ,m_nColSpan(1) ,m_nRowSpan(0) ,m_nRowIndex(0) ,m_nColumnIndex(0) { DBG_CTOR( rpt_OXMLTable,NULL); OSL_ENSURE(_xAttrList.is(),"Attribute list is NULL!"); const SvXMLNamespaceMap& rMap = rImport.GetNamespaceMap(); const SvXMLTokenMap& rTokenMap = rImport.GetSectionElemTokenMap(); const sal_Int16 nLength = (m_xSection.is() && _xAttrList.is()) ? _xAttrList->getLength() : 0; static const ::rtl::OUString s_sTRUE = ::xmloff::token::GetXMLToken(XML_TRUE); try { for(sal_Int16 i = 0; i < nLength; ++i) { rtl::OUString sLocalName; const rtl::OUString sAttrName = _xAttrList->getNameByIndex( i ); const sal_uInt16 nPrefix = rMap.GetKeyByAttrName( sAttrName,&sLocalName ); const rtl::OUString sValue = _xAttrList->getValueByIndex( i ); switch( rTokenMap.Get( nPrefix, sLocalName ) ) { case XML_TOK_VISIBLE: m_xSection->setVisible(sValue == s_sTRUE); break; case XML_TOK_FORCE_NEW_PAGE: m_xSection->setForceNewPage(lcl_getForceNewPageOption(sValue)); break; case XML_TOK_FORCE_NEW_COLUMN: m_xSection->setNewRowOrCol(lcl_getForceNewPageOption(sValue)); break; case XML_TOK_KEEP_TOGETHER: m_xSection->setKeepTogether(sValue == s_sTRUE); break; case XML_TOK_SECTION_NAME: m_xSection->setName(sValue); break; case XML_TOK_SECT_STYLE_NAME: m_sStyleName = sValue; break; default: break; } } } catch(Exception&) { OSL_ENSURE(0,"Exception catched while filling the section props"); } } // ----------------------------------------------------------------------------- OXMLTable::~OXMLTable() { DBG_DTOR( rpt_OXMLTable,NULL); } // ----------------------------------------------------------------------------- SvXMLImportContext* OXMLTable::CreateChildContext( sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName, const Reference< XAttributeList > & xAttrList ) { SvXMLImportContext *pContext = 0; ORptFilter& rImport = GetOwnImport(); const SvXMLTokenMap& rTokenMap = rImport.GetColumnTokenMap(); Reference xFactor = rImport.getServiceFactory(); switch( rTokenMap.Get( _nPrefix, _rLocalName ) ) { case XML_TOK_TABLE_COLUMNS: case XML_TOK_TABLE_ROWS: pContext = new OXMLRowColumn( rImport, _nPrefix, _rLocalName,xAttrList ,this); break; case XML_TOK_ROW: incrementRowIndex(); rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); pContext = new OXMLRowColumn( rImport, _nPrefix, _rLocalName,xAttrList,this); break; case XML_TOK_COLUMN: rImport.GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP ); pContext = new OXMLRowColumn( rImport, _nPrefix, _rLocalName,xAttrList,this); break; case XML_TOK_CONDITIONAL_PRINT_EXPRESSION: pContext = new OXMLCondPrtExpr( rImport, _nPrefix, _rLocalName,xAttrList,m_xSection.get()); break; default: break; } if( !pContext ) pContext = new SvXMLImportContext( rImport, _nPrefix, _rLocalName ); return pContext; } // ----------------------------------------------------------------------------- ORptFilter& OXMLTable::GetOwnImport() { return static_cast(GetImport()); } // ----------------------------------------------------------------------------- void OXMLTable::EndElement() { try { if ( m_xSection.is() ) { if ( m_sStyleName.getLength() ) { const SvXMLStylesContext* pAutoStyles = GetImport().GetAutoStyles(); if ( pAutoStyles ) { XMLPropStyleContext* pAutoStyle = PTR_CAST(XMLPropStyleContext,pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_TABLE_TABLE,m_sStyleName)); if ( pAutoStyle ) { pAutoStyle->FillPropertySet(m_xSection.get()); } } } // if ( m_sStyleName.getLength() ) // set height ::std::vector::iterator aIter = m_aHeight.begin(); ::std::vector::iterator aEnd = m_aHeight.end(); sal_Int32 nHeight = 0; for (; aIter != aEnd; ++aIter) nHeight += *aIter; m_xSection->setHeight( nHeight ); // set positions, widths, and heights sal_Int32 nLeftMargin = rptui::getStyleProperty(m_xSection->getReportDefinition(),PROPERTY_LEFTMARGIN); sal_Int32 nPosY = 0; ::std::vector< ::std::vector >::iterator aRowIter = m_aGrid.begin(); ::std::vector< ::std::vector >::iterator aRowEnd = m_aGrid.end(); for (sal_Int32 i = 0; aRowIter != aRowEnd; ++aRowIter,++i) { sal_Int32 nPosX = nLeftMargin; ::std::vector::iterator aColIter = (*aRowIter).begin(); ::std::vector::iterator aColEnd = (*aRowIter).end(); for (sal_Int32 j = 0; aColIter != aColEnd; ++aColIter,++j) { TCell& rCell = *aColIter; if ( !rCell.xElements.empty()) { ::std::vector< uno::Reference< report::XReportComponent> >::iterator aCellIter = rCell.xElements.begin(); const ::std::vector< uno::Reference< report::XReportComponent> >::iterator aCellEnd = rCell.xElements.end(); for (;aCellIter != aCellEnd ; ++aCellIter) { uno::Reference xShape(*aCellIter,uno::UNO_QUERY); if ( xShape.is() ) { xShape->setPositionX(xShape->getPositionX() + nLeftMargin); } else { sal_Int32 nWidth = rCell.nWidth; sal_Int32 nColSpan = rCell.nColSpan; if ( nColSpan > 1 ) { ::std::vector::iterator aWidthIter = aColIter + 1; while ( nColSpan > 1 ) { nWidth += (aWidthIter++)->nWidth; --nColSpan; } } nHeight = rCell.nHeight; sal_Int32 nRowSpan = rCell.nRowSpan; if ( nRowSpan > 1 ) { ::std::vector< ::std::vector >::iterator aHeightIter = aRowIter + 1; while( nRowSpan > 1) { nHeight += (*aHeightIter)[j].nHeight; ++aHeightIter; --nRowSpan; } } Reference xFixedLine(*aCellIter,uno::UNO_QUERY); if ( xFixedLine.is() ) { if ( xFixedLine->getOrientation() == 1 ) // vertical { OSL_ENSURE(static_cast(j+1) < m_aWidth.size(),"Illegal pos of col iter. There should be an empty cell for the next line part."); nWidth += m_aWidth[j+1]; if ( nWidth < MIN_WIDTH ) nWidth = MIN_WIDTH; } else if ( nHeight < MIN_HEIGHT ) nHeight = MIN_HEIGHT; } try { (*aCellIter)->setSize(awt::Size(nWidth,nHeight)); (*aCellIter)->setPosition(awt::Point(nPosX,nPosY)); } catch(beans::PropertyVetoException) { OSL_ENSURE(0,"Could not set the correct position or size!"); } } } } nPosX += m_aWidth[j]; } nPosY += m_aHeight[i]; } } // if ( m_xComponent.is() ) } catch(Exception&) { OSL_ENSURE(0,"OXMLTable::EndElement -> exception catched"); } } // ----------------------------------------------------------------------------- void OXMLTable::addCell(const Reference& _xElement) { uno::Reference xShape(_xElement,uno::UNO_QUERY); OSL_ENSURE(static_cast(m_nRowIndex-1 ) < m_aGrid.size() && static_cast( m_nColumnIndex-1 ) < m_aGrid[m_nRowIndex-1].size(), "OXMLTable::addCell: Invalid column and row index"); if ( static_cast(m_nRowIndex-1 ) < m_aGrid.size() && static_cast( m_nColumnIndex-1 ) < m_aGrid[m_nRowIndex-1].size() ) { TCell& rCell = m_aGrid[m_nRowIndex-1][m_nColumnIndex-1]; if ( _xElement.is() ) rCell.xElements.push_back( _xElement ); if ( !xShape.is() ) { rCell.nWidth = m_aWidth[m_nColumnIndex-1]; rCell.nHeight = m_aHeight[m_nRowIndex-1]; rCell.nColSpan = m_nColSpan; rCell.nRowSpan = m_nRowSpan; } } if ( !xShape.is() ) m_nColSpan = m_nRowSpan = 1; } // ----------------------------------------------------------------------------- void OXMLTable::incrementRowIndex() { ++m_nRowIndex; m_nColumnIndex = 0; m_aGrid.push_back(::std::vector(m_aWidth.size())); } //---------------------------------------------------------------------------- } // namespace rptxml // -----------------------------------------------------------------------------