/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #include "oox/drawingml/chart/titleconverter.hxx" #include #include #include #include #include #include #include #include "oox/drawingml/textbody.hxx" #include "oox/drawingml/textparagraph.hxx" #include "oox/drawingml/chart/datasourceconverter.hxx" #include "oox/drawingml/chart/titlemodel.hxx" #include "oox/helper/containerhelper.hxx" #include #include #include "oox/drawingml/chart/modelbase.hxx" namespace oox { namespace drawingml { namespace chart { // ============================================================================ using namespace ::com::sun::star::awt; using namespace ::com::sun::star::chart2; using namespace ::com::sun::star::chart2::data; using namespace ::com::sun::star::uno; using ::oox::core::XmlFilterBase; using ::rtl::OUString; using namespace ::com::sun::star::drawing; // ============================================================================ TextConverter::TextConverter( const ConverterRoot& rParent, TextModel& rModel ) : ConverterBase< TextModel >( rParent, rModel ) { } TextConverter::~TextConverter() { } Reference< XDataSequence > TextConverter::createDataSequence( const OUString& rRole ) { Reference< XDataSequence > xDataSeq; if( mrModel.mxDataSeq.is() ) { DataSequenceConverter aDataSeqConv( *this, *mrModel.mxDataSeq ); xDataSeq = aDataSeqConv.createDataSequence( rRole ); } return xDataSeq; } Sequence< Reference< XFormattedString > > TextConverter::createStringSequence( const OUString& rDefaultText, const ModelRef< TextBody >& rxTextProp, ObjectType eObjType ) { OSL_ENSURE( !mrModel.mxDataSeq || !mrModel.mxTextBody, "TextConverter::createStringSequence - linked string and rich text found" ); ::std::vector< Reference< XFormattedString > > aStringVec; if( mrModel.mxTextBody.is() ) { // rich-formatted text objects can be created, but currently Chart2 is not able to show them const TextParagraphVector& rTextParas = mrModel.mxTextBody->getParagraphs(); for( TextParagraphVector::const_iterator aPIt = rTextParas.begin(), aPEnd = rTextParas.end(); aPIt != aPEnd; ++aPIt ) { const TextParagraph& rTextPara = **aPIt; const TextCharacterProperties& rParaProps = rTextPara.getProperties().getTextCharacterProperties(); for( TextRunVector::const_iterator aRIt = rTextPara.getRuns().begin(), aREnd = rTextPara.getRuns().end(); aRIt != aREnd; ++aRIt ) { const TextRun& rTextRun = **aRIt; bool bAddNewLine = (aRIt + 1 == aREnd) && (aPIt + 1 != aPEnd); Reference< XFormattedString > xFmtStr = appendFormattedString( aStringVec, rTextRun.getText(), bAddNewLine ); PropertySet aPropSet( xFmtStr ); TextCharacterProperties aRunProps( rParaProps ); aRunProps.assignUsed( rTextRun.getTextCharacterProperties() ); getFormatter().convertTextFormatting( aPropSet, aRunProps, eObjType ); } } } else { OUString aString; // try to create string from linked data if( mrModel.mxDataSeq.is() && !mrModel.mxDataSeq->maData.empty() ) mrModel.mxDataSeq->maData.begin()->second >>= aString; // no linked string -> fall back to default string if( aString.getLength() == 0 ) aString = rDefaultText; // create formatted string object if( aString.getLength() > 0 ) { Reference< XFormattedString > xFmtStr = appendFormattedString( aStringVec, aString, false ); PropertySet aPropSet( xFmtStr ); getFormatter().convertTextFormatting( aPropSet, rxTextProp, eObjType ); } } return ContainerHelper::vectorToSequence( aStringVec ); } Reference< XFormattedString > TextConverter::appendFormattedString( ::std::vector< Reference< XFormattedString > >& orStringVec, const OUString& rString, bool bAddNewLine ) const { Reference< XFormattedString > xFmtStr; try { xFmtStr.set( ConverterRoot::createInstance( CREATE_OUSTRING( "com.sun.star.chart2.FormattedString" ) ), UNO_QUERY_THROW ); xFmtStr->setString( bAddNewLine ? (rString + OUString( sal_Unicode( '\n' ) )) : rString ); orStringVec.push_back( xFmtStr ); } catch( Exception& ) { } return xFmtStr; } // ============================================================================ TitleConverter::TitleConverter( const ConverterRoot& rParent, TitleModel& rModel ) : ConverterBase< TitleModel >( rParent, rModel ) { } TitleConverter::~TitleConverter() { } void TitleConverter::convertFromModel( const Reference< XTitled >& rxTitled, const OUString& rAutoTitle, ObjectType eObjType, sal_Int32 nMainIdx, sal_Int32 nSubIdx ) { if( rxTitled.is() ) { // create the formatted strings TextModel& rText = mrModel.mxText.getOrCreate(); TextConverter aTextConv( *this, rText ); Sequence< Reference< XFormattedString > > aStringSeq = aTextConv.createStringSequence( rAutoTitle, mrModel.mxTextProp, eObjType ); if( aStringSeq.hasElements() ) try { // create the title object and set the string data Reference< XTitle > xTitle( createInstance( CREATE_OUSTRING( "com.sun.star.chart2.Title" ) ), UNO_QUERY_THROW ); xTitle->setText( aStringSeq ); rxTitled->setTitleObject( xTitle ); // frame formatting (text formatting already done in TextConverter::createStringSequence()) PropertySet aPropSet( xTitle ); getFormatter().convertFrameFormatting( aPropSet, mrModel.mxShapeProp, eObjType ); // frame rotation OSL_ENSURE( !mrModel.mxTextProp || !rText.mxTextBody, "TitleConverter::convertFromModel - multiple text properties" ); ModelRef< TextBody > xTextProp = mrModel.mxTextProp.is() ? mrModel.mxTextProp : rText.mxTextBody; getFormatter().convertTextRotation( aPropSet, xTextProp, true ); // register the title and layout data for conversion of position registerTitleLayout( xTitle, mrModel.mxLayout, eObjType, nMainIdx, nSubIdx ); } catch( Exception& ) { } } } // ============================================================================ LegendConverter::LegendConverter( const ConverterRoot& rParent, LegendModel& rModel ) : ConverterBase< LegendModel >( rParent, rModel ) { } LegendConverter::~LegendConverter() { } void LegendConverter::convertFromModel( const Reference< XDiagram >& rxDiagram ) { if( rxDiagram.is() ) try { namespace cssc = ::com::sun::star::chart; namespace cssc2 = ::com::sun::star::chart2; // create the legend Reference< XLegend > xLegend( createInstance( CREATE_OUSTRING( "com.sun.star.chart2.Legend" ) ), UNO_QUERY_THROW ); rxDiagram->setLegend( xLegend ); PropertySet aPropSet( xLegend ); aPropSet.setProperty( PROP_Show, true ); // legend formatting getFormatter().convertFormatting( aPropSet, mrModel.mxShapeProp, mrModel.mxTextProp, OBJECTTYPE_LEGEND ); // predefined legend position and expansion cssc2::LegendPosition eLegendPos = cssc2::LegendPosition_CUSTOM; cssc::ChartLegendExpansion eLegendExpand = cssc::ChartLegendExpansion_CUSTOM; RelativePosition eRelPos; bool bTopRight=0; switch( mrModel.mnPosition ) { case XML_l: eLegendPos = cssc2::LegendPosition_LINE_START; eLegendExpand = cssc::ChartLegendExpansion_HIGH; break; case XML_r: eLegendPos = cssc2::LegendPosition_LINE_END; eLegendExpand = cssc::ChartLegendExpansion_HIGH; break; case XML_tr: // top-right not supported eLegendPos = LegendPosition_CUSTOM; eRelPos.Primary = 1; eRelPos.Secondary =0; eRelPos.Anchor = Alignment_TOP_RIGHT; bTopRight=1; break; case XML_t: eLegendPos = cssc2::LegendPosition_PAGE_START; eLegendExpand = cssc::ChartLegendExpansion_WIDE; break; case XML_b: eLegendPos = cssc2::LegendPosition_PAGE_END; eLegendExpand = cssc::ChartLegendExpansion_WIDE; break; } bool bManualLayout=false; // manual positioning and size if( mrModel.mxLayout.get() ) { LayoutConverter aLayoutConv( *this, *mrModel.mxLayout ); // manual size needs ChartLegendExpansion_CUSTOM if( aLayoutConv.convertFromModel( aPropSet ) ) eLegendExpand = cssc::ChartLegendExpansion_CUSTOM; bManualLayout = !aLayoutConv.getAutoLayout(); } // set position and expansion properties aPropSet.setProperty( PROP_AnchorPosition, eLegendPos ); aPropSet.setProperty( PROP_Expansion, eLegendExpand ); if(eLegendPos == LegendPosition_CUSTOM && 1 == bTopRight && bManualLayout==false) aPropSet.setProperty( PROP_RelativePosition , makeAny(eRelPos)); } catch( Exception& ) { } } // ============================================================================ } // namespace chart } // namespace drawingml } // namespace oox