1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "drawingml/textparagraphpropertiescontext.hxx"
22 #include <com/sun/star/text/WritingMode2.hpp>
23 #include <com/sun/star/awt/FontDescriptor.hpp>
24 #include <com/sun/star/style/ParagraphAdjust.hpp>
26 #include <svx/unopage.hxx>
28 #include "drawingml/colorchoicecontext.hxx"
29 #include "drawingml/textcharacterpropertiescontext.hxx"
30 #include "oox/drawingml/fillproperties.hxx"
31 #include "oox/helper/attributelist.hxx"
32 #include "textspacingcontext.hxx"
33 #include "texttabstoplistcontext.hxx"
35 using namespace ::oox::core
;
36 using ::com::sun::star::awt::FontDescriptor
;
37 using namespace ::com::sun::star::uno
;
38 using namespace ::com::sun::star::xml::sax
;
39 using namespace ::com::sun::star::style
;
40 using namespace ::com::sun::star::text
;
42 namespace oox
{ namespace drawingml
{
44 // CT_TextParagraphProperties
45 TextParagraphPropertiesContext::TextParagraphPropertiesContext( ContextHandler2Helper
& rParent
,
46 const AttributeList
& rAttribs
,
47 TextParagraphProperties
& rTextParagraphProperties
)
48 : ContextHandler2( rParent
)
49 , mrTextParagraphProperties( rTextParagraphProperties
)
50 , mrBulletList( rTextParagraphProperties
.getBulletList() )
54 PropertyMap
& rPropertyMap( mrTextParagraphProperties
.getTextParagraphPropertyMap() );
57 if ( rAttribs
.hasAttribute( XML_algn
) )
59 mrTextParagraphProperties
.getParaAdjust() = GetParaAdjust( rAttribs
.getToken( XML_algn
, XML_l
) );
61 // TODO see to do the same with RubyAdjust
64 // sValue = rAttribs.getString( XML_defTabSz ).get(); SJ: we need to be able to set the default tab size for each text object,
65 // this is possible at the moment only for the whole document.
66 // sal_Int32 nDefTabSize = ( sValue.getLength() == 0 ? 0 : GetCoordinate( sValue ) );
69 // bool bEaLineBrk = rAttribs.getBool( XML_eaLnBrk, true );
70 if ( rAttribs
.hasAttribute( XML_latinLnBrk
) )
72 bool bLatinLineBrk
= rAttribs
.getBool( XML_latinLnBrk
, true );
73 rPropertyMap
.setProperty( PROP_ParaIsHyphenation
, bLatinLineBrk
);
75 // TODO see what to do with Asian hyphenation
77 // ST_TextFontAlignType
79 // sal_Int32 nFontAlign = rAttribs.getToken( XML_fontAlgn, XML_base );
81 if ( rAttribs
.hasAttribute( XML_hangingPunct
) )
83 bool bHangingPunct
= rAttribs
.getBool( XML_hangingPunct
, false );
84 rPropertyMap
.setProperty( PROP_ParaIsHangingPunctuation
, bHangingPunct
);
88 if ( rAttribs
.hasAttribute( XML_indent
) )
90 sValue
= rAttribs
.getString( XML_indent
).get();
91 mrTextParagraphProperties
.getFirstLineIndentation() = boost::optional
< sal_Int32
>( sValue
.isEmpty() ? 0 : GetCoordinate( sValue
) );
94 // ST_TextIndentLevelType
95 // -1 is an invalid value and denote the lack of level
96 sal_Int32 nLevel
= rAttribs
.getInteger( XML_lvl
, 0 );
97 if( nLevel
> 8 || nLevel
< 0 )
102 mrTextParagraphProperties
.setLevel( static_cast< sal_Int16
>( nLevel
) );
104 char name
[] = "Outline X";
105 name
[8] = static_cast<char>( '1' + nLevel
);
106 const OUString
sStyleNameValue( OUString::createFromAscii( name
) );
107 mrBulletList
.setStyleName( sStyleNameValue
);
111 if ( rAttribs
.hasAttribute( XML_marL
) )
113 sValue
= rAttribs
.getString( XML_marL
).get();
114 mrTextParagraphProperties
.getParaLeftMargin() = boost::optional
< sal_Int32
>( sValue
.isEmpty() ? 0 : GetCoordinate( sValue
) );
118 if ( rAttribs
.hasAttribute( XML_marR
) )
120 sValue
= rAttribs
.getString( XML_marR
).get();
121 sal_Int32 nMarR
= sValue
.isEmpty() ? 0 : GetCoordinate( sValue
) ;
122 rPropertyMap
.setProperty( PROP_ParaRightMargin
, nMarR
);
125 if ( rAttribs
.hasAttribute( XML_rtl
) )
127 bool bRtl
= rAttribs
.getBool( XML_rtl
, false );
128 rPropertyMap
.setProperty( PROP_WritingMode
, ( bRtl
? WritingMode2::RL_TB
: WritingMode2::LR_TB
));
132 TextParagraphPropertiesContext::~TextParagraphPropertiesContext()
134 PropertyMap
& rPropertyMap( mrTextParagraphProperties
.getTextParagraphPropertyMap() );
135 if ( maLineSpacing
.bHasValue
)
136 rPropertyMap
.setProperty( PROP_ParaLineSpacing
, maLineSpacing
.toLineSpacing());
138 rPropertyMap
.setProperty( PROP_ParaLineSpacing
, ::com::sun::star::style::LineSpacing( ::com::sun::star::style::LineSpacingMode::PROP
, 100 ));
140 ::std::list
< TabStop
>::size_type nTabCount
= maTabList
.size();
143 Sequence
< TabStop
> aSeq( nTabCount
);
144 TabStop
* aArray
= aSeq
.getArray();
145 OSL_ENSURE( aArray
!= NULL
, "sequence array is NULL" );
146 ::std::copy( maTabList
.begin(), maTabList
.end(), aArray
);
147 rPropertyMap
.setProperty( PROP_ParaTabStops
, aSeq
);
150 if ( mxBlipProps
.get() && mxBlipProps
->mxGraphic
.is() )
151 mrBulletList
.setGraphic( mxBlipProps
->mxGraphic
);
153 if( mrBulletList
.is() )
154 rPropertyMap
.setProperty( PROP_IsNumbering
, sal_True
);
155 sal_Int16 nLevel
= mrTextParagraphProperties
.getLevel();
156 rPropertyMap
.setProperty( PROP_NumberingLevel
, nLevel
);
157 rPropertyMap
.setProperty( PROP_NumberingIsNumber
, sal_True
);
159 if( mrTextParagraphProperties
.getParaAdjust() )
160 rPropertyMap
.setProperty( PROP_ParaAdjust
, mrTextParagraphProperties
.getParaAdjust().get());
163 ContextHandlerRef
TextParagraphPropertiesContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
165 Reference
< XFastContextHandler
> xRet
;
166 switch( aElementToken
)
168 case A_TOKEN( lnSpc
): // CT_TextSpacing
169 return new TextSpacingContext( *this, maLineSpacing
);
170 case A_TOKEN( spcBef
): // CT_TextSpacing
171 return new TextSpacingContext( *this, mrTextParagraphProperties
.getParaTopMargin() );
172 case A_TOKEN( spcAft
): // CT_TextSpacing
173 return new TextSpacingContext( *this, mrTextParagraphProperties
.getParaBottomMargin() );
174 // EG_TextBulletColor
175 case A_TOKEN( buClrTx
): // CT_TextBulletColorFollowText ???
176 mrBulletList
.mbBulletColorFollowText
<<= sal_True
;
178 case A_TOKEN( buClr
): // CT_Color
179 return new ColorContext( *this, *mrBulletList
.maBulletColorPtr
);
181 case A_TOKEN( buSzTx
): // CT_TextBulletSizeFollowText
182 mrBulletList
.setBulletSize(100);
184 case A_TOKEN( buSzPct
): // CT_TextBulletSizePercent
185 mrBulletList
.setBulletSize( static_cast<sal_Int16
>( GetPercent( rAttribs
.getString( XML_val
).get() ) / 1000 ) );
187 case A_TOKEN( buSzPts
): // CT_TextBulletSizePoint
188 mrBulletList
.setBulletSize(0);
189 mrBulletList
.setFontSize( static_cast<sal_Int16
>(GetTextSize( rAttribs
.getString( XML_val
).get() ) ) );
192 // EG_TextBulletTypeface
193 case A_TOKEN( buFontTx
): // CT_TextBulletTypefaceFollowText
194 mrBulletList
.mbBulletFontFollowText
<<= sal_True
;
196 case A_TOKEN( buFont
): // CT_TextFont
197 mrBulletList
.maBulletFont
.setAttributes( rAttribs
);
201 case A_TOKEN( buNone
): // CT_TextNoBullet
202 mrBulletList
.setNone();
204 case A_TOKEN( buAutoNum
): // CT_TextAutonumberBullet
207 sal_Int32 nType
= rAttribs
.getToken( XML_type
, 0 );
208 sal_Int32 nStartAt
= rAttribs
.getInteger( XML_startAt
, 1 );
209 if( nStartAt
> 32767 )
213 else if( nStartAt
< 1 )
217 mrBulletList
.setStartAt( nStartAt
);
218 mrBulletList
.setType( nType
);
220 catch(SAXException
& /* e */ )
222 OSL_TRACE("OOX: SAXException in XML_buAutoNum");
226 case A_TOKEN( buChar
): // CT_TextCharBullet
229 mrBulletList
.setBulletChar( rAttribs
.getString( XML_char
).get() );
230 mrBulletList
.setSuffixNone();
232 catch(SAXException
& /* e */)
234 OSL_TRACE("OOX: SAXException in XML_buChar");
237 case A_TOKEN( buBlip
): // CT_TextBlipBullet
239 mxBlipProps
.reset( new BlipFillProperties
);
240 return new BlipFillContext( *this, rAttribs
, *mxBlipProps
);
242 case A_TOKEN( tabLst
): // CT_TextTabStopList
243 return new TextTabStopListContext( *this, maTabList
);
244 case A_TOKEN( defRPr
): // CT_TextCharacterProperties
245 return new TextCharacterPropertiesContext( *this, rAttribs
, mrTextParagraphProperties
.getTextCharacterProperties() );
248 OptValue
< OUString
> oParaAdjust
= rAttribs
.getString( W_TOKEN(val
) );
249 if( oParaAdjust
.has() && !oParaAdjust
.get().isEmpty() )
251 const OUString
& sParaAdjust
= oParaAdjust
.get();
252 if( sParaAdjust
== "left" )
253 mrTextParagraphProperties
.setParaAdjust(ParagraphAdjust_LEFT
);
254 else if ( sParaAdjust
== "right" )
255 mrTextParagraphProperties
.setParaAdjust(ParagraphAdjust_RIGHT
);
256 else if ( sParaAdjust
== "center" )
257 mrTextParagraphProperties
.setParaAdjust(ParagraphAdjust_CENTER
);
258 else if ( sParaAdjust
== "both" )
259 mrTextParagraphProperties
.setParaAdjust(ParagraphAdjust_BLOCK
);
263 case W_TOKEN( spacing
):
266 if( !rAttribs
.getBool(W_TOKEN(beforeAutospacing
), false) )
268 OptValue
<sal_Int32
> oBefore
= rAttribs
.getInteger(W_TOKEN(before
));
271 TextSpacing
& rSpacing
= mrTextParagraphProperties
.getParaTopMargin();
272 rSpacing
.nUnit
= TextSpacing::POINTS
;
273 rSpacing
.nValue
= TWIPS_TO_MM(oBefore
.get());
274 rSpacing
.bHasValue
= true;
278 OptValue
<sal_Int32
> oBeforeLines
= rAttribs
.getInteger(W_TOKEN(beforeLines
));
279 if (oBeforeLines
.has())
281 TextSpacing
& rSpacing
= mrTextParagraphProperties
.getParaTopMargin();
282 rSpacing
.nUnit
= TextSpacing::PERCENT
;
283 rSpacing
.nValue
= oBeforeLines
.get() * MAX_PERCENT
/ 100;
284 rSpacing
.bHasValue
= true;
290 if( !rAttribs
.getBool(W_TOKEN(afterAutospacing
), false) )
292 OptValue
<sal_Int32
> oAfter
= rAttribs
.getInteger(W_TOKEN(after
));
295 TextSpacing
& rSpacing
= mrTextParagraphProperties
.getParaBottomMargin();
296 rSpacing
.nUnit
= TextSpacing::POINTS
;
297 rSpacing
.nValue
= TWIPS_TO_MM(oAfter
.get());
298 rSpacing
.bHasValue
= true;
302 OptValue
<sal_Int32
> oAfterLines
= rAttribs
.getInteger(W_TOKEN(afterLines
));
303 if (oAfterLines
.has())
305 TextSpacing
& rSpacing
= mrTextParagraphProperties
.getParaBottomMargin();
306 rSpacing
.nUnit
= TextSpacing::PERCENT
;
307 rSpacing
.nValue
= oAfterLines
.get() * MAX_PERCENT
/ 100;
308 rSpacing
.bHasValue
= true;
314 OptValue
<OUString
> oLineRule
= rAttribs
.getString(W_TOKEN(lineRule
));
315 OptValue
<sal_Int32
> oLineSpacing
= rAttribs
.getInteger(W_TOKEN(line
));
316 if (oLineSpacing
.has())
318 if( !oLineRule
.has() || oLineRule
.get() == "auto" )
320 maLineSpacing
.nUnit
= TextSpacing::PERCENT
;
321 maLineSpacing
.nValue
= oLineSpacing
.get() * MAX_PERCENT
/ 240;
325 maLineSpacing
.nUnit
= TextSpacing::POINTS
;
326 maLineSpacing
.nValue
= TWIPS_TO_MM(oLineSpacing
.get());
328 maLineSpacing
.bHasValue
= true;
333 SAL_WARN("oox", "TextParagraphPropertiesContext::onCreateContext: unhandled element: " << getBaseToken(aElementToken
));
340 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */