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 "vbarows.hxx"
21 #include <com/sun/star/beans/XPropertySet.hpp>
22 #include <com/sun/star/text/HoriOrientation.hpp>
23 #include <com/sun/star/table/XCellRange.hpp>
24 #include <ooo/vba/word/WdRowAlignment.hpp>
25 #include <ooo/vba/word/WdConstants.hpp>
26 #include <ooo/vba/word/WdRulerStyle.hpp>
27 #include <basic/sberrors.hxx>
29 #include "vbacolumns.hxx"
30 #include "vbatablehelper.hxx"
31 #include "wordvbahelper.hxx"
32 #include <unotxdoc.hxx>
34 using namespace ::ooo::vba
;
35 using namespace ::ooo::vba::word
;
36 using namespace ::com::sun::star
;
40 class RowsEnumWrapper
: public EnumerationHelper_BASE
42 unotools::WeakReference
< SwVbaRows
> mxParent
;
43 uno::Reference
< uno::XComponentContext
> mxContext
;
44 uno::Reference
< text::XTextTable
> mxTextTable
;
45 uno::Reference
< container::XIndexAccess
> mxIndexAccess
;
49 RowsEnumWrapper( const rtl::Reference
< SwVbaRows
>& xParent
, uno::Reference
< uno::XComponentContext
> xContext
, uno::Reference
< text::XTextTable
> xTextTable
) : mxParent( xParent
), mxContext(std::move( xContext
)), mxTextTable(std::move( xTextTable
)), m_nIndex( 0 )
51 mxIndexAccess
= mxTextTable
->getRows();
53 virtual sal_Bool SAL_CALL
hasMoreElements( ) override
55 return ( m_nIndex
< mxIndexAccess
->getCount() );
58 virtual uno::Any SAL_CALL
nextElement( ) override
60 if( m_nIndex
< mxIndexAccess
->getCount() )
62 return uno::Any( uno::Reference
< word::XRow
> ( new SwVbaRow( mxParent
.get(), mxContext
, mxTextTable
, m_nIndex
++ ) ) );
64 throw container::NoSuchElementException();
70 SwVbaRows::SwVbaRows( const uno::Reference
< XHelperInterface
>& xParent
, const uno::Reference
< uno::XComponentContext
> & xContext
, uno::Reference
< text::XTextTable
> xTextTable
, const uno::Reference
< table::XTableRows
>& xTableRows
) : SwVbaRows_BASE( xParent
, xContext
, uno::Reference
< container::XIndexAccess
>( xTableRows
, uno::UNO_QUERY_THROW
) ), mxTextTable(std::move( xTextTable
)), mxTableRows( xTableRows
)
73 mnEndRowIndex
= m_xIndexAccess
->getCount() - 1;
76 SwVbaRows::SwVbaRows( const uno::Reference
< XHelperInterface
>& xParent
, const uno::Reference
< uno::XComponentContext
> & xContext
, uno::Reference
< text::XTextTable
> xTextTable
, const uno::Reference
< table::XTableRows
>& xTableRows
, sal_Int32 nStarIndex
, sal_Int32 nEndIndex
) : SwVbaRows_BASE( xParent
, xContext
, uno::Reference
< container::XIndexAccess
>( xTableRows
, uno::UNO_QUERY_THROW
) ), mxTextTable(std::move( xTextTable
)), mxTableRows( xTableRows
), mnStartRowIndex( nStarIndex
), mnEndRowIndex( nEndIndex
)
78 if( mnEndRowIndex
< mnStartRowIndex
)
79 throw uno::RuntimeException();
83 * get the alignment of the rows: SO format com.sun.star.text.HoriOrientation
84 * is mapped to WdRowAlignment in Word
85 * @return the alignment
87 ::sal_Int32 SAL_CALL
SwVbaRows::getAlignment()
89 sal_Int16 nAlignment
= text::HoriOrientation::LEFT
;
90 uno::Reference
< beans::XPropertySet
> xTableProps( mxTextTable
, uno::UNO_QUERY_THROW
);
91 xTableProps
->getPropertyValue(u
"HoriOrient"_ustr
) >>= nAlignment
;
95 case text::HoriOrientation::CENTER
:
97 nRet
= word::WdRowAlignment::wdAlignRowCenter
;
100 case text::HoriOrientation::RIGHT
:
102 nRet
= word::WdRowAlignment::wdAlignRowRight
;
107 nRet
= word::WdRowAlignment::wdAlignRowLeft
;
113 void SAL_CALL
SwVbaRows::setAlignment( ::sal_Int32 _alignment
)
115 sal_Int16 nAlignment
= text::HoriOrientation::LEFT
;
118 case word::WdRowAlignment::wdAlignRowCenter
:
120 nAlignment
= text::HoriOrientation::CENTER
;
123 case word::WdRowAlignment::wdAlignRowRight
:
125 nAlignment
= text::HoriOrientation::RIGHT
;
130 nAlignment
= text::HoriOrientation::LEFT
;
133 uno::Reference
< beans::XPropertySet
> xTableProps( mxTextTable
, uno::UNO_QUERY_THROW
);
134 xTableProps
->setPropertyValue(u
"HoriOrient"_ustr
, uno::Any( nAlignment
) );
137 uno::Any SAL_CALL
SwVbaRows::getAllowBreakAcrossPages()
139 bool bAllowBreak
= false;
140 uno::Reference
< container::XIndexAccess
> xRowsAccess( mxTableRows
, uno::UNO_QUERY_THROW
);
141 for( sal_Int32 index
= mnStartRowIndex
; index
<= mnEndRowIndex
; ++index
)
143 uno::Reference
< beans::XPropertySet
> xRowProps( xRowsAccess
->getByIndex( index
), uno::UNO_QUERY_THROW
);
145 xRowProps
->getPropertyValue(u
"IsSplitAllowed"_ustr
) >>= bSplit
;
148 bAllowBreak
= bSplit
;
150 if( bSplit
!= bAllowBreak
)
152 return uno::Any( sal_Int32(word::WdConstants::wdUndefined
) );
155 return uno::Any( bAllowBreak
);
158 void SAL_CALL
SwVbaRows::setAllowBreakAcrossPages( const uno::Any
& _allowbreakacrosspages
)
160 bool bAllowBreak
= false;
161 _allowbreakacrosspages
>>= bAllowBreak
;
162 uno::Reference
< container::XIndexAccess
> xRowsAccess( mxTableRows
, uno::UNO_QUERY_THROW
);
163 for( sal_Int32 index
= mnStartRowIndex
; index
<= mnEndRowIndex
; ++index
)
165 uno::Reference
< beans::XPropertySet
> xRowProps( xRowsAccess
->getByIndex( index
), uno::UNO_QUERY_THROW
);
166 xRowProps
->setPropertyValue(u
"IsSplitAllowed"_ustr
, uno::Any( bAllowBreak
) );
170 float SAL_CALL
SwVbaRows::getSpaceBetweenColumns()
172 // just get the first spacing of the first cell
173 uno::Reference
< table::XCellRange
> xCellRange( mxTextTable
, uno::UNO_QUERY_THROW
);
174 uno::Reference
< beans::XPropertySet
> xCellProps( xCellRange
->getCellByPosition( 0, mnStartRowIndex
), uno::UNO_QUERY_THROW
);
175 sal_Int32 nLeftBorderDistance
= 0;
176 sal_Int32 nRightBorderDistance
= 0;
177 xCellProps
->getPropertyValue(u
"LeftBorderDistance"_ustr
) >>= nLeftBorderDistance
;
178 xCellProps
->getPropertyValue(u
"RightBorderDistance"_ustr
) >>= nRightBorderDistance
;
179 return static_cast< float >( Millimeter::getInPoints( nLeftBorderDistance
+ nRightBorderDistance
) );
182 void SAL_CALL
SwVbaRows::setSpaceBetweenColumns( float _spacebetweencolumns
)
184 sal_Int32 nSpace
= Millimeter::getInHundredthsOfOneMillimeter( _spacebetweencolumns
) / 2;
185 uno::Reference
< container::XIndexAccess
> xColumnAccess( mxTextTable
->getColumns(), uno::UNO_QUERY_THROW
);
186 uno::Reference
< table::XCellRange
> xCellRange( mxTextTable
, uno::UNO_QUERY_THROW
);
187 SwVbaTableHelper
aTableHelper( mxTextTable
);
188 for( sal_Int32 row
= mnStartRowIndex
; row
<= mnEndRowIndex
; ++row
)
190 sal_Int32 nColumns
= aTableHelper
.getTabColumnsCount( row
);
191 for( sal_Int32 column
= 0; column
< nColumns
; ++column
)
193 uno::Reference
< beans::XPropertySet
> xCellProps( xCellRange
->getCellByPosition( column
, row
), uno::UNO_QUERY_THROW
);
194 xCellProps
->setPropertyValue(u
"LeftBorderDistance"_ustr
, uno::Any( nSpace
) );
195 xCellProps
->setPropertyValue(u
"RightBorderDistance"_ustr
, uno::Any( nSpace
) );
200 void SAL_CALL
SwVbaRows::Delete( )
202 mxTableRows
->removeByIndex( mnStartRowIndex
, getCount() );
205 void SAL_CALL
SwVbaRows::SetLeftIndent( float LeftIndent
, ::sal_Int32 RulerStyle
)
207 uno::Reference
< word::XColumns
> xColumns( new SwVbaColumns( getParent(), mxContext
, mxTextTable
, mxTextTable
->getColumns() ) );
208 sal_Int32 nIndent
= static_cast<sal_Int32
>(LeftIndent
);
211 case word::WdRulerStyle::wdAdjustFirstColumn
:
213 setIndentWithAdjustFirstColumn( xColumns
, nIndent
);
216 case word::WdRulerStyle::wdAdjustNone
:
218 setIndentWithAdjustNone( nIndent
);
221 case word::WdRulerStyle::wdAdjustProportional
:
223 setIndentWithAdjustProportional( xColumns
, nIndent
);
226 case word::WdRulerStyle::wdAdjustSameWidth
:
228 setIndentWithAdjustSameWidth( xColumns
, nIndent
);
233 DebugHelper::runtimeexception(ERRCODE_BASIC_BAD_ARGUMENT
);
238 void SwVbaRows::setIndentWithAdjustNone( sal_Int32 indent
)
240 uno::Reference
< beans::XPropertySet
> xTableProps( mxTextTable
, uno::UNO_QUERY_THROW
);
241 sal_Int32 nMargin
= 0;
242 xTableProps
->getPropertyValue(u
"LeftMargin"_ustr
) >>= nMargin
;
244 xTableProps
->setPropertyValue(u
"LeftMargin"_ustr
, uno::Any( nMargin
) );
247 void SwVbaRows::setIndentWithAdjustFirstColumn( const uno::Reference
< word::XColumns
>& xColumns
, sal_Int32 indent
)
249 uno::Reference
< XCollection
> xCol( xColumns
, uno::UNO_QUERY_THROW
);
250 uno::Reference
< word::XColumn
> xColumn( xCol
->Item( uno::Any( sal_Int32(1) ), uno::Any() ), uno::UNO_QUERY_THROW
);
251 sal_Int32 nWidth
= xColumn
->getWidth();
253 xColumn
->setWidth( nWidth
);
254 setIndentWithAdjustNone( indent
);
257 void SwVbaRows::setIndentWithAdjustProportional(
258 const uno::Reference
< word::XColumns
>& xColumns
,
262 // calculate the new width and get the proportion between old and new
263 uno::Reference
< beans::XPropertySet
> xTableProps( mxTextTable
, uno::UNO_QUERY_THROW
);
264 sal_Int32 nWidth
= 0;
265 xTableProps
->getPropertyValue(u
"Width"_ustr
) >>= nWidth
;
266 sal_Int32 nNewWidth
= nWidth
- indent
;
267 if ((nNewWidth
<= 0) || (nWidth
<= 0))
269 throw uno::RuntimeException(
270 u
"Pb with width, in SwVbaRows::setIndentWithAdjustProportional "
271 "(nNewWidth <= 0) || (nWidth <= 0)"_ustr
274 double propFactor
= static_cast<double>(nNewWidth
)/static_cast<double>(nWidth
);
276 // get all columns, calculate and set the new width of the columns
277 uno::Reference
< XCollection
> xCol( xColumns
, uno::UNO_QUERY_THROW
);
278 sal_Int32 nColCount
= xCol
->getCount();
279 for( sal_Int32 i
= 0; i
< nColCount
; i
++ )
281 uno::Reference
< word::XColumn
> xColumn( xCol
->Item( uno::Any( i
), uno::Any() ), uno::UNO_QUERY_THROW
);
282 sal_Int32 nColWidth
= xColumn
->getWidth();
283 sal_Int32 nNewColWidth
= static_cast<sal_Int32
>( propFactor
* nColWidth
);
284 xColumn
->setWidth( nNewColWidth
);
287 // set the width and position of the table
288 setIndentWithAdjustNone( indent
);
289 xTableProps
->setPropertyValue(u
"Width"_ustr
, uno::Any( nNewWidth
) );
292 void SwVbaRows::setIndentWithAdjustSameWidth( const uno::Reference
< word::XColumns
>& xColumns
, sal_Int32 indent
)
294 // calculate the new width and get the width of all columns
295 uno::Reference
< beans::XPropertySet
> xTableProps( mxTextTable
, uno::UNO_QUERY_THROW
);
296 sal_Int32 nWidth
= 0;
297 xTableProps
->getPropertyValue(u
"Width"_ustr
) >>= nWidth
;
298 sal_Int32 nNewWidth
= nWidth
- indent
;
300 // get all columns, calculate and set the new width of the columns
301 uno::Reference
< XCollection
> xCol( xColumns
, uno::UNO_QUERY_THROW
);
302 sal_Int32 nColCount
= xCol
->getCount();
303 sal_Int32 nNewColWidth
= static_cast<sal_Int32
>( double( nNewWidth
)/nColCount
);
304 for( sal_Int32 i
= 0; i
< nColCount
; i
++ )
306 uno::Reference
< word::XColumn
> xColumn( xCol
->Item( uno::Any( i
), uno::Any() ), uno::UNO_QUERY_THROW
);
307 xColumn
->setWidth( nNewColWidth
);
310 // set the width and position of the table
311 setIndentWithAdjustNone( indent
);
312 xTableProps
->setPropertyValue(u
"Width"_ustr
, uno::Any( nNewWidth
) );
315 void SAL_CALL
SwVbaRows::Select( )
317 SwVbaRow::SelectRow( getCurrentWordDoc(mxContext
), mxTextTable
, mnStartRowIndex
, mnEndRowIndex
);
320 ::sal_Int32 SAL_CALL
SwVbaRows::getCount()
322 return ( mnEndRowIndex
- mnStartRowIndex
+ 1 );
325 uno::Any SAL_CALL
SwVbaRows::Item( const uno::Any
& Index1
, const uno::Any
& /*not processed in this base class*/ )
327 sal_Int32 nIndex
= 0;
328 if( Index1
>>= nIndex
)
330 if( nIndex
<= 0 || nIndex
> getCount() )
332 throw lang::IndexOutOfBoundsException(u
"Index out of bounds"_ustr
);
334 return uno::Any( uno::Reference
< word::XRow
>( new SwVbaRow( this, mxContext
, mxTextTable
, nIndex
- 1 ) ) );
336 throw uno::RuntimeException(u
"Index out of bounds"_ustr
);
339 // XEnumerationAccess
341 SwVbaRows::getElementType()
343 return cppu::UnoType
<word::XRow
>::get();
345 uno::Reference
< container::XEnumeration
>
346 SwVbaRows::createEnumeration()
348 return new RowsEnumWrapper( this, mxContext
, mxTextTable
);
352 SwVbaRows::createCollectionObject( const uno::Any
& aSource
)
358 SwVbaRows::getServiceImplName()
360 return u
"SwVbaRows"_ustr
;
363 uno::Sequence
<OUString
>
364 SwVbaRows::getServiceNames()
366 static uno::Sequence
< OUString
> const sNames
368 u
"ooo.vba.word.Rows"_ustr
373 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */