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 .
19 #include "vbaparagraphformat.hxx"
21 #include <vbahelper/vbahelper.hxx>
22 #include <basic/sberrors.hxx>
23 #include <com/sun/star/style/LineSpacingMode.hpp>
24 #include <ooo/vba/word/WdLineSpacing.hpp>
25 #include <ooo/vba/word/WdParagraphAlignment.hpp>
26 #include <ooo/vba/word/WdOutlineLevel.hpp>
27 #include <com/sun/star/style/ParagraphAdjust.hpp>
28 #include <com/sun/star/style/BreakType.hpp>
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include "vbatabstops.hxx"
31 #include <o3tl/string_view.hxx>
33 using namespace ::ooo::vba
;
34 using namespace ::com::sun::star
;
36 const sal_Int16 CHARACTER_INDENT_FACTOR
= 12;
37 const sal_Int16 PERCENT100
= 100;
38 const sal_Int16 PERCENT150
= 150;
39 const sal_Int16 PERCENT200
= 200;
41 SwVbaParagraphFormat::SwVbaParagraphFormat( const uno::Reference
< ooo::vba::XHelperInterface
>& rParent
, const uno::Reference
< uno::XComponentContext
>& rContext
, uno::Reference
< beans::XPropertySet
> xParaProps
) : SwVbaParagraphFormat_BASE( rParent
, rContext
), mxParaProps(std::move( xParaProps
))
45 SwVbaParagraphFormat::~SwVbaParagraphFormat()
49 sal_Int32 SAL_CALL
SwVbaParagraphFormat::getAlignment()
51 style::ParagraphAdjust aParaAdjust
= style::ParagraphAdjust_LEFT
;
52 mxParaProps
->getPropertyValue("ParaAdjust") >>= aParaAdjust
;
53 return getMSWordAlignment( aParaAdjust
);
56 void SAL_CALL
SwVbaParagraphFormat::setAlignment( sal_Int32 _alignment
)
58 style::ParagraphAdjust aParaAdjust
= getOOoAlignment( _alignment
);
59 mxParaProps
->setPropertyValue("ParaAdjust", uno::Any( aParaAdjust
) );
62 float SAL_CALL
SwVbaParagraphFormat::getFirstLineIndent()
65 mxParaProps
->getPropertyValue("ParaFirstLineIndent") >>= indent
;
66 return static_cast<float>( Millimeter::getInPoints( indent
) );
69 void SAL_CALL
SwVbaParagraphFormat::setFirstLineIndent( float _firstlineindent
)
71 sal_Int32 indent
= Millimeter::getInHundredthsOfOneMillimeter( _firstlineindent
);
72 mxParaProps
->setPropertyValue("ParaFirstLineIndent", uno::Any( indent
) );
75 uno::Any SAL_CALL
SwVbaParagraphFormat::getKeepTogether()
78 mxParaProps
->getPropertyValue("ParaKeepTogether") >>= bKeep
;
79 return uno::Any ( bKeep
);
82 void SAL_CALL
SwVbaParagraphFormat::setKeepTogether( const uno::Any
& _keeptogether
)
85 if( _keeptogether
>>= bKeep
)
87 mxParaProps
->setPropertyValue("ParaKeepTogether", uno::Any( bKeep
) );
91 DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER
);
95 uno::Any SAL_CALL
SwVbaParagraphFormat::getKeepWithNext()
98 mxParaProps
->getPropertyValue("ParaSplit") >>= bKeep
;
99 return uno::Any ( bKeep
);
102 void SAL_CALL
SwVbaParagraphFormat::setKeepWithNext( const uno::Any
& _keepwithnext
)
105 if( _keepwithnext
>>= bKeep
)
107 mxParaProps
->setPropertyValue("ParaSplit", uno::Any( bKeep
) );
111 DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER
);
115 uno::Any SAL_CALL
SwVbaParagraphFormat::getHyphenation()
118 mxParaProps
->getPropertyValue("ParaIsHyphenation") >>= bHypn
;
119 return uno::Any ( bHypn
);
122 void SAL_CALL
SwVbaParagraphFormat::setHyphenation( const uno::Any
& _hyphenation
)
125 if( _hyphenation
>>= bHypn
)
127 mxParaProps
->setPropertyValue("ParaIsHyphenation", uno::Any( bHypn
) );
131 DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER
);
135 float SAL_CALL
SwVbaParagraphFormat::getLineSpacing()
137 style::LineSpacing aLineSpacing
;
138 mxParaProps
->getPropertyValue("ParaLineSpacing") >>= aLineSpacing
;
139 return getMSWordLineSpacing( aLineSpacing
);
142 void SAL_CALL
SwVbaParagraphFormat::setLineSpacing( float _linespacing
)
144 style::LineSpacing aLineSpacing
;
145 mxParaProps
->getPropertyValue("ParaLineSpacing") >>= aLineSpacing
;
146 aLineSpacing
= getOOoLineSpacing( _linespacing
, aLineSpacing
.Mode
);
147 mxParaProps
->setPropertyValue("ParaLineSpacing", uno::Any( aLineSpacing
) );
150 sal_Int32 SAL_CALL
SwVbaParagraphFormat::getLineSpacingRule()
152 style::LineSpacing aLineSpacing
;
153 mxParaProps
->getPropertyValue("ParaLineSpacing") >>= aLineSpacing
;
154 return getMSWordLineSpacingRule( aLineSpacing
);
157 void SAL_CALL
SwVbaParagraphFormat::setLineSpacingRule( sal_Int32 _linespacingrule
)
159 style::LineSpacing aLineSpacing
= getOOoLineSpacingFromRule( _linespacingrule
);
160 mxParaProps
->setPropertyValue("ParaLineSpacing", uno::Any( aLineSpacing
) );
163 uno::Any SAL_CALL
SwVbaParagraphFormat::getNoLineNumber()
165 bool noLineNum
= false;
166 mxParaProps
->getPropertyValue("ParaLineNumberCount") >>= noLineNum
;
167 return uno::Any ( noLineNum
);
170 void SAL_CALL
SwVbaParagraphFormat::setNoLineNumber( const uno::Any
& _nolinenumber
)
172 bool noLineNum
= false;
173 if( _nolinenumber
>>= noLineNum
)
175 mxParaProps
->setPropertyValue("ParaLineNumberCount", uno::Any( noLineNum
) );
179 DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER
);
183 sal_Int32 SAL_CALL
SwVbaParagraphFormat::getOutlineLevel()
185 sal_Int32 nLevel
= word::WdOutlineLevel::wdOutlineLevelBodyText
;
187 static const OUStringLiteral HEADING
= u
"Heading";
188 mxParaProps
->getPropertyValue("ParaStyleName") >>= aHeading
;
189 if( aHeading
.startsWith( HEADING
) )
191 // get the sub string after "Heading"
192 nLevel
= o3tl::toInt32(aHeading
.subView( HEADING
.getLength() ));
197 void SAL_CALL
SwVbaParagraphFormat::setOutlineLevel( sal_Int32 _outlinelevel
)
199 if( _outlinelevel
!= getOutlineLevel() )
201 // TODO: in my test in msword, there is no effect for this function.
205 uno::Any SAL_CALL
SwVbaParagraphFormat::getPageBreakBefore()
207 style::BreakType aBreakType
;
208 mxParaProps
->getPropertyValue("BreakType") >>= aBreakType
;
209 bool bBreakBefore
= ( aBreakType
== style::BreakType_PAGE_BEFORE
|| aBreakType
== style::BreakType_PAGE_BOTH
);
210 return uno::Any( bBreakBefore
);
213 void SAL_CALL
SwVbaParagraphFormat::setPageBreakBefore( const uno::Any
& _breakbefore
)
215 bool bBreakBefore
= false;
216 if( _breakbefore
>>= bBreakBefore
)
218 style::BreakType aBreakType
;
219 mxParaProps
->getPropertyValue("BreakType") >>= aBreakType
;
222 if( aBreakType
== style::BreakType_NONE
)
223 aBreakType
= style::BreakType_PAGE_BEFORE
;
224 else if ( aBreakType
== style::BreakType_PAGE_AFTER
)
225 aBreakType
= style::BreakType_PAGE_BOTH
;
229 if( aBreakType
== style::BreakType_PAGE_BOTH
)
230 aBreakType
= style::BreakType_PAGE_AFTER
;
231 else if ( aBreakType
== style::BreakType_PAGE_BEFORE
)
232 aBreakType
= style::BreakType_PAGE_AFTER
;
234 mxParaProps
->setPropertyValue("BreakType", uno::Any( aBreakType
) );
238 DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER
);
242 float SAL_CALL
SwVbaParagraphFormat::getSpaceBefore()
244 sal_Int32 nSpace
= 0;
245 mxParaProps
->getPropertyValue("ParaTopMargin") >>= nSpace
;
246 return static_cast<float>( Millimeter::getInPoints( nSpace
) );
249 void SAL_CALL
SwVbaParagraphFormat::setSpaceBefore( float _space
)
251 sal_Int32 nSpace
= Millimeter::getInHundredthsOfOneMillimeter( _space
);
252 mxParaProps
->setPropertyValue("ParaTopMargin", uno::Any( nSpace
) );
255 float SAL_CALL
SwVbaParagraphFormat::getSpaceAfter()
257 sal_Int32 nSpace
= 0;
258 mxParaProps
->getPropertyValue("ParaBottomMargin") >>= nSpace
;
259 return static_cast<float>( Millimeter::getInPoints( nSpace
) );
262 void SAL_CALL
SwVbaParagraphFormat::setSpaceAfter( float _space
)
264 sal_Int32 nSpace
= Millimeter::getInHundredthsOfOneMillimeter( _space
);
265 mxParaProps
->setPropertyValue("ParaBottomMargin", uno::Any( nSpace
) );
268 float SAL_CALL
SwVbaParagraphFormat::getLeftIndent()
270 sal_Int32 nIndent
= 0;
271 mxParaProps
->getPropertyValue("ParaLeftMargin") >>= nIndent
;
272 return static_cast<float>( Millimeter::getInPoints( nIndent
) );
275 void SAL_CALL
SwVbaParagraphFormat::setLeftIndent( float _leftindent
)
277 sal_Int32 nIndent
= Millimeter::getInHundredthsOfOneMillimeter( _leftindent
);
278 mxParaProps
->setPropertyValue("ParaLeftMargin", uno::Any( nIndent
) );
281 float SAL_CALL
SwVbaParagraphFormat::getRightIndent()
283 sal_Int32 nIndent
= 0;
284 mxParaProps
->getPropertyValue("ParaRightMargin") >>= nIndent
;
285 return static_cast<float>( Millimeter::getInPoints( nIndent
) );
288 void SAL_CALL
SwVbaParagraphFormat::setRightIndent( float _rightindent
)
290 sal_Int32 nIndent
= Millimeter::getInHundredthsOfOneMillimeter( _rightindent
);
291 mxParaProps
->setPropertyValue("ParaRightMargin", uno::Any( nIndent
) );
294 uno::Any SAL_CALL
SwVbaParagraphFormat::getTabStops()
296 return uno::Any( uno::Reference
< word::XTabStops
>( new SwVbaTabStops( this, mxContext
, mxParaProps
) ) );
299 void SAL_CALL
SwVbaParagraphFormat::setTabStops( const uno::Any
& /*_tabstops*/ )
301 throw uno::RuntimeException("Not implemented" );
304 uno::Any SAL_CALL
SwVbaParagraphFormat::getWidowControl()
307 mxParaProps
->getPropertyValue("ParaWidows") >>= nWidow
;
308 sal_Int8 nOrphan
= 0;
309 mxParaProps
->getPropertyValue("ParaOrphans") >>= nOrphan
;
310 // if the amount of single lines on one page > 1 and the same of start and end of the paragraph,
312 bool bWidow
= ( nWidow
> 1 && nOrphan
== nWidow
);
313 return uno::Any( bWidow
);
316 void SAL_CALL
SwVbaParagraphFormat::setWidowControl( const uno::Any
& _widowcontrol
)
318 // if we get true, the part of the paragraph on one page has to be
319 // at least two lines
321 if( _widowcontrol
>>= bWidow
)
323 sal_Int8 nControl
= bWidow
? 2:1;
324 mxParaProps
->setPropertyValue("ParaWidows", uno::Any( nControl
) );
325 mxParaProps
->setPropertyValue("ParaOrphans", uno::Any( nControl
) );
329 DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER
);
333 style::LineSpacing
SwVbaParagraphFormat::getOOoLineSpacing( float _lineSpace
, sal_Int16 mode
)
335 style::LineSpacing aLineSpacing
;
336 if( mode
!= style::LineSpacingMode::MINIMUM
&& mode
!= style::LineSpacingMode::FIX
)
338 // special behaviour of word: if the space is set to these values, the rule and
339 // the height are changed accordingly
340 if( _lineSpace
== CHARACTER_INDENT_FACTOR
)
342 aLineSpacing
.Mode
= style::LineSpacingMode::PROP
;
343 aLineSpacing
.Height
= PERCENT100
;
345 else if( _lineSpace
== CHARACTER_INDENT_FACTOR
* 1.5 ) // no rounding issues, == 18
347 aLineSpacing
.Mode
= style::LineSpacingMode::PROP
;
348 aLineSpacing
.Height
= PERCENT150
;
350 else if( _lineSpace
== CHARACTER_INDENT_FACTOR
* 2 )
352 aLineSpacing
.Mode
= style::LineSpacingMode::PROP
;
353 aLineSpacing
.Height
= PERCENT200
;
357 aLineSpacing
.Mode
= style::LineSpacingMode::FIX
;
358 aLineSpacing
.Height
= static_cast<sal_Int16
>( Millimeter::getInHundredthsOfOneMillimeter( _lineSpace
) );
363 aLineSpacing
.Mode
= mode
;
364 aLineSpacing
.Height
= static_cast<sal_Int16
>( Millimeter::getInHundredthsOfOneMillimeter( _lineSpace
) );
369 style::LineSpacing
SwVbaParagraphFormat::getOOoLineSpacingFromRule( sal_Int32 _linespacingrule
)
371 style::LineSpacing aLineSpacing
;
372 switch( _linespacingrule
)
374 case word::WdLineSpacing::wdLineSpace1pt5
:
376 aLineSpacing
.Mode
= style::LineSpacingMode::PROP
;
377 aLineSpacing
.Height
= PERCENT150
;
380 case word::WdLineSpacing::wdLineSpaceAtLeast
:
382 aLineSpacing
.Mode
= style::LineSpacingMode::MINIMUM
;
383 aLineSpacing
.Height
= getCharHeight();
386 case word::WdLineSpacing::wdLineSpaceDouble
:
388 aLineSpacing
.Mode
= style::LineSpacingMode::PROP
;
389 aLineSpacing
.Height
= getCharHeight();
392 case word::WdLineSpacing::wdLineSpaceExactly
:
393 case word::WdLineSpacing::wdLineSpaceMultiple
:
395 aLineSpacing
.Mode
= style::LineSpacingMode::FIX
;
396 aLineSpacing
.Height
= getCharHeight();
399 case word::WdLineSpacing::wdLineSpaceSingle
:
401 aLineSpacing
.Mode
= style::LineSpacingMode::PROP
;
402 aLineSpacing
.Height
= PERCENT100
;
407 DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER
);
414 float SwVbaParagraphFormat::getMSWordLineSpacing( style::LineSpacing
const & rLineSpacing
)
416 float wdLineSpacing
= 0;
417 if( rLineSpacing
.Mode
!= style::LineSpacingMode::PROP
)
419 wdLineSpacing
= static_cast<float>( Millimeter::getInPoints( rLineSpacing
.Height
) );
423 wdLineSpacing
= static_cast<float>( CHARACTER_INDENT_FACTOR
* rLineSpacing
.Height
) / PERCENT100
;
425 return wdLineSpacing
;
428 sal_Int32
SwVbaParagraphFormat::getMSWordLineSpacingRule( style::LineSpacing
const & rLineSpacing
)
430 sal_Int32 wdLineSpacing
= word::WdLineSpacing::wdLineSpaceSingle
;
431 switch( rLineSpacing
.Mode
)
433 case style::LineSpacingMode::PROP
:
435 switch( rLineSpacing
.Height
)
439 wdLineSpacing
= word::WdLineSpacing::wdLineSpaceSingle
;
444 wdLineSpacing
= word::WdLineSpacing::wdLineSpace1pt5
;
449 wdLineSpacing
= word::WdLineSpacing::wdLineSpaceDouble
;
454 wdLineSpacing
= word::WdLineSpacing::wdLineSpaceMultiple
;
459 case style::LineSpacingMode::MINIMUM
:
461 wdLineSpacing
= word::WdLineSpacing::wdLineSpaceAtLeast
;
464 case style::LineSpacingMode::FIX
:
465 case style::LineSpacingMode::LEADING
:
467 wdLineSpacing
= word::WdLineSpacing::wdLineSpaceExactly
;
472 DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER
);
475 return wdLineSpacing
;
478 sal_Int16
SwVbaParagraphFormat::getCharHeight()
480 float fCharHeight
= 0.0;
481 mxParaProps
->getPropertyValue("CharHeight") >>= fCharHeight
;
482 return static_cast<sal_Int16
>( Millimeter::getInHundredthsOfOneMillimeter( fCharHeight
) );
485 style::ParagraphAdjust
SwVbaParagraphFormat::getOOoAlignment( sal_Int32 _alignment
)
487 style::ParagraphAdjust nParaAjust
= style::ParagraphAdjust_LEFT
;
490 case word::WdParagraphAlignment::wdAlignParagraphCenter
:
492 nParaAjust
= style::ParagraphAdjust_CENTER
;
495 case word::WdParagraphAlignment::wdAlignParagraphJustify
:
497 nParaAjust
= style::ParagraphAdjust_BLOCK
;
500 case word::WdParagraphAlignment::wdAlignParagraphLeft
:
502 nParaAjust
= style::ParagraphAdjust_LEFT
;
505 case word::WdParagraphAlignment::wdAlignParagraphRight
:
507 nParaAjust
= style::ParagraphAdjust_RIGHT
;
512 DebugHelper::runtimeexception( ERRCODE_BASIC_BAD_PARAMETER
);
518 sal_Int32
SwVbaParagraphFormat::getMSWordAlignment( style::ParagraphAdjust _alignment
)
520 sal_Int32 wdAlignment
= word::WdParagraphAlignment::wdAlignParagraphLeft
;
523 case style::ParagraphAdjust_CENTER
:
525 wdAlignment
= word::WdParagraphAlignment::wdAlignParagraphCenter
;
528 case style::ParagraphAdjust_LEFT
:
530 wdAlignment
= word::WdParagraphAlignment::wdAlignParagraphLeft
;
533 case style::ParagraphAdjust_BLOCK
:
535 wdAlignment
= word::WdParagraphAlignment::wdAlignParagraphJustify
;
538 case style::ParagraphAdjust_RIGHT
:
540 wdAlignment
= word::WdParagraphAlignment::wdAlignParagraphRight
;
545 DebugHelper::basicexception( ERRCODE_BASIC_BAD_PARAMETER
, {} );
552 SwVbaParagraphFormat::getServiceImplName()
554 return "SwVbaParagraphFormat";
557 uno::Sequence
< OUString
>
558 SwVbaParagraphFormat::getServiceNames()
560 static uno::Sequence
< OUString
> const aServiceNames
562 "ooo.vba.word.ParagraphFormat"
564 return aServiceNames
;
567 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */