1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "oox/drawingml/chart/titleconverter.hxx" 29 30 #include <com/sun/star/chart/ChartLegendExpansion.hpp> 31 #include <com/sun/star/chart2/LegendPosition.hpp> 32 #include <com/sun/star/chart2/XDiagram.hpp> 33 #include <com/sun/star/chart2/XFormattedString.hpp> 34 #include <com/sun/star/chart2/XLegend.hpp> 35 #include <com/sun/star/chart2/XTitle.hpp> 36 #include <com/sun/star/chart2/XTitled.hpp> 37 #include "oox/drawingml/textbody.hxx" 38 #include "oox/drawingml/textparagraph.hxx" 39 #include "oox/drawingml/chart/datasourceconverter.hxx" 40 #include "oox/drawingml/chart/titlemodel.hxx" 41 #include "oox/helper/containerhelper.hxx" 42 43 namespace oox { 44 namespace drawingml { 45 namespace chart { 46 47 // ============================================================================ 48 49 using namespace ::com::sun::star::awt; 50 using namespace ::com::sun::star::chart2; 51 using namespace ::com::sun::star::chart2::data; 52 using namespace ::com::sun::star::uno; 53 54 using ::oox::core::XmlFilterBase; 55 using ::rtl::OUString; 56 57 // ============================================================================ 58 59 TextConverter::TextConverter( const ConverterRoot& rParent, TextModel& rModel ) : 60 ConverterBase< TextModel >( rParent, rModel ) 61 { 62 } 63 64 TextConverter::~TextConverter() 65 { 66 } 67 68 Reference< XDataSequence > TextConverter::createDataSequence( const OUString& rRole ) 69 { 70 Reference< XDataSequence > xDataSeq; 71 if( mrModel.mxDataSeq.is() ) 72 { 73 DataSequenceConverter aDataSeqConv( *this, *mrModel.mxDataSeq ); 74 xDataSeq = aDataSeqConv.createDataSequence( rRole ); 75 } 76 return xDataSeq; 77 } 78 79 Sequence< Reference< XFormattedString > > TextConverter::createStringSequence( 80 const OUString& rDefaultText, const ModelRef< TextBody >& rxTextProp, ObjectType eObjType ) 81 { 82 OSL_ENSURE( !mrModel.mxDataSeq || !mrModel.mxTextBody, "TextConverter::createStringSequence - linked string and rich text found" ); 83 ::std::vector< Reference< XFormattedString > > aStringVec; 84 if( mrModel.mxTextBody.is() ) 85 { 86 // rich-formatted text objects can be created, but currently Chart2 is not able to show them 87 const TextParagraphVector& rTextParas = mrModel.mxTextBody->getParagraphs(); 88 for( TextParagraphVector::const_iterator aPIt = rTextParas.begin(), aPEnd = rTextParas.end(); aPIt != aPEnd; ++aPIt ) 89 { 90 const TextParagraph& rTextPara = **aPIt; 91 const TextCharacterProperties& rParaProps = rTextPara.getProperties().getTextCharacterProperties(); 92 for( TextRunVector::const_iterator aRIt = rTextPara.getRuns().begin(), aREnd = rTextPara.getRuns().end(); aRIt != aREnd; ++aRIt ) 93 { 94 const TextRun& rTextRun = **aRIt; 95 bool bAddNewLine = (aRIt + 1 == aREnd) && (aPIt + 1 != aPEnd); 96 Reference< XFormattedString > xFmtStr = appendFormattedString( aStringVec, rTextRun.getText(), bAddNewLine ); 97 PropertySet aPropSet( xFmtStr ); 98 TextCharacterProperties aRunProps( rParaProps ); 99 aRunProps.assignUsed( rTextRun.getTextCharacterProperties() ); 100 getFormatter().convertTextFormatting( aPropSet, aRunProps, eObjType ); 101 } 102 } 103 } 104 else 105 { 106 OUString aString; 107 // try to create string from linked data 108 if( mrModel.mxDataSeq.is() && !mrModel.mxDataSeq->maData.empty() ) 109 mrModel.mxDataSeq->maData.begin()->second >>= aString; 110 // no linked string -> fall back to default string 111 if( aString.getLength() == 0 ) 112 aString = rDefaultText; 113 114 // create formatted string object 115 if( aString.getLength() > 0 ) 116 { 117 Reference< XFormattedString > xFmtStr = appendFormattedString( aStringVec, aString, false ); 118 PropertySet aPropSet( xFmtStr ); 119 getFormatter().convertTextFormatting( aPropSet, rxTextProp, eObjType ); 120 } 121 } 122 123 return ContainerHelper::vectorToSequence( aStringVec ); 124 } 125 126 Reference< XFormattedString > TextConverter::appendFormattedString( 127 ::std::vector< Reference< XFormattedString > >& orStringVec, const OUString& rString, bool bAddNewLine ) const 128 { 129 Reference< XFormattedString > xFmtStr; 130 try 131 { 132 xFmtStr.set( ConverterRoot::createInstance( CREATE_OUSTRING( "com.sun.star.chart2.FormattedString" ) ), UNO_QUERY_THROW ); 133 xFmtStr->setString( bAddNewLine ? (rString + OUString( sal_Unicode( '\n' ) )) : rString ); 134 orStringVec.push_back( xFmtStr ); 135 } 136 catch( Exception& ) 137 { 138 } 139 return xFmtStr; 140 } 141 142 // ============================================================================ 143 144 TitleConverter::TitleConverter( const ConverterRoot& rParent, TitleModel& rModel ) : 145 ConverterBase< TitleModel >( rParent, rModel ) 146 { 147 } 148 149 TitleConverter::~TitleConverter() 150 { 151 } 152 153 void TitleConverter::convertFromModel( const Reference< XTitled >& rxTitled, const OUString& rAutoTitle, ObjectType eObjType, sal_Int32 nMainIdx, sal_Int32 nSubIdx ) 154 { 155 if( rxTitled.is() ) 156 { 157 // create the formatted strings 158 TextModel& rText = mrModel.mxText.getOrCreate(); 159 TextConverter aTextConv( *this, rText ); 160 Sequence< Reference< XFormattedString > > aStringSeq = aTextConv.createStringSequence( rAutoTitle, mrModel.mxTextProp, eObjType ); 161 if( aStringSeq.hasElements() ) try 162 { 163 // create the title object and set the string data 164 Reference< XTitle > xTitle( createInstance( CREATE_OUSTRING( "com.sun.star.chart2.Title" ) ), UNO_QUERY_THROW ); 165 xTitle->setText( aStringSeq ); 166 rxTitled->setTitleObject( xTitle ); 167 168 // frame formatting (text formatting already done in TextConverter::createStringSequence()) 169 PropertySet aPropSet( xTitle ); 170 getFormatter().convertFrameFormatting( aPropSet, mrModel.mxShapeProp, eObjType ); 171 172 // frame rotation 173 OSL_ENSURE( !mrModel.mxTextProp || !rText.mxTextBody, "TitleConverter::convertFromModel - multiple text properties" ); 174 ModelRef< TextBody > xTextProp = mrModel.mxTextProp.is() ? mrModel.mxTextProp : rText.mxTextBody; 175 getFormatter().convertTextRotation( aPropSet, xTextProp, true ); 176 177 // register the title and layout data for conversion of position 178 registerTitleLayout( xTitle, mrModel.mxLayout, eObjType, nMainIdx, nSubIdx ); 179 } 180 catch( Exception& ) 181 { 182 } 183 } 184 } 185 186 // ============================================================================ 187 188 LegendConverter::LegendConverter( const ConverterRoot& rParent, LegendModel& rModel ) : 189 ConverterBase< LegendModel >( rParent, rModel ) 190 { 191 } 192 193 LegendConverter::~LegendConverter() 194 { 195 } 196 197 void LegendConverter::convertFromModel( const Reference< XDiagram >& rxDiagram ) 198 { 199 if( rxDiagram.is() ) try 200 { 201 namespace cssc = ::com::sun::star::chart; 202 namespace cssc2 = ::com::sun::star::chart2; 203 204 // create the legend 205 Reference< XLegend > xLegend( createInstance( CREATE_OUSTRING( "com.sun.star.chart2.Legend" ) ), UNO_QUERY_THROW ); 206 rxDiagram->setLegend( xLegend ); 207 PropertySet aPropSet( xLegend ); 208 aPropSet.setProperty( PROP_Show, true ); 209 210 // legend formatting 211 getFormatter().convertFormatting( aPropSet, mrModel.mxShapeProp, mrModel.mxTextProp, OBJECTTYPE_LEGEND ); 212 213 // predefined legend position and expansion 214 cssc2::LegendPosition eLegendPos = cssc2::LegendPosition_CUSTOM; 215 cssc::ChartLegendExpansion eLegendExpand = cssc::ChartLegendExpansion_CUSTOM; 216 switch( mrModel.mnPosition ) 217 { 218 case XML_l: 219 eLegendPos = cssc2::LegendPosition_LINE_START; 220 eLegendExpand = cssc::ChartLegendExpansion_HIGH; 221 break; 222 case XML_r: 223 case XML_tr: // top-right not supported 224 eLegendPos = cssc2::LegendPosition_LINE_END; 225 eLegendExpand = cssc::ChartLegendExpansion_HIGH; 226 break; 227 case XML_t: 228 eLegendPos = cssc2::LegendPosition_PAGE_START; 229 eLegendExpand = cssc::ChartLegendExpansion_WIDE; 230 break; 231 case XML_b: 232 eLegendPos = cssc2::LegendPosition_PAGE_END; 233 eLegendExpand = cssc::ChartLegendExpansion_WIDE; 234 break; 235 } 236 237 // manual positioning and size 238 if( mrModel.mxLayout.get() ) 239 { 240 LayoutConverter aLayoutConv( *this, *mrModel.mxLayout ); 241 // manual size needs ChartLegendExpansion_CUSTOM 242 if( aLayoutConv.convertFromModel( aPropSet ) ) 243 eLegendExpand = cssc::ChartLegendExpansion_CUSTOM; 244 } 245 246 // set position and expansion properties 247 aPropSet.setProperty( PROP_AnchorPosition, eLegendPos ); 248 aPropSet.setProperty( PROP_Expansion, eLegendExpand ); 249 } 250 catch( Exception& ) 251 { 252 } 253 } 254 255 // ============================================================================ 256 257 } // namespace chart 258 } // namespace drawingml 259 } // namespace oox 260